loader_defs/
linux.rs

1// Copyright (c) Microsoft Corporation.
2// Licensed under the MIT License.
3
4//! Linux loader definitions.
5//!
6//! These structures are defined in the Linux kernel and can be found in the kernel docs under
7//! [`The Linux/x86 Boot Protocol`](https://www.kernel.org/doc/html/latest/x86/boot.html).
8
9#![expect(missing_docs)]
10
11use static_assertions::const_assert_eq;
12use zerocopy::FromBytes;
13use zerocopy::FromZeros;
14use zerocopy::Immutable;
15use zerocopy::IntoBytes;
16use zerocopy::KnownLayout;
17
18#[allow(non_camel_case_types)]
19mod packed_nums {
20    pub type u16_ne = zerocopy::U16<zerocopy::NativeEndian>;
21    pub type u32_ne = zerocopy::U32<zerocopy::NativeEndian>;
22    pub type u64_ne = zerocopy::U64<zerocopy::NativeEndian>;
23}
24use self::packed_nums::*;
25
26#[repr(C)]
27#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
28pub struct apm_bios_info {
29    pub version: u16,
30    pub cseg: u16,
31    pub offset: u32,
32    pub cseg_16: u16,
33    pub dseg: u16,
34    pub flags: u16,
35    pub cseg_len: u16,
36    pub cseg_16_len: u16,
37    pub dseg_len: u16,
38}
39
40#[repr(C)]
41#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
42pub struct screen_info {
43    pub orig_x: u8,
44    pub orig_y: u8,
45    pub ext_mem_k: u16,
46    pub orig_video_page: u16,
47    pub orig_video_mode: u8,
48    pub orig_video_cols: u8,
49    pub flags: u8,
50    pub unused2: u8,
51    pub orig_video_ega_bx: u16,
52    pub unused3: u16,
53    pub orig_video_lines: u8,
54    pub orig_video_is_vga: u8,
55    pub orig_video_points: u16,
56    pub lfb_width: u16,
57    pub lfb_height: u16,
58    pub lfb_depth: u16,
59    pub lfb_base: u32,
60    pub lfb_size: u32,
61    pub cl_magic: u16,
62    pub cl_offset: u16,
63    pub lfb_linelength: u16,
64    pub red_size: u8,
65    pub red_pos: u8,
66    pub green_size: u8,
67    pub green_pos: u8,
68    pub blue_size: u8,
69    pub blue_pos: u8,
70    pub rsvd_size: u8,
71    pub rsvd_pos: u8,
72    pub vesapm_seg: u16,
73    pub vesapm_off: u16,
74    pub pages: u16,
75    pub vesa_attributes: u16,
76    pub capabilities: u32_ne,
77    pub _reserved: [u8; 6],
78}
79
80#[repr(C)]
81#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
82pub struct sys_desc_table {
83    pub length: u16,
84    pub table: [u8; 14],
85}
86
87#[repr(C)]
88#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
89pub struct olpc_ofw_header {
90    pub ofw_magic: u32,
91    pub ofw_version: u32,
92    pub cif_handler: u32,
93    pub irq_desc_table: u32,
94}
95
96#[repr(C)]
97#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
98pub struct edid_info {
99    pub dummy: [u8; 128],
100}
101
102#[repr(C)]
103#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
104pub struct efi_info {
105    pub efi_loader_signature: u32,
106    pub efi_systab: u32,
107    pub efi_memdesc_size: u32,
108    pub efi_memdesc_version: u32,
109    pub efi_memmap: u32,
110    pub efi_memmap_size: u32,
111    pub efi_systab_hi: u32,
112    pub efi_memmap_hi: u32,
113}
114
115#[repr(C)]
116#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
117pub struct setup_header {
118    pub setup_sects: u8,
119    pub root_flags: u16_ne,
120    pub syssize: u32_ne,
121    pub ram_size: u16_ne,
122    pub vid_mode: u16_ne,
123    pub root_dev: u16_ne,
124    pub boot_flag: u16_ne,
125    pub jump: u16_ne,
126    pub header: u32_ne,
127    pub version: u16_ne,
128    pub realmode_swtch: u32_ne,
129    pub start_sys: u16_ne,
130    pub kernel_version: u16_ne,
131    pub type_of_loader: u8,
132    pub loadflags: u8,
133    pub setup_move_size: u16_ne,
134    pub code32_start: u32_ne,
135    pub ramdisk_image: u32_ne,
136    pub ramdisk_size: u32_ne,
137    pub bootsect_kludge: u32_ne,
138    pub heap_end_ptr: u16_ne,
139    pub ext_loader_ver: u8,
140    pub ext_loader_type: u8,
141    pub cmd_line_ptr: u32_ne,
142    pub initrd_addr_max: u32_ne,
143    pub kernel_alignment: u32_ne,
144    pub relocatable_kernel: u8,
145    pub min_alignment: u8,
146    pub xloadflags: u16_ne,
147    pub cmdline_size: u32_ne,
148    pub hardware_subarch: u32_ne,
149    pub hardware_subarch_data: u64_ne,
150    pub payload_offset: u32_ne,
151    pub payload_length: u32_ne,
152    pub setup_data: u64_ne,
153    pub pref_address: u64_ne,
154    pub init_size: u32_ne,
155    pub handover_offset: u32_ne,
156}
157
158// TODO: zerocopy doesn't support const new methods, so define them as u32 for now. (https://github.com/microsoft/openvmm/issues/759)
159pub const E820_RAM: u32 = 1;
160pub const E820_RESERVED: u32 = 2;
161pub const E820_ACPI: u32 = 3;
162pub const E820_NVS: u32 = 4;
163pub const E820_UNUSABLE: u32 = 5;
164
165#[repr(C)]
166#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
167pub struct e820entry {
168    pub addr: u64_ne,
169    pub size: u64_ne,
170    pub typ: u32_ne,
171}
172
173#[repr(C)]
174#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
175pub struct edd_info {
176    pub device: u8,
177    pub version: u8,
178    pub interface_support: u16,
179    pub legacy_max_cylinder: u16,
180    pub legacy_max_head: u8,
181    pub legacy_sectors_per_track: u8,
182    pub params: edd_device_params,
183}
184
185#[repr(C)]
186#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
187pub struct edd_device_params {
188    pub length: u16,
189    pub info_flags: u16,
190    pub num_default_cylinders: u32_ne,
191    pub num_default_heads: u32_ne,
192    pub sectors_per_track: u32_ne,
193    pub number_of_sectors: u64_ne,
194    pub bytes_per_sector: u16,
195    pub dpte_ptr: u32_ne,
196    pub key: u16,
197    pub device_path_info_length: u8,
198    pub reserved2: u8,
199    pub reserved3: u16,
200    pub host_bus_type: [u8; 4],
201    pub interface_type: [u8; 8],
202    pub interface_path: [u8; 8],
203    pub device_path: [u8; 16],
204    pub reserved4: u8,
205    pub checksum: u8,
206}
207
208#[repr(C)]
209#[derive(Debug, Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
210pub struct ist_info {
211    pub signature: u32,
212    pub command: u32,
213    pub event: u32,
214    pub perf_level: u32,
215}
216
217#[repr(C)]
218#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
219pub struct boot_params {
220    pub screen_info: screen_info,
221    pub apm_bios_info: apm_bios_info,
222    pub _pad2: [u8; 4],
223    pub tboot_addr: u64,
224    pub ist_info: ist_info,
225    pub _pad3: [u8; 16],
226    pub hd0_info: [u8; 16],
227    pub hd1_info: [u8; 16],
228    pub sys_desc_table: sys_desc_table,
229    pub olpc_ofw_header: olpc_ofw_header,
230    pub ext_ramdisk_image: u32,
231    pub ext_ramdisk_size: u32,
232    pub ext_cmd_line_ptr: u32,
233    pub _pad4: [[u8; 29]; 4],
234    pub edid_info: edid_info,
235    pub efi_info: efi_info,
236    pub alt_mem_k: u32,
237    pub scratch: u32,
238    pub e820_entries: u8,
239    pub eddbuf_entries: u8,
240    pub edd_mbr_sig_buf_entries: u8,
241    pub kbd_status: u8,
242    pub _pad5: [u8; 3],
243    pub sentinel: u8,
244    pub _pad6: [u8; 1],
245    pub hdr: setup_header,
246    pub _pad7: [u8; 40],
247    pub edd_mbr_sig_buffer: [u32; 16],
248    pub e820_map: [e820entry; 128],
249    pub _pad8: [u8; 48],
250    pub eddbuf: [edd_info; 6],
251    pub _pad9: [[u8; 23]; 12],
252}
253
254impl Default for boot_params {
255    fn default() -> Self {
256        FromZeros::new_zeroed()
257    }
258}
259
260const_assert_eq!(size_of::<boot_params>(), 4096);
261
262// This must be aligned so that it doesn't straddle a page boundary.
263#[repr(C, align(16))]
264#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
265pub struct setup_data {
266    pub next: u64,
267    pub ty: u32,
268    pub len: u32,
269}
270
271pub const SETUP_E820_EXT: u32 = 1;
272pub const SETUP_DTB: u32 = 2;
273pub const SETUP_CC_BLOB: u32 = 7;
274
275#[repr(C)]
276#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
277pub struct cc_blob_sev_info {
278    pub magic: u32,
279    pub version: u16,
280    pub _reserved: u16,
281    pub secrets_phys: u64,
282    pub secrets_len: u32,
283    pub _rsvd1: u32,
284    pub cpuid_phys: u64,
285    pub cpuid_len: u32,
286    pub _rsvd2: u32,
287}
288
289pub const CC_BLOB_SEV_INFO_MAGIC: u32 = 0x45444d41;
290
291#[repr(C, align(16))]
292#[derive(Copy, Clone, IntoBytes, Immutable, KnownLayout, FromBytes)]
293pub struct cc_setup_data {
294    pub header: setup_data,
295    pub cc_blob_address: u32,
296    pub _padding: [u32; 3],
297}