summaryrefslogtreecommitdiffstats
path: root/main.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--main.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/main.c b/main.c
new file mode 100644
index 0000000..d28a337
--- /dev/null
+++ b/main.c
@@ -0,0 +1,114 @@
1/* =============================================================================
2 * main.c — RNG UEFI bootloader (rsbl) — minimal smoke-test version
3 *
4 * Just prints to screen then loads kernel + initrd via LoadImage/StartImage.
5 * ============================================================================= */
6
7#include "uefi.h"
8
9static const char16 kpath[] = u"\\bzImage";
10static const char16 ipath[] = u"\\initramfs.cpio.gz";
11/* same cmdline systemd-boot used */
12static const char16 base_opt[] = u"console=ttyS0,115200 console=tty0 earlyprintk=serial,ttyS0,115200 loglevel=3 rng_tty=ttyS0 initrd=\\initramfs.cpio.gz";
13
14static efi_guid lg = EFI_LOADED_IMAGE_GUID;
15static efi_guid sg = EFI_SIMPLE_FILE_SYSTEM_GUID;
16
17static void pr(efi_simple_text_output *c, const char16 *s) { c->output_string(c, s); }
18static void ph(efi_simple_text_output *c, u64 v) {
19 char16 b[19] = u"0x0000000000000000";
20 for (int i = 17; i >= 2; i--) {
21 u8 n = (u8)(v & 0xF);
22 b[i] = n < 10 ? u'0' + n : u'a' + n - 10;
23 v >>= 4;
24 }
25 c->output_string(c, b);
26}
27
28static u64 allocate_pages(efi_boot_services *b, u64 mt, u64 np, u64 *a) {
29 typedef u64 (*F)(u64, u64, u64, u64 *);
30 return ((F)b->allocate_pages)(0, mt, np, a);
31}
32static u8 *rf(efi_boot_services *b, efi_file_protocol *f, u64 *sz, u64 mx) {
33 u64 np = (mx + 4095) / 4096, a;
34 if (allocate_pages(b, 6, np, &a)) return 0;
35 u8 *d = (u8 *)a;
36 u64 r = mx;
37 if (f->read(f, &r, d) && r != mx) return 0;
38 *sz = r; return d;
39}
40
41u64 __attribute__((aligned(16))) efi_main(handle ih, efi_system_table *st) {
42 efi_simple_text_output *c = st->con_out;
43 efi_boot_services *b = st->boot_services;
44 u64 s;
45
46 pr(c, u"\r\n");
47 pr(c, u"rsbl v0.1 -- RNG UEFI Bootloader\r\n");
48 pr(c, u"\r\n");
49
50 efi_loaded_image *our_li;
51 s = b->handle_protocol(ih, &lg, (void **)&our_li);
52 if (s) { pr(c, u" handle_protocol LI failed\r\n"); goto h; }
53
54 efi_simple_file_system *fs;
55 s = b->handle_protocol(our_li->device_handle, &sg, (void **)&fs);
56 if (s) { pr(c, u" SFSP not on device handle\r\n"); goto h; }
57
58 efi_file_protocol *rt;
59 s = fs->open_volume(fs, (void **)&rt);
60 if (s) { pr(c, u" open_volume failed\r\n"); goto h; }
61
62 pr(c, u" [ loading kernel\r");
63 efi_file_protocol *f;
64 s = rt->open(rt, &f, (char16 *)kpath, 1, 0);
65 if (s) { pr(c, u" [FAIL] loading kernel\r\n"); goto h; }
66 u64 ks; u8 *kd = rf(b, f, &ks, 64*1024*1024);
67 f->close(f);
68 if (!kd) { pr(c, u" [FAIL] loading kernel\r\n"); goto h; }
69 pr(c, u" [ ok] loading kernel "); ph(c, ks); pr(c, u" bytes\r\n");
70
71 pr(c, u" [ loading initrd\r");
72 s = rt->open(rt, &f, (char16 *)ipath, 1, 0);
73 if (s) { pr(c, u" [FAIL] loading initrd\r\n"); goto h; }
74 u64 is; u8 *id = rf(b, f, &is, 32*1024*1024);
75 f->close(f);
76 if (!id) { pr(c, u" [FAIL] loading initrd\r\n"); goto h; }
77 pr(c, u" [ ok] loading initrd "); ph(c, is); pr(c, u" bytes\r\n");
78
79 pr(c, u" [ starting image\r");
80 handle kh = 0;
81 s = b->load_image(0, ih, 0, kd, ks, &kh);
82 if (s) { pr(c, u" [FAIL] LoadImage\r\n"); goto h; }
83
84 efi_loaded_image *kli;
85 s = b->handle_protocol(kh, &lg, (void **)&kli);
86 if (s) { pr(c, u" [FAIL] kernel image info\r\n"); goto h; }
87 kli->device_handle = our_li->device_handle;
88
89 u16 osz = 0;
90 while (base_opt[osz]) osz++;
91 osz = (osz + 1) * 2;
92 u16 *opts;
93 {
94 typedef u64 (*ap_t)(u8, u64, void **);
95 s = ((ap_t)b->allocate_pool)(0, osz, (void **)&opts);
96 }
97 if (s) { pr(c, u" [FAIL] cmdline alloc\r\n"); goto h; }
98 for (u16 i = 0; i < osz / 2; i++) opts[i] = base_opt[i];
99 kli->load_options = opts;
100 kli->load_options_size = osz;
101
102 pr(c, u" [ ok] starting image\r\n");
103 pr(c, u"\r\n");
104 pr(c, u" Launching RNG/Linux ...\r\n");
105 pr(c, u"\r\n");
106
107 s = b->start_image(kh, 0, 0);
108 pr(c, u" kernel returned "); ph(c, s); pr(c, u"\r\n");
109
110h:
111 pr(c, u" Halt\r\n");
112 while (1) asm volatile("hlt");
113 return s;
114}