summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorsalmonik <salmonik@tuta.io>2026-07-31 02:55:10 +0200
committersalmonik <salmonik@tuta.io>2026-07-31 02:55:10 +0200
commit1963a0a6d7398a426d0701f90a5bc796e32899ae (patch)
tree8294a30acd2c8bb0d0ff98ebaee14f9667cbcc6d
downloadrsboot-1963a0a6d7398a426d0701f90a5bc796e32899ae.tar.gz
rsboot-1963a0a6d7398a426d0701f90a5bc796e32899ae.zip
feat(rsboot): initial commit — UEFI bootloader extracted from RNG
-rw-r--r--.gitignore5
-rw-r--r--AGENTS.md82
-rw-r--r--Makefile48
-rw-r--r--fix_pe_simple.py64
-rw-r--r--main.c114
-rw-r--r--pad_for_optiplex.py69
-rw-r--r--uefi.h230
7 files changed, 612 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..e828353
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,5 @@
1*.o
2*.elf
3/build/
4build/
5.pi/
diff --git a/AGENTS.md b/AGENTS.md
new file mode 100644
index 0000000..a39c192
--- /dev/null
+++ b/AGENTS.md
@@ -0,0 +1,82 @@
1# AGENTS.md — rsboot (RaiserSoft Bootloader)
2
3## Identity
4
5rsboot is a custom **UEFI** bootloader (PE32+, x64) that loads a Linux kernel +
6initramfs from an ext2 partition using UEFI file system protocols, then
7launches the kernel via `LoadImage`/`StartImage`. Single-stage design —
8no MBR, no real mode, no stage1/stage2 split.
9
10This is a standalone submodule of the [RNG](https://git.2137697.xyz/RaiserSoft/rng) project.
11
12## Code
13
14- **Language:** C (freestanding, `-m64`, `-ffreestanding`, `-fPIE`, `-mabi=ms`).
15- **Assembler:** none currently (no `.asm` files needed).
16- **Linker:** `ld` with `-Ttext=0x1000 -e efi_main`, producing an ELF64
17 intermediate (`main.elf`).
18- **PE conversion:** `objcopy -O pei-x86-64 --subsystem=10` converts the ELF
19 to a PE32+ image, then Python scripts fix up headers and pad for
20 firmware compatibility.
21- **Dependencies:** none. No libc, no CRT — just raw UEFI protocol calls.
22- **Debug:** UEFI console output (`con_out->OutputString()` via serial +
23 framebuffer as configured by the firmware).
24- **UEFI types:** `uefi.h` provides minimal stand-alone type definitions,
25 GUIDs, and protocol structs (system table, boot services, file system
26 protocol, loaded image protocol, etc.).
27
28## Source Layout
29
30```
31main.c — EFI entry point, loads kernel + initrd, starts image
32uefi.h — UEFI types, GUIDs, protocol structs
33Makefile — builds BOOTX64.EFI
34fix_pe_simple.py — PE header fixup (ImageBase, DllChar, strip relocs)
35pad_for_optiplex.py — PE padding for Optiplex 7010 firmware
36```
37
38## Build
39
40```sh
41make # produces ../build/bootloader/BOOTX64.EFI
42```
43
44The build pipeline:
45
461. **main.o** — compiled with `-fPIE -fshort-wchar -mno-red-zone -mabi=ms`
472. **main.elf** — linked as position-independent ELF64 starting at text 0x1000
483. **BOOTX64.EFI** — objcopy to `pei-x86-64`, subsystem=10 (EFI application)
494. **fix_pe_simple.py** — sets ImageBase, marks RELOCS_STRIPPED (PIE code
50 uses only PC-relative addressing, so no fixups needed), sets NX |
51 DYNAMIC_BASE | HIGH_ENTROPY_VA, clears .reloc data directory and
52 checksum
535. **pad_for_optiplex.py** — if the PE is smaller than ~160KB, pad to match
54 the size systemd-boot uses (some AMI Aptio firmware versions on
55 Optiplex 7010 reject smaller PE files)
56
57## Kernel Loading Flow
58
591. Get our own `LoadedImage` protocol via `handle_protocol`
602. Get `SimpleFileSystem` from the device handle
613. `OpenVolume` → root directory
624. Open `\bzImage`, read into allocated pages
635. Open `\initramfs.cpio.gz`, read into allocated pages
646. `LoadImage` (from memory, not device path) → kernel handle
657. Set kernel's `load_options` (command line) on its `LoadedImage` protocol
668. `StartImage` → kernel takes over
67
68## Key Conventions
69
70- **GUIDs:** EFI_LOADED_IMAGE_GUID, EFI_SIMPLE_FILE_SYSTEM_GUID (defined
71 in `uefi.h` matching the UEFI 2.10 spec).
72- **Boot device:** The device we were loaded from (our `LoadedImage.device_handle`).
73- **File paths:** `\bzImage`, `\initramfs.cpio.gz` (backslash prefix for
74 UEFI device paths).
75- **Cmdline:** `console=ttyS0,115200 console=tty0 earlyprintk=serial,ttyS0,115200 loglevel=3 rng_tty=ttyS0 initrd=\initramfs.cpio.gz`
76- **Memory allocation:** UEFI boot services `AllocatePages` (type 6 =
77 EfiLoaderData) for kernel/initrd buffers; `AllocatePool` for cmdline copy.
78- **Compilation quirks:** `-mabi=ms` is required so UEFI calling convention
79 (Microsoft x64 ABI) is used; `-fshort-wchar` makes `wchar_t` 16-bit to
80 match UEFI's CHAR16; `-mno-red-zone` because the red-zone can be clobbered
81 by UEFI firmware handlers.
82- **Commits:** `feat(rsboot):` prefix.
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..bd21c45
--- /dev/null
+++ b/Makefile
@@ -0,0 +1,48 @@
1# =============================================================================
2# Makefile — rsbl (UEFI bootloader for RNG)
3#
4# Produces build/bootloader/BOOTX64.EFI (PE32+ for UEFI)
5#
6# Uses -fPIE for position-independent code so the image works at any
7# load address. The Optiplex 7010 firmware ignores ImageBase + relocs,
8# so RELOCS_STRIPPED + padding to ~160KB is required.
9# =============================================================================
10
11BUILD_DIR = ../build/bootloader
12CC = gcc
13LD = ld
14OBJCOPY = objcopy
15
16CFLAGS = -m64 -ffreestanding -nostdinc -nostartfiles -nodefaultlibs \
17 -fno-builtin -fno-stack-protector -fPIE -fPIC \
18 -fshort-wchar -mno-red-zone -mabi=ms -Qn \
19 -fno-asynchronous-unwind-tables -fno-unwind-tables \
20 -fno-exceptions \
21 -I. -Wall -Wextra -Werror
22
23LDFLAGS = -m elf_x86_64 -nostdlib -z norelro --no-dynamic-linker \
24 -Ttext=0x1000 -e efi_main
25
26.PHONY: all clean
27
28all: $(BUILD_DIR)/BOOTX64.EFI
29
30$(BUILD_DIR)/BOOTX64.EFI: main.elf
31 @mkdir -p $(BUILD_DIR)
32 $(OBJCOPY) -O pei-x86-64 --subsystem=10:1.1 \
33 --heap 0x100000,0x1000 \
34 --stack 0x100000,0x1000 \
35 $< $@
36 python3 fix_pe_simple.py $@
37 python3 pad_for_optiplex.py $@
38 @echo " -> $@"
39 @ls -lh $@
40
41main.elf: main.o
42 $(LD) $(LDFLAGS) -o "$@" "$^"
43
44main.o: main.c uefi.h
45 $(CC) $(CFLAGS) -c -o "$@" "$<"
46
47clean:
48 rm -f *.o *.elf $(BUILD_DIR)/BOOTX64.EFI
diff --git a/fix_pe_simple.py b/fix_pe_simple.py
new file mode 100644
index 0000000..77b1366
--- /dev/null
+++ b/fix_pe_simple.py
@@ -0,0 +1,64 @@
1#!/usr/bin/env python3
2"""fix_pe_simple.py — PE header fixup for PIE-built UEFI bootloader
3
4The -fPIE-built bootloader uses only PC-relative addressing, so it needs
5zero absolute fixups. This script just sets proper PE flags:
6
7 - ImageBase (env IMAGE_BASE, default 0x10000000)
8 - Characteristics = 0x022e (RELOCS_STRIPPED)
9 - DllChar = 0x0160 (NX | DYNAMIC_BASE | HIGH_ENTROPY_VA)
10 - Clears .reloc DD (no relocations needed)
11 - Clears checksum (not signed)
12"""
13
14import struct, os, sys
15
16def fix_pe(path):
17 try:
18 with open(path, 'rb') as f:
19 d = bytearray(f.read())
20 except IOError as e:
21 print(f" ERROR: cannot read {path}: {e}")
22 return False
23
24 po = struct.unpack('<I', d[0x3C:0x40])[0]
25 if d[po:po+4] != b'PE\x00\x00':
26 print(f" Not a PE file")
27 return False
28
29 coff = po + 4
30 opt = po + 24
31
32 magic = struct.unpack('<H', d[opt:opt+2])[0]
33 if magic != 0x20b:
34 print(f" Not PE32+")
35 return False
36
37 ib_env = os.environ.get('IMAGE_BASE', '0x10000000')
38 img_base = int(ib_env, 16) if ib_env.startswith('0x') else 0x10000000
39 struct.pack_into('<Q', d, opt+24, img_base)
40 struct.pack_into('<H', d, coff+18, 0x022e)
41 struct.pack_into('<H', d, opt+70, 0x0160)
42 struct.pack_into('<I', d, coff+8, 0)
43 struct.pack_into('<I', d, coff+12, 0)
44 struct.pack_into('<I', d, opt+64, 0)
45
46 dd = opt + 112
47 struct.pack_into('<II', d, dd + 5*8, 0, 0)
48
49 try:
50 with open(path, 'wb') as f:
51 f.write(d)
52 except IOError as e:
53 print(f" ERROR: cannot write {path}: {e}")
54 return False
55
56 print(f" Fixed: ImageBase={img_base:#010x} char=0x022e dll=0x0160 reloc=cleared")
57 return True
58
59if __name__ == '__main__':
60 if len(sys.argv) < 2:
61 print(f"Usage: IMAGE_BASE=0x... {sys.argv[0]} <pe-path>")
62 sys.exit(1)
63 if not fix_pe(sys.argv[1]):
64 sys.exit(1)
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}
diff --git a/pad_for_optiplex.py b/pad_for_optiplex.py
new file mode 100644
index 0000000..2d48552
--- /dev/null
+++ b/pad_for_optiplex.py
@@ -0,0 +1,69 @@
1#!/usr/bin/env python3
2"""pad_for_optiplex.py — pad a UEFI bootloader PE for Optiplex 7010
3
4The Optiplex 7010 AMI Aptio firmware rejects PEs smaller than ~160KB
5("no bootable devices"). This pads the PE to match systemd-boot's size
6and sets SizeOfImage accordingly.
7"""
8
9import struct, sys, os
10
11def pad(path):
12 try:
13 with open(path, 'rb') as f:
14 d = bytearray(f.read())
15 except IOError as e:
16 print(f" ERROR: cannot read {path}: {e}")
17 return False
18
19 po = struct.unpack('<I', d[0x3C:0x40])[0]
20 if d[po:po+4] != b'PE\x00\x00':
21 print(f" Not a PE file")
22 return False
23
24 opt = po + 24
25
26 # Target size: 160256 bytes (matching systemd-boot)
27 target = 160256
28 if len(d) >= target:
29 print(f" Already >= {target} bytes ({len(d)}), nothing to do")
30 return True
31
32 # Compute SizeOfImage: round current SizeOfImage to match file growth
33 cur_si = struct.unpack('<I', d[opt+56:opt+60])[0]
34 cur_file_size = len(d)
35
36 # The file is padded after all sections. SizeOfImage is the highest
37 # RVA + virtual size, rounded up to SectionAlignment. After padding
38 # the file, we need to increase SizeOfImage so the firmware sees a
39 # consistent image.
40 #
41 # Simple approach: set SizeOfImage = target - file_delta + old_si
42 # Actually: SizeOfImage already covers our sections at up to ~0x4000.
43 # We just need to make it large enough for the padded region.
44 # Use systemd-boot's SizeOfImage = 0x2d000 as reference.
45 file_growth = target - len(d)
46 new_si = ((cur_si + file_growth + 0xfff) // 0x1000) * 0x1000
47
48 # Pad the file
49 d += b'\x00' * file_growth
50
51 # Update SizeOfImage in optional header
52 struct.pack_into('<I', d, opt+56, new_si)
53
54 try:
55 with open(path, 'wb') as f:
56 f.write(d)
57 except IOError as e:
58 print(f" ERROR: cannot write {path}: {e}")
59 return False
60
61 print(f" Padded: {len(d)} bytes (was {cur_file_size}), SizeOfImage = {new_si:#x}")
62 return True
63
64if __name__ == '__main__':
65 if len(sys.argv) < 2:
66 print(f"Usage: {sys.argv[0]} <pe-path>")
67 sys.exit(1)
68 if not pad(sys.argv[1]):
69 sys.exit(1)
diff --git a/uefi.h b/uefi.h
new file mode 100644
index 0000000..6d46f16
--- /dev/null
+++ b/uefi.h
@@ -0,0 +1,230 @@
1/* =============================================================================
2 * uefi.h — minimal UEFI types and protocols for the RNG bootloader
3 *
4 * Standalone, freestanding, no external headers.
5 * ============================================================================= */
6
7#ifndef UEFI_H
8#define UEFI_H
9
10/* ---- basic types ---- */
11typedef unsigned char u8;
12typedef unsigned short u16;
13typedef unsigned int u32;
14typedef unsigned long long u64;
15/* UEFI CHAR16 — wchar_t must be 16-bit (use -fshort-wchar).
16 * GCC by default makes wchar_t = int (32-bit). -fshort-wchar makes
17 * it unsigned short (16-bit) to match UEFI's CHAR16.
18 * We don't include <stddef.h> (freestanding), so define our own. */
19typedef __CHAR16_TYPE__ char16;
20typedef signed short int16;
21typedef long long int64;
22typedef void *handle;
23
24/* ---- EFI status codes ---- */
25#define EFI_SUCCESS 0
26#define EFI_LOAD_ERROR ((u64)1)
27#define EFI_INVALID_PARAMETER ((u64)2)
28#define EFI_UNSUPPORTED ((u64)3)
29#define EFI_NOT_FOUND ((u64)14)
30#define EFI_ALREADY_STARTED ((u64)25)
31#define EFI_OUT_OF_RESOURCES ((u64)9)
32
33/* ---- GUIDs (128-bit) ---- */
34typedef struct { u32 a; u16 b; u16 c; u8 d[8]; } efi_guid;
35
36/* ---- EFI time (unused, part of file info struct) ---- */
37typedef struct {
38 u16 year; u8 month; u8 day;
39 u8 hour; u8 minute; u8 second; u8 pad1;
40 u32 ns; int16 tz; u8 daylight;
41} efi_time;
42
43/* ---- table headers ---- */
44typedef struct {
45 u64 signature;
46 u32 revision;
47 u32 header_size;
48 u32 crc32;
49 u32 reserved;
50} efi_table_header;
51
52/* ---- system table ---- */
53typedef struct efi_config_table efi_config_table;
54typedef struct efi_simple_text_output efi_simple_text_output;
55typedef struct efi_simple_text_input efi_simple_text_input;
56typedef struct efi_boot_services efi_boot_services;
57typedef struct efi_runtime_services efi_runtime_services;
58
59typedef struct {
60 efi_table_header hdr;
61 char16 *firmware_vendor;
62 u32 firmware_revision;
63 handle console_in_handle;
64 efi_simple_text_input *con_in;
65 handle console_out_handle;
66 efi_simple_text_output *con_out;
67 handle stderr_handle;
68 efi_simple_text_output *std_err;
69 efi_runtime_services *runtime_services;
70 efi_boot_services *boot_services;
71 u64 number_of_table_entries;
72 efi_config_table *configuration_table;
73} efi_system_table;
74
75/* ---- EFI input key ---- */
76typedef struct {
77 u16 scan_code;
78 char16 unicode_char;
79} efi_input_key;
80
81/* ---- simple text output (console) ---- */
82typedef u64 (*efi_text_reset)(efi_simple_text_output *, u8);
83typedef u64 (*efi_text_output)(efi_simple_text_output *, const char16 *);
84
85struct efi_simple_text_output {
86 void *unused; // Index 0: Reset
87 efi_text_output output_string; // Index 1: OutputString
88 void *unused2[8]; // Index 2-9: TestString..Mode
89};
90
91/* ---- simple text input (keyboard) ---- */
92typedef u64 (*efi_input_reset)(efi_simple_text_input *, u8);
93typedef u64 (*efi_input_read_key)(efi_simple_text_input *, efi_input_key *);
94
95struct efi_simple_text_input {
96 efi_input_reset reset; /* Index 0: Reset */
97 efi_input_read_key read_key_stroke; /* Index 1: ReadKeyStroke */
98 handle wait_for_key; /* Index 2: WaitForKey event */
99};
100
101/* ---- boot services ---- */
102typedef u64 (*efi_exit_boot_services)(handle, u64);
103typedef u64 (*efi_get_memory_map)(void*, void*, void*, void*, void*);
104typedef u64 (*efi_locate_protocol)(const efi_guid *, void *, void **);
105typedef u64 (*efi_load_image)(u8, handle, void *, void *, u64, handle *);
106typedef u64 (*efi_start_image)(handle, void *, u64 *);
107typedef u64 (*efi_handle_protocol)(handle, const efi_guid *, void **);
108typedef u64 (*efi_open_volume)(void *, void **);
109typedef u64 (*efi_open_file)(void *, void **, char16 *, u64, u64);
110typedef u64 (*efi_read_file)(void *, u64 *, void *);
111typedef u64 (*efi_allocate_pool)(u8, u64, void **);
112
113/* Boot Services table matching UEFI spec v2.10 function order.
114 Each entry is one function pointer (8 bytes on x64). */
115struct efi_boot_services {
116 efi_table_header hdr; /* 0 */
117 void *raise_tpl; /* 24 index 0 */
118 void *restore_tpl; /* 32 index 1 */
119 void *allocate_pages; /* 40 index 2 */
120 void *free_pages; /* 48 index 3 */
121 efi_get_memory_map get_memory_map; /* 56 index 4 */
122 efi_allocate_pool allocate_pool; /* 64 index 5 */
123 void *free_pool; /* 72 index 6 */
124 void *create_event; /* 80 index 7 */
125 void *set_timer; /* 88 index 8 */
126 void *wait_for_event; /* 96 index 9 */
127 void *signal_event; /*104 index 10 */
128 void *close_event; /*112 index 11 */
129 void *check_event; /*120 index 12 */
130 void *install_protocol_interface; /*128 index 13 */
131 void *reinstall_protocol_interface;/*136 index 14 */
132 void *uninstall_protocol_interface;/*144 index 15 */
133 efi_handle_protocol handle_protocol; /*152 index 16 */
134 void *reserved; /*160 index 17 */
135 void *register_protocol_notify; /*168 index 18 */
136 void *locate_handle; /*176 index 19 */
137 void *locate_device_path; /*184 index 20 */
138 void *install_config_table; /*192 index 21 */
139 efi_load_image load_image; /*200 index 22 */
140 efi_start_image start_image; /*208 index 23 */
141 void *exit; /*216 index 24 */
142 void *unload_image; /*224 index 25 */
143 efi_exit_boot_services exit_boot_services; /*232 index 26 */
144 void *get_next_monotonic_count; /*240 index 27 */
145 void *stall; /*248 index 28 */
146 void *set_watchdog_timer; /*256 index 29 */
147 void *connect_controller; /*264 index 30 */
148 void *disconnect_controller; /*272 index 31 */
149 void *open_protocol; /*280 index 32 */
150 void *close_protocol; /*288 index 33 */
151 void *open_protocol_information; /*296 index 34 */
152 void *protocols_per_handle; /*304 index 35 */
153 void *locate_handle_buffer; /*312 index 36 */
154 efi_locate_protocol locate_protocol; /*320 index 37 */
155 void *install_multiple_protocols; /*328 index 38 */
156 void *uninstall_multiple_protocols;/*336 index 39 */
157 void *calculate_crc32; /*344 index 40 */
158 void *copy_mem; /*352 index 41 */
159 void *set_mem; /*360 index 42 */
160 void *create_event_ex; /*368 index 43 */
161};
162
163/* ---- GUID for Simple File System Protocol ---- */
164#define EFI_SIMPLE_FILE_SYSTEM_GUID \
165 {0x0964e5b22, 0x6459, 0x11d2, {0x8e,0x39,0x00,0xa0,0xc9,0x69,0x72,0x3b}}
166
167/* ---- file protocol ---- */
168typedef struct {
169 u64 revision;
170 efi_open_volume open_volume;
171} efi_simple_file_system;
172
173typedef struct efi_file_protocol efi_file_protocol;
174
175typedef u64 (*efi_file_open)(efi_file_protocol *, efi_file_protocol **, char16 *, u64, u64);
176typedef u64 (*efi_file_read)(efi_file_protocol *, u64 *, void *);
177typedef u64 (*efi_file_close)(efi_file_protocol *);
178
179#define EFI_FILE_MODE_READ 1
180
181struct efi_file_protocol {
182 u64 revision;
183 efi_file_open open;
184 efi_file_close close;
185 void *unused;
186 efi_file_read read;
187 void *unused2[5];
188};
189
190/* ---- file info (for getting file size) ---- */
191typedef struct {
192 u64 size;
193 u64 file_size;
194 u64 physical_size;
195 efi_time create_time;
196 efi_time last_access;
197 efi_time modification_time;
198 u64 attribute;
199 char16 file_name[1];
200} efi_file_info;
201
202/* ---- loaded image protocol ---- */
203typedef struct {
204 u32 revision;
205 handle parent_handle;
206 handle system_table;
207 handle device_handle;
208 void *file_path;
209 void *reserved;
210 u32 load_options_size;
211 void *load_options;
212 void *image_base;
213 u64 image_size;
214 u64 image_code_type;
215 u64 image_data_type;
216 void *unused;
217} efi_loaded_image;
218
219/* ---- loaded image protocol GUID ---- */
220#define EFI_LOADED_IMAGE_GUID \
221 {0x5b1b31a1, 0x9562, 0x11d2, {0x8e,0x3f,0x00,0xa0,0xc9,0x69,0x72,0x3b}}
222
223/* ---- device path protocol ---- */
224typedef struct {
225 u8 type;
226 u8 sub_type;
227 u16 length;
228} efi_device_path;
229
230#endif /* UEFI_H */