Skip to content

Commit d5e99f7

Browse files
committed
multiboot2: Support passing the EFI System Table
1 parent 6379b42 commit d5e99f7

File tree

2 files changed

+83
-2
lines changed

2 files changed

+83
-2
lines changed

multiboot2/src/builder/information.rs

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
//! Exports item [`Multiboot2InformationBuilder`].
22
use crate::builder::traits::StructAsBytes;
33
use crate::{
4-
BasicMemoryInfoTag, BootInformationInner, BootLoaderNameTag, CommandLineTag, ElfSectionsTag,
5-
EndTag, FramebufferTag, MemoryMapTag, ModuleTag,
4+
BasicMemoryInfoTag, BootInformationInner, BootLoaderNameTag, CommandLineTag, EFISdt32,
5+
EFISdt64, ElfSectionsTag, EndTag, FramebufferTag, MemoryMapTag, ModuleTag,
66
};
77

88
use alloc::boxed::Box;
@@ -21,6 +21,8 @@ pub struct Multiboot2InformationBuilder {
2121
framebuffer_tag: Option<Box<FramebufferTag>>,
2222
memory_map_tag: Option<Box<MemoryMapTag>>,
2323
module_tags: Vec<Box<ModuleTag>>,
24+
efisdt32: Option<EFISdt32>,
25+
efisdt64: Option<EFISdt64>,
2426
}
2527

2628
impl Multiboot2InformationBuilder {
@@ -29,6 +31,8 @@ impl Multiboot2InformationBuilder {
2931
basic_memory_info_tag: None,
3032
boot_loader_name_tag: None,
3133
command_line_tag: None,
34+
efisdt32: None,
35+
efisdt64: None,
3236
elf_sections_tag: None,
3337
framebuffer_tag: None,
3438
memory_map_tag: None,
@@ -66,6 +70,12 @@ impl Multiboot2InformationBuilder {
6670
if let Some(tag) = &self.command_line_tag {
6771
len += Self::size_or_up_aligned(tag.byte_size())
6872
}
73+
if let Some(tag) = &self.efisdt32 {
74+
len += Self::size_or_up_aligned(tag.byte_size())
75+
}
76+
if let Some(tag) = &self.efisdt64 {
77+
len += Self::size_or_up_aligned(tag.byte_size())
78+
}
6979
if let Some(tag) = &self.elf_sections_tag {
7080
len += Self::size_or_up_aligned(tag.byte_size())
7181
}
@@ -117,6 +127,12 @@ impl Multiboot2InformationBuilder {
117127
if let Some(tag) = self.command_line_tag.as_ref() {
118128
Self::build_add_bytes(&mut data, &tag.struct_as_bytes(), false)
119129
}
130+
if let Some(tag) = self.efisdt32.as_ref() {
131+
Self::build_add_bytes(&mut data, &tag.struct_as_bytes(), false)
132+
}
133+
if let Some(tag) = self.efisdt64.as_ref() {
134+
Self::build_add_bytes(&mut data, &tag.struct_as_bytes(), false)
135+
}
120136
if let Some(tag) = self.elf_sections_tag.as_ref() {
121137
Self::build_add_bytes(&mut data, &tag.struct_as_bytes(), false)
122138
}
@@ -147,6 +163,14 @@ impl Multiboot2InformationBuilder {
147163
self.command_line_tag = Some(command_line_tag);
148164
}
149165

166+
pub fn efisdt32(&mut self, efisdt32: EFISdt32) {
167+
self.efisdt32 = Some(efisdt32);
168+
}
169+
170+
pub fn efisdt64(&mut self, efisdt64: EFISdt64) {
171+
self.efisdt64 = Some(efisdt64);
172+
}
173+
150174
pub fn elf_sections_tag(&mut self, elf_sections_tag: Box<ElfSectionsTag>) {
151175
self.elf_sections_tag = Some(elf_sections_tag);
152176
}

multiboot2/src/efi.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,12 @@
11
//! All MBI tags related to (U)EFI.
22
3+
use crate::TagType;
34
use crate::TagTypeId;
5+
use core::convert::TryInto;
6+
use core::mem::size_of;
7+
8+
#[cfg(feature = "builder")]
9+
use crate::builder::traits::StructAsBytes;
410

511
/// EFI system table in 32 bit mode
612
#[derive(Clone, Copy, Debug)]
@@ -12,12 +18,28 @@ pub struct EFISdt32 {
1218
}
1319

1420
impl EFISdt32 {
21+
/// Create a new tag to pass the EFI32 System Table pointer.
22+
pub fn new(pointer: u32) -> Self {
23+
Self {
24+
typ: TagType::Efi32.into(),
25+
size: size_of::<Self>().try_into().unwrap(),
26+
pointer,
27+
}
28+
}
29+
1530
/// The physical address of a i386 EFI system table.
1631
pub fn sdt_address(&self) -> usize {
1732
self.pointer as usize
1833
}
1934
}
2035

36+
#[cfg(feature = "builder")]
37+
impl StructAsBytes for EFISdt32 {
38+
fn byte_size(&self) -> usize {
39+
size_of::<Self>()
40+
}
41+
}
42+
2143
/// EFI system table in 64 bit mode
2244
#[derive(Clone, Copy, Debug)]
2345
#[repr(C)]
@@ -28,12 +50,28 @@ pub struct EFISdt64 {
2850
}
2951

3052
impl EFISdt64 {
53+
/// Create a new tag to pass the EFI64 System Table pointer.
54+
pub fn new(pointer: u64) -> Self {
55+
Self {
56+
typ: TagType::Efi64.into(),
57+
size: size_of::<Self>().try_into().unwrap(),
58+
pointer,
59+
}
60+
}
61+
3162
/// The physical address of a x86_64 EFI system table.
3263
pub fn sdt_address(&self) -> usize {
3364
self.pointer as usize
3465
}
3566
}
3667

68+
#[cfg(feature = "builder")]
69+
impl StructAsBytes for EFISdt64 {
70+
fn byte_size(&self) -> usize {
71+
size_of::<Self>()
72+
}
73+
}
74+
3775
/// Contains pointer to boot loader image handle.
3876
#[derive(Debug)]
3977
#[repr(C)]
@@ -65,3 +103,22 @@ impl EFIImageHandle64 {
65103
self.pointer as usize
66104
}
67105
}
106+
107+
#[cfg(test)]
108+
mod tests {
109+
use super::{EFISdt32, EFISdt64};
110+
111+
const ADDR: usize = 0xABCDEF;
112+
113+
#[test]
114+
fn test_build_eftsdt32() {
115+
let tag = EFISdt32::new(ADDR.try_into().unwrap());
116+
assert_eq!(tag.sdt_address(), ADDR);
117+
}
118+
119+
#[test]
120+
fn test_build_eftsdt64() {
121+
let tag = EFISdt64::new(ADDR.try_into().unwrap());
122+
assert_eq!(tag.sdt_address(), ADDR);
123+
}
124+
}

0 commit comments

Comments
 (0)