Skip to main content

linux_loader/loader_gen/x86_64/
bootparam.rs

1// Rust translation of arch/x86/include/uapi/asm/bootparam.h and its dependencies.
2// All structs use #[repr(C, packed)] to match the kernel's binary layout exactly.
3
4#![allow(non_camel_case_types, non_snake_case)]
5
6// --- setup_data.h constants ---
7
8pub const SETUP_NONE: u32 = 0;
9pub const SETUP_E820_EXT: u32 = 1;
10pub const SETUP_DTB: u32 = 2;
11pub const SETUP_PCI: u32 = 3;
12pub const SETUP_EFI: u32 = 4;
13pub const SETUP_APPLE_PROPERTIES: u32 = 5;
14pub const SETUP_JAILHOUSE: u32 = 6;
15pub const SETUP_CC_BLOB: u32 = 7;
16pub const SETUP_IMA: u32 = 8;
17pub const SETUP_RNG_SEED: u32 = 9;
18pub const SETUP_KEXEC_KHO: u32 = 10;
19pub const SETUP_ENUM_MAX: u32 = SETUP_KEXEC_KHO;
20pub const SETUP_INDIRECT: u32 = 1 << 31;
21pub const SETUP_TYPE_MAX: u32 = SETUP_ENUM_MAX | SETUP_INDIRECT;
22
23// --- bootparam.h constants ---
24
25pub const RAMDISK_IMAGE_START_MASK: u16 = 0x07FF;
26pub const RAMDISK_PROMPT_FLAG: u16 = 0x8000;
27pub const RAMDISK_LOAD_FLAG: u16 = 0x4000;
28
29pub const LOADED_HIGH: u8 = 1 << 0;
30pub const KASLR_FLAG: u8 = 1 << 1;
31pub const QUIET_FLAG: u8 = 1 << 5;
32pub const KEEP_SEGMENTS: u8 = 1 << 6;
33pub const CAN_USE_HEAP: u8 = 1 << 7;
34
35pub const XLF_KERNEL_64: u16 = 1 << 0;
36pub const XLF_CAN_BE_LOADED_ABOVE_4G: u16 = 1 << 1;
37pub const XLF_EFI_HANDOVER_32: u16 = 1 << 2;
38pub const XLF_EFI_HANDOVER_64: u16 = 1 << 3;
39pub const XLF_EFI_KEXEC: u16 = 1 << 4;
40pub const XLF_5LEVEL: u16 = 1 << 5;
41pub const XLF_5LEVEL_ENABLED: u16 = 1 << 6;
42pub const XLF_MEM_ENCRYPTION: u16 = 1 << 7;
43
44pub const E820_MAX_ENTRIES_ZEROPAGE: usize = 128;
45pub const JAILHOUSE_SETUP_REQUIRED_VERSION: u32 = 1;
46
47// --- edd.h constants ---
48
49pub const EDDNR: u16 = 0x1e9;
50pub const EDDBUF: u16 = 0xd00;
51pub const EDDMAXNR: usize = 6;
52pub const EDDEXTSIZE: usize = 8;
53pub const EDDPARMSIZE: usize = 74;
54pub const CHECKEXTENSIONSPRESENT: u8 = 0x41;
55pub const GETDEVICEPARAMETERS: u8 = 0x48;
56pub const LEGACYGETDEVICEPARAMETERS: u8 = 0x08;
57pub const EDDMAGIC1: u16 = 0x55AA;
58pub const EDDMAGIC2: u16 = 0xAA55;
59
60pub const READ_SECTORS: u8 = 0x02;
61pub const EDD_MBR_SIG_OFFSET: u16 = 0x1B8;
62pub const EDD_MBR_SIG_BUF: u16 = 0x290;
63pub const EDD_MBR_SIG_MAX: usize = 16;
64pub const EDD_MBR_SIG_NR_BUF: u16 = 0x1ea;
65
66pub const EDD_EXT_FIXED_DISK_ACCESS: u16 = 1 << 0;
67pub const EDD_EXT_DEVICE_LOCKING_AND_EJECTING: u16 = 1 << 1;
68pub const EDD_EXT_ENHANCED_DISK_DRIVE_SUPPORT: u16 = 1 << 2;
69pub const EDD_EXT_64BIT_EXTENSIONS: u16 = 1 << 3;
70
71pub const EDD_INFO_DMA_BOUNDARY_ERROR_TRANSPARENT: u16 = 1 << 0;
72pub const EDD_INFO_GEOMETRY_VALID: u16 = 1 << 1;
73pub const EDD_INFO_REMOVABLE: u16 = 1 << 2;
74pub const EDD_INFO_WRITE_VERIFY: u16 = 1 << 3;
75pub const EDD_INFO_MEDIA_CHANGE_NOTIFICATION: u16 = 1 << 4;
76pub const EDD_INFO_LOCKABLE: u16 = 1 << 5;
77pub const EDD_INFO_NO_MEDIA_PRESENT: u16 = 1 << 6;
78pub const EDD_INFO_USE_INT13_FN50: u16 = 1 << 7;
79
80// --- screen_info.h constants ---
81
82pub const VIDEO_TYPE_MDA: u8 = 0x10;
83pub const VIDEO_TYPE_CGA: u8 = 0x11;
84pub const VIDEO_TYPE_EGAM: u8 = 0x20;
85pub const VIDEO_TYPE_EGAC: u8 = 0x21;
86pub const VIDEO_TYPE_VGAC: u8 = 0x22;
87pub const VIDEO_TYPE_VLFB: u8 = 0x23;
88pub const VIDEO_TYPE_PICA_S3: u8 = 0x30;
89pub const VIDEO_TYPE_MIPS_G364: u8 = 0x31;
90pub const VIDEO_TYPE_SGI: u8 = 0x33;
91pub const VIDEO_TYPE_TGAC: u8 = 0x40;
92pub const VIDEO_TYPE_SUN: u8 = 0x50;
93pub const VIDEO_TYPE_SUNPCI: u8 = 0x51;
94pub const VIDEO_TYPE_PMAC: u8 = 0x60;
95pub const VIDEO_TYPE_EFI: u8 = 0x70;
96
97pub const VIDEO_FLAGS_NOCURSOR: u8 = 1 << 0;
98pub const VIDEO_CAPABILITY_SKIP_QUIRKS: u32 = 1 << 0;
99pub const VIDEO_CAPABILITY_64BIT_BASE: u32 = 1 << 1;
100
101// ============================================================================
102// Struct definitions
103// ============================================================================
104
105/// From include/uapi/linux/screen_info.h
106#[repr(C, packed)]
107#[derive(Debug, Default, Copy, Clone, PartialEq)]
108pub struct screen_info {
109    pub orig_x: u8,
110    pub orig_y: u8,
111    pub ext_mem_k: u16,
112    pub orig_video_page: u16,
113    pub orig_video_mode: u8,
114    pub orig_video_cols: u8,
115    pub flags: u8,
116    pub unused2: u8,
117    pub orig_video_ega_bx: u16,
118    pub unused3: u16,
119    pub orig_video_lines: u8,
120    pub orig_video_isVGA: u8,
121    pub orig_video_points: u16,
122    pub lfb_width: u16,
123    pub lfb_height: u16,
124    pub lfb_depth: u16,
125    pub lfb_base: u32,
126    pub lfb_size: u32,
127    pub cl_magic: u16,
128    pub cl_offset: u16,
129    pub lfb_linelength: u16,
130    pub red_size: u8,
131    pub red_pos: u8,
132    pub green_size: u8,
133    pub green_pos: u8,
134    pub blue_size: u8,
135    pub blue_pos: u8,
136    pub rsvd_size: u8,
137    pub rsvd_pos: u8,
138    pub vesapm_seg: u16,
139    pub vesapm_off: u16,
140    pub pages: u16,
141    pub vesa_attributes: u16,
142    pub capabilities: u32,
143    pub ext_lfb_base: u32,
144    pub _reserved: [u8; 2],
145}
146
147/// From include/uapi/linux/apm_bios.h
148#[repr(C, packed)]
149#[derive(Debug, Default, Copy, Clone, PartialEq)]
150pub struct apm_bios_info {
151    pub version: u16,
152    pub cseg: u16,
153    pub offset: u32,
154    pub cseg_16: u16,
155    pub dseg: u16,
156    pub flags: u16,
157    pub cseg_len: u16,
158    pub cseg_16_len: u16,
159    pub dseg_len: u16,
160}
161
162/// From arch/x86/include/uapi/asm/ist.h
163#[repr(C, packed)]
164#[derive(Debug, Default, Copy, Clone, PartialEq)]
165pub struct ist_info {
166    pub signature: u32,
167    pub command: u32,
168    pub event: u32,
169    pub perf_level: u32,
170}
171
172/// From include/uapi/video/edid.h
173#[repr(C, packed)]
174#[derive(Debug, Copy, Clone, PartialEq)]
175pub struct edid_info {
176    pub dummy: [u8; 128],
177}
178
179impl Default for edid_info {
180    fn default() -> Self {
181        unsafe { core::mem::zeroed() }
182    }
183}
184
185/// From arch/x86/include/uapi/asm/setup_data.h
186#[repr(C, packed)]
187#[derive(Debug, Default, Copy, Clone, PartialEq)]
188pub struct boot_e820_entry {
189    pub addr: u64,
190    pub size: u64,
191    pub r#type: u32,
192}
193
194/// From include/uapi/linux/edd.h
195///
196/// The `interface_path` and `device_path` fields are unions in C. They are
197/// represented here as fixed-size byte arrays (8 and 16 bytes respectively)
198/// for simplicity. Transmute or use `ptr::read_unaligned` to access a
199/// specific variant.
200#[repr(C, packed)]
201#[derive(Debug, Default, Copy, Clone, PartialEq)]
202pub struct edd_device_params {
203    pub length: u16,
204    pub info_flags: u16,
205    pub num_default_cylinders: u32,
206    pub num_default_heads: u32,
207    pub sectors_per_track: u32,
208    pub number_of_sectors: u64,
209    pub bytes_per_sector: u16,
210    pub dpte_ptr: u32,
211    pub key: u16,
212    pub device_path_info_length: u8,
213    pub reserved2: u8,
214    pub reserved3: u16,
215    pub host_bus_type: [u8; 4],
216    pub interface_type: [u8; 8],
217    pub interface_path: [u8; 8],
218    pub device_path: [u8; 16],
219    pub reserved4: u8,
220    pub checksum: u8,
221}
222
223/// From include/uapi/linux/edd.h
224#[repr(C, packed)]
225#[derive(Debug, Default, Copy, Clone, PartialEq)]
226pub struct edd_info {
227    pub device: u8,
228    pub version: u8,
229    pub interface_support: u16,
230    pub legacy_max_cylinder: u16,
231    pub legacy_max_head: u8,
232    pub legacy_sectors_per_track: u8,
233    pub params: edd_device_params,
234}
235
236/// From arch/x86/include/uapi/asm/bootparam.h
237#[repr(C, packed)]
238#[derive(Debug, Default, Copy, Clone, PartialEq)]
239pub struct setup_header {
240    pub setup_sects: u8,
241    pub root_flags: u16,
242    pub syssize: u32,
243    pub ram_size: u16,
244    pub vid_mode: u16,
245    pub root_dev: u16,
246    pub boot_flag: u16,
247    pub jump: u16,
248    pub header: u32,
249    pub version: u16,
250    pub realmode_swtch: u32,
251    pub start_sys_seg: u16,
252    pub kernel_version: u16,
253    pub type_of_loader: u8,
254    pub loadflags: u8,
255    pub setup_move_size: u16,
256    pub code32_start: u32,
257    pub ramdisk_image: u32,
258    pub ramdisk_size: u32,
259    pub bootsect_kludge: u32,
260    pub heap_end_ptr: u16,
261    pub ext_loader_ver: u8,
262    pub ext_loader_type: u8,
263    pub cmd_line_ptr: u32,
264    pub initrd_addr_max: u32,
265    pub kernel_alignment: u32,
266    pub relocatable_kernel: u8,
267    pub min_alignment: u8,
268    pub xloadflags: u16,
269    pub cmdline_size: u32,
270    pub hardware_subarch: u32,
271    pub hardware_subarch_data: u64,
272    pub payload_offset: u32,
273    pub payload_length: u32,
274    pub setup_data: u64,
275    pub pref_address: u64,
276    pub init_size: u32,
277    pub handover_offset: u32,
278    pub kernel_info_offset: u32,
279}
280
281#[repr(C, packed)]
282#[derive(Debug, Default, Copy, Clone, PartialEq)]
283pub struct sys_desc_table {
284    pub length: u16,
285    pub table: [u8; 14],
286}
287
288#[repr(C, packed)]
289#[derive(Debug, Default, Copy, Clone, PartialEq)]
290pub struct olpc_ofw_header {
291    pub ofw_magic: u32,
292    pub ofw_version: u32,
293    pub cif_handler: u32,
294    pub irq_desc_table: u32,
295}
296
297#[repr(C, packed)]
298#[derive(Debug, Default, Copy, Clone, PartialEq)]
299pub struct efi_info {
300    pub efi_loader_signature: u32,
301    pub efi_systab: u32,
302    pub efi_memdesc_size: u32,
303    pub efi_memdesc_version: u32,
304    pub efi_memmap: u32,
305    pub efi_memmap_size: u32,
306    pub efi_systab_hi: u32,
307    pub efi_memmap_hi: u32,
308}
309
310/// The x86 "zeropage" — exactly 4096 bytes.
311///
312/// `_pad7` size is `0x290 - 0x1f1 - sizeof(setup_header)` = 36 bytes.
313#[repr(C, packed)]
314#[derive(Debug, Copy, Clone, PartialEq)]
315pub struct boot_params {
316    pub screen_info: screen_info,                                 // 0x000
317    pub apm_bios_info: apm_bios_info,                             // 0x040
318    pub _pad2: [u8; 4],                                           // 0x054
319    pub tboot_addr: u64,                                          // 0x058
320    pub ist_info: ist_info,                                       // 0x060
321    pub acpi_rsdp_addr: u64,                                      // 0x070
322    pub _pad3: [u8; 8],                                           // 0x078
323    pub hd0_info: [u8; 16],                                       // 0x080
324    pub hd1_info: [u8; 16],                                       // 0x090
325    pub sys_desc_table: sys_desc_table,                           // 0x0a0
326    pub olpc_ofw_header: olpc_ofw_header,                         // 0x0b0
327    pub ext_ramdisk_image: u32,                                   // 0x0c0
328    pub ext_ramdisk_size: u32,                                    // 0x0c4
329    pub ext_cmd_line_ptr: u32,                                    // 0x0c8
330    pub _pad4: [u8; 112],                                         // 0x0cc
331    pub cc_blob_address: u32,                                     // 0x13c
332    pub edid_info: edid_info,                                     // 0x140
333    pub efi_info: efi_info,                                       // 0x1c0
334    pub alt_mem_k: u32,                                           // 0x1e0
335    pub scratch: u32,                                             // 0x1e4
336    pub e820_entries: u8,                                         // 0x1e8
337    pub eddbuf_entries: u8,                                       // 0x1e9
338    pub edd_mbr_sig_buf_entries: u8,                              // 0x1ea
339    pub kbd_status: u8,                                           // 0x1eb
340    pub secure_boot: u8,                                          // 0x1ec
341    pub _pad5: [u8; 2],                                           // 0x1ed
342    pub sentinel: u8,                                             // 0x1ef
343    pub _pad6: [u8; 1],                                           // 0x1f0
344    pub hdr: setup_header,                                        // 0x1f1
345    pub _pad7: [u8; 36],                                          // 0x26c
346    pub edd_mbr_sig_buffer: [u32; EDD_MBR_SIG_MAX],               // 0x290
347    pub e820_table: [boot_e820_entry; E820_MAX_ENTRIES_ZEROPAGE], // 0x2d0
348    pub _pad8: [u8; 48],                                          // 0xcd0
349    pub eddbuf: [edd_info; EDDMAXNR],                             // 0xd00
350    pub _pad9: [u8; 276],                                         // 0xeec
351}
352
353#[repr(u32)]
354#[derive(Debug, Default, Copy, Clone, PartialEq, Eq)]
355pub enum x86_hardware_subarch {
356    #[default]
357    X86_SUBARCH_PC = 0,
358    X86_SUBARCH_LGUEST = 1,
359    X86_SUBARCH_XEN = 2,
360    X86_SUBARCH_INTEL_MID = 3,
361    X86_SUBARCH_CE4100 = 4,
362}
363
364pub const X86_NR_SUBARCHS: u32 = 5;
365
366impl Default for boot_params {
367    fn default() -> Self {
368        unsafe { core::mem::zeroed() }
369    }
370}
371
372// ============================================================================
373// Compile-time layout assertions
374// ============================================================================
375
376const _: () = assert!(core::mem::size_of::<screen_info>() == 0x40);
377const _: () = assert!(core::mem::size_of::<apm_bios_info>() == 0x14);
378const _: () = assert!(core::mem::size_of::<ist_info>() == 0x10);
379const _: () = assert!(core::mem::size_of::<edid_info>() == 0x80);
380const _: () = assert!(core::mem::size_of::<boot_e820_entry>() == 20);
381const _: () = assert!(core::mem::size_of::<edd_device_params>() == EDDPARMSIZE);
382const _: () = assert!(core::mem::size_of::<edd_info>() == EDDEXTSIZE + EDDPARMSIZE);
383const _: () = assert!(core::mem::size_of::<sys_desc_table>() == 0x10);
384const _: () = assert!(core::mem::size_of::<olpc_ofw_header>() == 0x10);
385const _: () = assert!(core::mem::size_of::<efi_info>() == 0x20);
386const _: () = assert!(core::mem::size_of::<setup_header>() == 123);
387const _: () = assert!(core::mem::size_of::<boot_params>() == 4096);