Skip to content

Commit

Permalink
multiboot2-header: improve code style
Browse files Browse the repository at this point in the history
  • Loading branch information
phip1611 committed Aug 14, 2024
1 parent 089431b commit 031856d
Show file tree
Hide file tree
Showing 18 changed files with 414 additions and 191 deletions.
3 changes: 2 additions & 1 deletion multiboot2-header/Changelog.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,9 @@

## Unreleased

- **Breaking** All functions that returns something useful are now `#[must_use]`
- updated dependencies
- MSRV is 1.75
- documentation enhancements

## 0.4.0 (2024-05-01)

Expand Down
41 changes: 30 additions & 11 deletions multiboot2-header/src/address.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{HeaderTagFlag, HeaderTagType};
use crate::{HeaderTagFlag, HeaderTagHeader, HeaderTagType};
use core::mem::size_of;

/// This information does not need to be provided if the kernel image is in ELF
Expand All @@ -8,9 +8,7 @@ use core::mem::size_of;
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(C)]
pub struct AddressHeaderTag {
typ: HeaderTagType,
flags: HeaderTagFlag,
size: u32,
header: HeaderTagHeader,
/// Contains the address corresponding to the beginning of the Multiboot2 header — the physical memory location at which the magic value is supposed to be loaded. This field serves to synchronize the mapping between OS image offsets and physical memory addresses.
header_addr: u32,
/// Contains the physical address of the beginning of the text segment. The offset in the OS image file at which to start loading is defined by the offset at which the header was found, minus (header_addr - load_addr). load_addr must be less than or equal to header_addr.
Expand All @@ -24,42 +22,63 @@ pub struct AddressHeaderTag {
}

impl AddressHeaderTag {
/// Constructs a new tag.
#[must_use]
pub const fn new(
flags: HeaderTagFlag,
header_addr: u32,
load_addr: u32,
load_end_addr: u32,
bss_end_addr: u32,
) -> Self {
AddressHeaderTag {
typ: HeaderTagType::Address,
flags,
size: size_of::<Self>() as u32,
let header = HeaderTagHeader::new(HeaderTagType::Address, flags, size_of::<Self>() as u32);
Self {
header,
header_addr,
load_addr,
load_end_addr,
bss_end_addr,
}
}

/// Returns the [`HeaderTagType`].
#[must_use]
pub const fn typ(&self) -> HeaderTagType {
self.typ
self.header.typ()
}

/// Returns the [`HeaderTagFlag`]s.
#[must_use]
pub const fn flags(&self) -> HeaderTagFlag {
self.flags
self.header.flags()
}

/// Returns the size.
#[must_use]
pub const fn size(&self) -> u32 {
self.size
self.header.size()
}

/// Returns the header address.
#[must_use]
pub const fn header_addr(&self) -> u32 {
self.header_addr
}

/// Returns the load begin address.
#[must_use]
pub const fn load_addr(&self) -> u32 {
self.load_addr
}

/// Returns the load end address.
#[must_use]
pub const fn load_end_addr(&self) -> u32 {
self.load_end_addr
}

/// Returns the bss end address.
#[must_use]
pub const fn bss_end_addr(&self) -> u32 {
self.bss_end_addr
}
Expand Down
40 changes: 37 additions & 3 deletions multiboot2-header/src/builder/header.rs
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ pub struct HeaderBuilder {
}

impl HeaderBuilder {
/// Creates a new builder.
#[must_use]
pub const fn new(arch: HeaderTagISA) -> Self {
Self {
arch,
Expand All @@ -98,6 +100,7 @@ impl HeaderBuilder {

/// Returns the expected length of the Multiboot2 header, when the
/// [`Self::build`]-method gets called.
#[must_use]
pub fn expected_len(&self) -> usize {
let base_len = size_of::<Multiboot2BasicHeader>();
// size_or_up_aligned not required, because basic header length is 16 and the
Expand Down Expand Up @@ -159,7 +162,8 @@ impl HeaderBuilder {
}

/// Constructs the bytes for a valid Multiboot2 header with the given properties.
pub fn build(mut self) -> HeaderBytes {
#[must_use]
pub fn build(self) -> HeaderBytes {
const ALIGN: usize = 8;

// PHASE 1/2: Prepare Vector
Expand Down Expand Up @@ -205,7 +209,7 @@ impl HeaderBuilder {
}

/// Helper method that adds all the tags to the given vector.
fn build_add_tags(&mut self, bytes: &mut Vec<u8>) {
fn build_add_tags(&self, bytes: &mut Vec<u8>) {
Self::build_add_bytes(
bytes,
// important that we write the correct expected length into the header!
Expand Down Expand Up @@ -247,46 +251,76 @@ impl HeaderBuilder {
}

// clippy thinks this can be a const fn but the compiler denies it
#[allow(clippy::missing_const_for_fn)]
// #[allow(clippy::missing_const_for_fn)]
/// Adds information requests from the
/// [`InformationRequestHeaderTagBuilder`] to the builder.
#[must_use]
pub fn information_request_tag(
mut self,
information_request_tag: InformationRequestHeaderTagBuilder,
) -> Self {
self.information_request_tag = Some(information_request_tag);
self
}

/// Adds a [`AddressHeaderTag`] to the builder.
#[must_use]
pub const fn address_tag(mut self, address_tag: AddressHeaderTag) -> Self {
self.address_tag = Some(address_tag);
self
}

/// Adds a [`EntryAddressHeaderTag`] to the builder.
#[must_use]
pub const fn entry_tag(mut self, entry_tag: EntryAddressHeaderTag) -> Self {
self.entry_tag = Some(entry_tag);
self
}

/// Adds a [`ConsoleHeaderTag`] to the builder.
#[must_use]
pub const fn console_tag(mut self, console_tag: ConsoleHeaderTag) -> Self {
self.console_tag = Some(console_tag);
self
}

/// Adds a [`FramebufferHeaderTag`] to the builder.
#[must_use]
pub const fn framebuffer_tag(mut self, framebuffer_tag: FramebufferHeaderTag) -> Self {
self.framebuffer_tag = Some(framebuffer_tag);
self
}

/// Adds a [`ModuleAlignHeaderTag`] to the builder.
#[must_use]
pub const fn module_align_tag(mut self, module_align_tag: ModuleAlignHeaderTag) -> Self {
self.module_align_tag = Some(module_align_tag);
self
}

/// Adds a [`EfiBootServiceHeaderTag`] to the builder.
#[must_use]
pub const fn efi_bs_tag(mut self, efi_bs_tag: EfiBootServiceHeaderTag) -> Self {
self.efi_bs_tag = Some(efi_bs_tag);
self
}

/// Adds a [`EntryEfi32HeaderTag`] to the builder.
#[must_use]
pub const fn efi_32_tag(mut self, efi_32_tag: EntryEfi32HeaderTag) -> Self {
self.efi_32_tag = Some(efi_32_tag);
self
}

/// Adds a [`EntryEfi64HeaderTag`] to the builder.
#[must_use]
pub const fn efi_64_tag(mut self, efi_64_tag: EntryEfi64HeaderTag) -> Self {
self.efi_64_tag = Some(efi_64_tag);
self
}

/// Adds a [`RelocatableHeaderTag`] to the builder.
#[must_use]
pub const fn relocatable_tag(mut self, relocatable_tag: RelocatableHeaderTag) -> Self {
self.relocatable_tag = Some(relocatable_tag);
self
Expand Down
4 changes: 4 additions & 0 deletions multiboot2-header/src/builder/information_request.rs
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ pub struct InformationRequestHeaderTagBuilder {
#[cfg(feature = "builder")]
impl InformationRequestHeaderTagBuilder {
/// New builder.
#[must_use]
pub const fn new(flag: HeaderTagFlag) -> Self {
Self {
irs: BTreeSet::new(),
Expand All @@ -31,19 +32,22 @@ impl InformationRequestHeaderTagBuilder {

/// Returns the expected length of the information request tag,
/// when the `build`-method gets called.
#[must_use]
pub fn expected_len(&self) -> usize {
let basic_header_size = size_of::<InformationRequestHeaderTag<0>>();
let req_tags_size = self.irs.len() * size_of::<MbiTagTypeId>();
basic_header_size + req_tags_size
}

/// Adds an [`MbiTagType`] to the information request.
#[must_use]
pub fn add_ir(mut self, tag: MbiTagType) -> Self {
self.irs.insert(tag);
self
}

/// Adds multiple [`MbiTagType`] to the information request.
#[must_use]
pub fn add_irs(mut self, tags: &[MbiTagType]) -> Self {
self.irs.extend(tags);
self
Expand Down
2 changes: 1 addition & 1 deletion multiboot2-header/src/builder/traits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ use core::mem::size_of;
/// Trait for all tags that helps to create a byte array from the tag.
/// Useful in builders to construct a byte vector that
/// represents the Multiboot2 header with all its tags.
pub(crate) trait StructAsBytes: Sized {
pub trait StructAsBytes: Sized {
/// Returns the size in bytes of the struct, as known during compile
/// time. This doesn't use read the "size" field of tags.
fn byte_size(&self) -> usize {
Expand Down
33 changes: 22 additions & 11 deletions multiboot2-header/src/console.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use crate::{HeaderTagFlag, HeaderTagType};
use crate::{HeaderTagFlag, HeaderTagHeader, HeaderTagType};
use core::mem::size_of;

/// Possible flags for [`ConsoleHeaderTag`].
Expand All @@ -16,31 +16,42 @@ pub enum ConsoleHeaderTagFlags {
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(C)]
pub struct ConsoleHeaderTag {
typ: HeaderTagType,
flags: HeaderTagFlag,
size: u32,
header: HeaderTagHeader,
console_flags: ConsoleHeaderTagFlags,
}

impl ConsoleHeaderTag {
/// Constructs a new tag.
#[must_use]
pub const fn new(flags: HeaderTagFlag, console_flags: ConsoleHeaderTagFlags) -> Self {
ConsoleHeaderTag {
typ: HeaderTagType::ConsoleFlags,
flags,
size: size_of::<Self>() as u32,
let header =
HeaderTagHeader::new(HeaderTagType::ConsoleFlags, flags, size_of::<Self>() as u32);
Self {
header,
console_flags,
}
}

/// Returns the [`HeaderTagType`].
#[must_use]
pub const fn typ(&self) -> HeaderTagType {
self.typ
self.header.typ()
}

/// Returns the [`HeaderTagFlag`]s.
#[must_use]
pub const fn flags(&self) -> HeaderTagFlag {
self.flags
self.header.flags()
}

/// Returns the size.
#[must_use]
pub const fn size(&self) -> u32 {
self.size
self.header.size()
}

/// Returns the [`ConsoleHeaderTagFlags`].
#[must_use]
pub const fn console_flags(&self) -> ConsoleHeaderTagFlags {
self.console_flags
}
Expand Down
35 changes: 21 additions & 14 deletions multiboot2-header/src/end.rs
Original file line number Diff line number Diff line change
@@ -1,15 +1,11 @@
use crate::{HeaderTagFlag, HeaderTagType};
use crate::{HeaderTagFlag, HeaderTagHeader, HeaderTagType};
use core::mem::size_of;

/// Terminates a list of optional tags in a Multiboot2 header.
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
#[repr(C)]
pub struct EndHeaderTag {
// u16 value
typ: HeaderTagType,
// u16 value
flags: HeaderTagFlag,
size: u32,
header: HeaderTagHeader,
}

impl Default for EndHeaderTag {
Expand All @@ -19,22 +15,33 @@ impl Default for EndHeaderTag {
}

impl EndHeaderTag {
/// Constructs a new tag.
#[must_use]
pub const fn new() -> Self {
EndHeaderTag {
typ: HeaderTagType::End,
flags: HeaderTagFlag::Required,
size: size_of::<Self>() as u32,
}
let header = HeaderTagHeader::new(
HeaderTagType::EntryAddress,
HeaderTagFlag::Required,
size_of::<Self>() as u32,
);
Self { header }
}

/// Returns the [`HeaderTagType`].
#[must_use]
pub const fn typ(&self) -> HeaderTagType {
self.typ
self.header.typ()
}

/// Returns the [`HeaderTagFlag`]s.
#[must_use]
pub const fn flags(&self) -> HeaderTagFlag {
self.flags
self.header.flags()
}

/// Returns the size.
#[must_use]
pub const fn size(&self) -> u32 {
self.size
self.header.size()
}
}

Expand Down
Loading

0 comments on commit 031856d

Please sign in to comment.