Skip to content

Add a builder to multiboot2 #133

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 20 commits into from
Jun 19, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
152c985
multiboot2: Add basic information builder
YtvwlD Mar 6, 2023
544e1ca
multiboot2: Implement setting the command line
YtvwlD Mar 6, 2023
535c9e7
multiboot2: Implement adding module tags
YtvwlD Mar 7, 2023
41428fb
multiboot2: Implement setting ELF section tag
YtvwlD Mar 7, 2023
08df6c2
multiboot2: Implement setting boot loader name
YtvwlD Mar 7, 2023
bb21998
multiboot2: Implement setting the framebuffer tag
YtvwlD Mar 8, 2023
0320148
multiboot2: Implement setting the BasicMemoryInfoTag
YtvwlD Mar 8, 2023
d198dce
multiboot2: Implement setting memory map tag
YtvwlD Mar 8, 2023
122fc9c
multiboot2: Implement building the multiboot2 information
YtvwlD Mar 8, 2023
6379b42
multiboot2: Implement Debug and PartialEq for packed structs
YtvwlD Mar 14, 2023
d5e99f7
multiboot2: Support passing the EFI System Table
YtvwlD Mar 27, 2023
888dd27
multiboot2: Allow setting the SMBIOS tag
YtvwlD Mar 28, 2023
79646bb
multiboot2: Allow setting the RSDP tags
YtvwlD Mar 28, 2023
690c84a
multiboot2: Support setting the EFI memory map tag
YtvwlD Apr 3, 2023
12f4642
multiboot2: Support setting Boot Services not exited tag
YtvwlD Apr 3, 2023
ed316cb
multiboot2: Support setting the image handle pointer
YtvwlD Apr 4, 2023
cbc47ab
multiboot2: Support setting the image load address
YtvwlD Apr 4, 2023
2f2a058
multiboot2: Improve builder test
YtvwlD Jun 4, 2023
09de523
multiboot2-header: Improve builder test
YtvwlD Jun 4, 2023
69630b3
multiboot2: Don't require an offset for the ELF sections
YtvwlD Jun 19, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 16 additions & 2 deletions multiboot2-header/src/builder/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -244,7 +244,7 @@ mod tests {
}

#[test]
fn test_size_builder() {
fn test_builder() {
let builder = Multiboot2HeaderBuilder::new(HeaderTagISA::I386);
// Multiboot2 basic header + end tag
let mut expected_len = 16 + 8;
Expand Down Expand Up @@ -274,14 +274,28 @@ mod tests {
4096,
RelocatableHeaderTagPreference::None,
));
expected_len += 0x18;
assert_eq!(builder.expected_len(), expected_len);

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

let mb2_hdr_data = builder.build();
let mb2_hdr = mb2_hdr_data.as_ptr() as usize;
let mb2_hdr = unsafe { Multiboot2Header::from_addr(mb2_hdr) };
let mb2_hdr = unsafe { Multiboot2Header::from_addr(mb2_hdr) }
.expect("the generated header to be loadable");
println!("{:#?}", mb2_hdr);
assert_eq!(
mb2_hdr.relocatable_tag().unwrap().flags(),
HeaderTagFlag::Required
);
assert_eq!(mb2_hdr.relocatable_tag().unwrap().min_addr(), 0x1337);
assert_eq!(mb2_hdr.relocatable_tag().unwrap().max_addr(), 0xdeadbeef);
assert_eq!(mb2_hdr.relocatable_tag().unwrap().align(), 4096);
assert_eq!(
mb2_hdr.relocatable_tag().unwrap().preference(),
RelocatableHeaderTagPreference::None
);

/* you can write the binary to a file and a tool such as crate "bootinfo"
will be able to fully parse the MB2 header
Expand Down
2 changes: 1 addition & 1 deletion multiboot2-header/src/relocatable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ use core::mem::size_of;
/// but not lower than min addr and ‘2’ means load image at highest possible
/// address but not higher than max addr.
#[repr(u32)]
#[derive(Copy, Clone, Debug)]
#[derive(Copy, Clone, Debug, PartialEq)]
pub enum RelocatableHeaderTagPreference {
/// Let boot loader decide.
None = 0,
Expand Down
5 changes: 4 additions & 1 deletion multiboot2/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,10 @@ repository = "https://github.com/rust-osdev/multiboot2"
documentation = "https://docs.rs/multiboot2"

[features]
default = []
# by default, builder is included
default = ["builder"]
std = []
builder = ["std"]
# Nightly-only features that will eventually be stabilized.
unstable = []

Expand Down
43 changes: 37 additions & 6 deletions multiboot2/src/boot_loader_name.rs
Original file line number Diff line number Diff line change
@@ -1,8 +1,16 @@
use crate::TagTrait;
use crate::{Tag, TagTypeId};
use crate::{Tag, TagTrait, TagType, TagTypeId};
use core::fmt::{Debug, Formatter};
use core::mem::size_of;
use core::str::Utf8Error;

#[cfg(feature = "builder")]
use {
crate::builder::boxed_dst_tag, crate::builder::traits::StructAsBytes, alloc::boxed::Box,
alloc::vec::Vec,
};

const METADATA_SIZE: usize = size_of::<TagTypeId>() + size_of::<u32>();

/// The bootloader name tag.
#[derive(ptr_meta::Pointee)]
#[repr(C, packed)] // only repr(C) would add unwanted padding before first_section
Expand All @@ -14,6 +22,13 @@ pub struct BootLoaderNameTag {
}

impl BootLoaderNameTag {
#[cfg(feature = "builder")]
pub fn new(name: &str) -> Box<Self> {
let mut bytes: Vec<_> = name.bytes().collect();
bytes.push(0);
boxed_dst_tag(TagType::BootLoaderName, &bytes)
}

/// Reads the name of the bootloader that is booting the kernel as Rust
/// string slice without the null-byte.
///
Expand Down Expand Up @@ -46,10 +61,15 @@ impl Debug for BootLoaderNameTag {

impl TagTrait for BootLoaderNameTag {
fn dst_size(base_tag: &Tag) -> usize {
// The size of the sized portion of the bootloader name tag.
let tag_base_size = 8;
assert!(base_tag.size >= 8);
base_tag.size as usize - tag_base_size
assert!(base_tag.size as usize >= METADATA_SIZE);
base_tag.size as usize - METADATA_SIZE
}
}

#[cfg(feature = "builder")]
impl StructAsBytes for BootLoaderNameTag {
fn byte_size(&self) -> usize {
self.size.try_into().unwrap()
}
}

Expand Down Expand Up @@ -85,4 +105,15 @@ mod tests {
assert_eq!({ tag.typ }, TagType::BootLoaderName);
assert_eq!(tag.name().expect("must be valid UTF-8"), MSG);
}

/// Test to generate a tag from a given string.
#[test]
#[cfg(feature = "builder")]
fn test_build_str() {
use crate::builder::traits::StructAsBytes;

let tag = BootLoaderNameTag::new(MSG);
let bytes = tag.struct_as_bytes();
assert_eq!(bytes, get_bytes());
}
}
Loading