Skip to content

Commit 714905b

Browse files
authored
Merge pull request #133 from YtvwlD/bootloader
Add a builder to multiboot2
2 parents 455f7bc + 69630b3 commit 714905b

18 files changed

+1377
-269
lines changed

multiboot2-header/src/builder/header.rs

+16-2
Original file line numberDiff line numberDiff line change
@@ -244,7 +244,7 @@ mod tests {
244244
}
245245

246246
#[test]
247-
fn test_size_builder() {
247+
fn test_builder() {
248248
let builder = Multiboot2HeaderBuilder::new(HeaderTagISA::I386);
249249
// Multiboot2 basic header + end tag
250250
let mut expected_len = 16 + 8;
@@ -274,14 +274,28 @@ mod tests {
274274
4096,
275275
RelocatableHeaderTagPreference::None,
276276
));
277+
expected_len += 0x18;
278+
assert_eq!(builder.expected_len(), expected_len);
277279

278280
println!("builder: {:#?}", builder);
279281
println!("expected_len: {} bytes", builder.expected_len());
280282

281283
let mb2_hdr_data = builder.build();
282284
let mb2_hdr = mb2_hdr_data.as_ptr() as usize;
283-
let mb2_hdr = unsafe { Multiboot2Header::from_addr(mb2_hdr) };
285+
let mb2_hdr = unsafe { Multiboot2Header::from_addr(mb2_hdr) }
286+
.expect("the generated header to be loadable");
284287
println!("{:#?}", mb2_hdr);
288+
assert_eq!(
289+
mb2_hdr.relocatable_tag().unwrap().flags(),
290+
HeaderTagFlag::Required
291+
);
292+
assert_eq!(mb2_hdr.relocatable_tag().unwrap().min_addr(), 0x1337);
293+
assert_eq!(mb2_hdr.relocatable_tag().unwrap().max_addr(), 0xdeadbeef);
294+
assert_eq!(mb2_hdr.relocatable_tag().unwrap().align(), 4096);
295+
assert_eq!(
296+
mb2_hdr.relocatable_tag().unwrap().preference(),
297+
RelocatableHeaderTagPreference::None
298+
);
285299

286300
/* you can write the binary to a file and a tool such as crate "bootinfo"
287301
will be able to fully parse the MB2 header

multiboot2-header/src/relocatable.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ use core::mem::size_of;
88
/// but not lower than min addr and ‘2’ means load image at highest possible
99
/// address but not higher than max addr.
1010
#[repr(u32)]
11-
#[derive(Copy, Clone, Debug)]
11+
#[derive(Copy, Clone, Debug, PartialEq)]
1212
pub enum RelocatableHeaderTagPreference {
1313
/// Let boot loader decide.
1414
None = 0,

multiboot2/Cargo.toml

+4-1
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,10 @@ repository = "https://github.com/rust-osdev/multiboot2"
3232
documentation = "https://docs.rs/multiboot2"
3333

3434
[features]
35-
default = []
35+
# by default, builder is included
36+
default = ["builder"]
37+
std = []
38+
builder = ["std"]
3639
# Nightly-only features that will eventually be stabilized.
3740
unstable = []
3841

multiboot2/src/boot_loader_name.rs

+37-6
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,16 @@
1-
use crate::TagTrait;
2-
use crate::{Tag, TagTypeId};
1+
use crate::{Tag, TagTrait, TagType, TagTypeId};
32
use core::fmt::{Debug, Formatter};
3+
use core::mem::size_of;
44
use core::str::Utf8Error;
55

6+
#[cfg(feature = "builder")]
7+
use {
8+
crate::builder::boxed_dst_tag, crate::builder::traits::StructAsBytes, alloc::boxed::Box,
9+
alloc::vec::Vec,
10+
};
11+
12+
const METADATA_SIZE: usize = size_of::<TagTypeId>() + size_of::<u32>();
13+
614
/// The bootloader name tag.
715
#[derive(ptr_meta::Pointee)]
816
#[repr(C, packed)] // only repr(C) would add unwanted padding before first_section
@@ -14,6 +22,13 @@ pub struct BootLoaderNameTag {
1422
}
1523

1624
impl BootLoaderNameTag {
25+
#[cfg(feature = "builder")]
26+
pub fn new(name: &str) -> Box<Self> {
27+
let mut bytes: Vec<_> = name.bytes().collect();
28+
bytes.push(0);
29+
boxed_dst_tag(TagType::BootLoaderName, &bytes)
30+
}
31+
1732
/// Reads the name of the bootloader that is booting the kernel as Rust
1833
/// string slice without the null-byte.
1934
///
@@ -46,10 +61,15 @@ impl Debug for BootLoaderNameTag {
4661

4762
impl TagTrait for BootLoaderNameTag {
4863
fn dst_size(base_tag: &Tag) -> usize {
49-
// The size of the sized portion of the bootloader name tag.
50-
let tag_base_size = 8;
51-
assert!(base_tag.size >= 8);
52-
base_tag.size as usize - tag_base_size
64+
assert!(base_tag.size as usize >= METADATA_SIZE);
65+
base_tag.size as usize - METADATA_SIZE
66+
}
67+
}
68+
69+
#[cfg(feature = "builder")]
70+
impl StructAsBytes for BootLoaderNameTag {
71+
fn byte_size(&self) -> usize {
72+
self.size.try_into().unwrap()
5373
}
5474
}
5575

@@ -85,4 +105,15 @@ mod tests {
85105
assert_eq!({ tag.typ }, TagType::BootLoaderName);
86106
assert_eq!(tag.name().expect("must be valid UTF-8"), MSG);
87107
}
108+
109+
/// Test to generate a tag from a given string.
110+
#[test]
111+
#[cfg(feature = "builder")]
112+
fn test_build_str() {
113+
use crate::builder::traits::StructAsBytes;
114+
115+
let tag = BootLoaderNameTag::new(MSG);
116+
let bytes = tag.struct_as_bytes();
117+
assert_eq!(bytes, get_bytes());
118+
}
88119
}

0 commit comments

Comments
 (0)