Skip to content

Commit c3aca97

Browse files
committed
multiboot2: Add SMBIOS tag
1 parent 4bf969f commit c3aca97

File tree

2 files changed

+76
-0
lines changed

2 files changed

+76
-0
lines changed

multiboot2/src/lib.rs

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ pub use memory_map::{
5757
};
5858
pub use module::{ModuleIter, ModuleTag};
5959
pub use rsdp::{RsdpV1Tag, RsdpV2Tag};
60+
pub use smbios::SmbiosTag;
6061
use tag_type::TagIter;
6162
pub use tag_type::{Tag, TagType, TagTypeId};
6263
pub use vbe_info::{
@@ -76,6 +77,7 @@ mod image_load_addr;
7677
mod memory_map;
7778
mod module;
7879
mod rsdp;
80+
mod smbios;
7981
mod tag_type;
8082
mod vbe_info;
8183

@@ -309,6 +311,11 @@ impl BootInformation {
309311
self.get_tag::<VBEInfoTag, _>(TagType::Vbe)
310312
}
311313

314+
/// Search for the SMBIOS tag.
315+
pub fn smbios_tag(&self) -> Option<&SmbiosTag> {
316+
self.get_tag::<SmbiosTag, _>(TagType::Smbios)
317+
}
318+
312319
fn get(&self) -> &BootInformationInner {
313320
unsafe { &*self.inner }
314321
}

multiboot2/src/smbios.rs

Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
use crate::{Tag, TagTrait, TagTypeId};
2+
3+
use core::fmt::Debug;
4+
5+
const METADATA_SIZE: usize = core::mem::size_of::<TagTypeId>()
6+
+ core::mem::size_of::<u32>()
7+
+ core::mem::size_of::<u8>() * 8;
8+
9+
/// This tag contains a copy of SMBIOS tables as well as their version.
10+
#[derive(ptr_meta::Pointee)]
11+
#[repr(C, packed)]
12+
pub struct SmbiosTag {
13+
typ: TagTypeId,
14+
size: u32,
15+
pub major: u8,
16+
pub minor: u8,
17+
_reserved: [u8; 6],
18+
pub tables: [u8],
19+
}
20+
21+
impl TagTrait for SmbiosTag {
22+
fn dst_size(base_tag: &Tag) -> usize {
23+
assert!(base_tag.size as usize >= METADATA_SIZE);
24+
base_tag.size as usize - METADATA_SIZE
25+
}
26+
}
27+
28+
impl Debug for SmbiosTag {
29+
fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
30+
f.debug_struct("BootLoaderNameTag")
31+
.field("typ", &{ self.typ })
32+
.field("size", &{ self.size })
33+
.field("major", &{ self.major })
34+
.field("minor", &{ self.minor })
35+
.finish()
36+
}
37+
}
38+
39+
#[cfg(test)]
40+
mod tests {
41+
use crate::{SmbiosTag, Tag, TagType};
42+
43+
/// Returns the tag structure in bytes in native endian format.
44+
fn get_bytes() -> std::vec::Vec<u8> {
45+
let tables = [0xabu8; 24];
46+
// size is: 4 bytes for tag + 4 bytes for size + 1 byte for major and minor
47+
// + 6 bytes reserved + the actual tables
48+
let size = (4 + 4 + 1 + 1 + 6 + tables.len()) as u32;
49+
let typ: u32 = TagType::Smbios.into();
50+
let mut bytes = [typ.to_ne_bytes(), size.to_ne_bytes()].concat();
51+
bytes.push(3);
52+
bytes.push(0);
53+
bytes.extend([0; 6]);
54+
bytes.extend(tables);
55+
bytes
56+
}
57+
58+
/// Test to parse a given tag.
59+
#[test]
60+
fn test_parse() {
61+
let tag = get_bytes();
62+
let tag = unsafe { &*tag.as_ptr().cast::<Tag>() };
63+
let tag = tag.cast_tag::<SmbiosTag>();
64+
assert_eq!({ tag.typ }, TagType::Smbios);
65+
assert_eq!(tag.major, 3);
66+
assert_eq!(tag.minor, 0);
67+
assert_eq!(tag.tables, [0xabu8; 24]);
68+
}
69+
}

0 commit comments

Comments
 (0)