Skip to content

Commit 4b3d8f8

Browse files
committed
boot: Add structures for Info, E820, and Params
To support multiple boot protocols, we need a common abstraction for the information given in a boot protocol. This is the Info trait. This also requires adding a common E820Entry structure, so we can get the memory map. We also add a boot::Params structure (i.e. the Linux Zeropage) to make reading/writing the structure easier. This will let us avoid needing to hardcode struct offsets. The layout for these structures is taken from the Kernel's arch/x86/include/uapi/asm/bootparam.h Signed-off-by: Joe Richey <joerichey@google.com>
1 parent a59b528 commit 4b3d8f8

File tree

2 files changed

+188
-0
lines changed

2 files changed

+188
-0
lines changed

src/boot.rs

Lines changed: 187 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,187 @@
1+
use core::mem;
2+
3+
use crate::common;
4+
5+
// Common data needed for all boot paths
6+
pub trait Info {
7+
// Starting address of the Root System Descriptor Pointer
8+
fn rsdp_addr(&self) -> u64;
9+
// The kernel command line (not including null terminator)
10+
fn cmdline(&self) -> &[u8];
11+
// Methods to access the E820 Memory map
12+
fn num_entries(&self) -> u8;
13+
fn entry(&self, idx: u8) -> E820Entry;
14+
}
15+
16+
#[derive(Clone, Copy, Debug)]
17+
#[repr(C, packed)]
18+
pub struct E820Entry {
19+
pub addr: u64,
20+
pub size: u64,
21+
pub entry_type: u32,
22+
}
23+
24+
impl E820Entry {
25+
pub const RAM_TYPE: u32 = 1;
26+
}
27+
28+
// The so-called "zeropage"
29+
#[derive(Clone, Copy)]
30+
#[repr(C, packed)]
31+
pub struct Params {
32+
screen_info: ScreenInfo, // 0x000
33+
apm_bios_info: ApmBiosInfo, // 0x040
34+
_pad2: [u8; 4], // 0x054
35+
tboot_addr: u64, // 0x058
36+
ist_info: IstInfo, // 0x060
37+
pub acpi_rsdp_addr: u64, // 0x070
38+
_pad3: [u8; 8], // 0x078
39+
hd0_info: HdInfo, // 0x080 - obsolete
40+
hd1_info: HdInfo, // 0x090 - obsolete
41+
sys_desc_table: SysDescTable, // 0x0a0 - obsolete
42+
olpc_ofw_header: OlpcOfwHeader, // 0x0b0
43+
ext_ramdisk_image: u32, // 0x0c0
44+
ext_ramdisk_size: u32, // 0x0c4
45+
ext_cmd_line_ptr: u32, // 0x0c8
46+
_pad4: [u8; 0x74], // 0x0cc
47+
edd_info: EdidInfo, // 0x140
48+
efi_info: EfiInfo, // 0x1c0
49+
alt_mem_k: u32, // 0x1e0
50+
scratch: u32, // 0x1e4
51+
e820_entries: u8, // 0x1e8
52+
eddbuf_entries: u8, // 0x1e9
53+
edd_mbr_sig_buf_entries: u8, // 0x1ea
54+
kbd_status: u8, // 0x1eb
55+
secure_boot: u8, // 0x1ec
56+
_pad5: [u8; 2], // 0x1ed
57+
sentinel: u8, // 0x1ef
58+
_pad6: [u8; 1], // 0x1f0
59+
pub hdr: Header, // 0x1f1
60+
_pad7: [u8; 0x290 - HEADER_END],
61+
edd_mbr_sig_buffer: [u32; 16], // 0x290
62+
e820_table: [E820Entry; 128], // 0x2d0
63+
_pad8: [u8; 0x30], // 0xcd0
64+
eddbuf: [EddInfo; 6], // 0xd00
65+
_pad9: [u8; 0x114], // 0xeec
66+
}
67+
68+
impl Default for Params {
69+
fn default() -> Self {
70+
// SAFETY: Struct consists entirely of primitive integral types.
71+
unsafe { mem::zeroed() }
72+
}
73+
}
74+
75+
impl Params {
76+
pub fn set_entries(&mut self, info: &dyn Info) {
77+
self.e820_entries = info.num_entries();
78+
for i in 0..self.e820_entries {
79+
self.e820_table[i as usize] = info.entry(i);
80+
}
81+
}
82+
}
83+
84+
impl Info for Params {
85+
fn rsdp_addr(&self) -> u64 {
86+
self.acpi_rsdp_addr
87+
}
88+
fn cmdline(&self) -> &[u8] {
89+
unsafe { common::from_cstring(self.hdr.cmd_line_ptr as u64) }
90+
}
91+
fn num_entries(&self) -> u8 {
92+
self.e820_entries
93+
}
94+
fn entry(&self, idx: u8) -> E820Entry {
95+
assert!(idx < self.num_entries());
96+
self.e820_table[idx as usize]
97+
}
98+
}
99+
100+
const HEADER_START: usize = 0x1f1;
101+
const HEADER_END: usize = HEADER_START + mem::size_of::<Header>();
102+
103+
#[derive(Clone, Copy, Debug)]
104+
#[repr(C, packed)]
105+
pub struct Header {
106+
pub setup_sects: u8,
107+
pub root_flags: u16,
108+
pub syssize: u32,
109+
pub ram_size: u16,
110+
pub vid_mode: u16,
111+
pub root_dev: u16,
112+
pub boot_flag: u16,
113+
pub jump: u16,
114+
pub header: [u8; 4],
115+
pub version: u16,
116+
pub realmode_swtch: u32,
117+
pub start_sys_seg: u16,
118+
pub kernel_version: u16,
119+
pub type_of_loader: u8,
120+
pub loadflags: u8,
121+
pub setup_move_size: u16,
122+
pub code32_start: u32,
123+
pub ramdisk_image: u32,
124+
pub ramdisk_size: u32,
125+
pub bootsect_kludge: u32,
126+
pub heap_end_ptr: u16,
127+
pub ext_loader_ver: u8,
128+
pub ext_loader_type: u8,
129+
pub cmd_line_ptr: u32,
130+
pub initrd_addr_max: u32,
131+
pub kernel_alignment: u32,
132+
pub relocatable_kernel: u8,
133+
pub min_alignment: u8,
134+
pub xloadflags: u16,
135+
pub cmdline_size: u32,
136+
pub hardware_subarch: u32,
137+
pub hardware_subarch_data: u64,
138+
pub payload_offset: u32,
139+
pub payload_length: u32,
140+
pub setup_data: u64,
141+
pub pref_address: u64,
142+
pub init_size: u32,
143+
pub handover_offset: u32,
144+
}
145+
146+
// Right now the stucts below are unused, so we only need them to be the correct
147+
// size. Update test_size_and_offset if a struct's real definition is added.
148+
#[derive(Clone, Copy)]
149+
#[repr(C, packed)]
150+
struct ScreenInfo([u8; 0x40]);
151+
#[derive(Clone, Copy)]
152+
#[repr(C, packed)]
153+
struct ApmBiosInfo([u8; 0x14]);
154+
#[derive(Clone, Copy)]
155+
#[repr(C, packed)]
156+
struct IstInfo([u8; 0x10]);
157+
#[derive(Clone, Copy)]
158+
#[repr(C, packed)]
159+
struct HdInfo([u8; 0x10]);
160+
#[derive(Clone, Copy)]
161+
#[repr(C, packed)]
162+
struct SysDescTable([u8; 0x10]);
163+
#[derive(Clone, Copy)]
164+
#[repr(C, packed)]
165+
struct OlpcOfwHeader([u8; 0x10]);
166+
#[derive(Clone, Copy)]
167+
#[repr(C, packed)]
168+
struct EdidInfo([u8; 0x80]);
169+
#[derive(Clone, Copy)]
170+
#[repr(C, packed)]
171+
struct EfiInfo([u8; 0x20]);
172+
#[derive(Clone, Copy)]
173+
#[repr(C, packed)]
174+
struct EddInfo([u8; 0x52]);
175+
176+
#[cfg(test)]
177+
mod tests {
178+
use super::*;
179+
#[test]
180+
fn test_size_and_offset() {
181+
assert_eq!(mem::size_of::<Header>(), 119);
182+
assert_eq!(mem::size_of::<E820Entry>(), 20);
183+
assert_eq!(mem::size_of::<Params>(), 4096);
184+
185+
assert_eq!(offset_of!(Params, hdr), HEADER_START);
186+
}
187+
}

src/main.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@ mod common;
3434
#[cfg(not(test))]
3535
mod asm;
3636
mod block;
37+
mod boot;
3738
mod bzimage;
3839
mod efi;
3940
mod fat;

0 commit comments

Comments
 (0)