瀏覽代碼

multiboot2: Add basic information builder

Niklas Sombert 2 年之前
父節點
當前提交
152c985591

+ 4 - 1
multiboot2/Cargo.toml

@@ -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 = []
 

+ 16 - 0
multiboot2/src/builder/information.rs

@@ -0,0 +1,16 @@
+//! Exports item [`Multiboot2InformationBuilder`].
+use crate::{builder::traits::StructAsBytes, CommandLineTag};
+
+use alloc::boxed::Box;
+
+/// Builder to construct a valid Multiboot2 information dynamically at runtime.
+/// The tags will appear in the order of their corresponding enumeration,
+/// except for the END tag.
+#[derive(Debug)]
+pub struct Multiboot2InformationBuilder {}
+
+impl Multiboot2InformationBuilder {
+    pub const fn new() -> Self {
+        Self {}
+    }
+}

+ 6 - 0
multiboot2/src/builder/mod.rs

@@ -0,0 +1,6 @@
+//! Module for the builder-feature.
+
+mod information;
+pub(self) mod traits;
+
+pub use information::Multiboot2InformationBuilder;

+ 30 - 0
multiboot2/src/builder/traits.rs

@@ -0,0 +1,30 @@
+//! Module for the helper trait [`StructAsBytes`].
+
+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 information with all its tags.
+pub(crate) 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 {
+        size_of::<Self>()
+    }
+
+    /// Returns a byte pointer to the begin of the struct.
+    fn as_ptr(&self) -> *const u8 {
+        self as *const Self as *const u8
+    }
+
+    /// Returns the structure as a vector of its bytes.
+    /// The length is determined by [`Self::byte_size`].
+    fn struct_as_bytes(&self) -> alloc::vec::Vec<u8> {
+        let ptr = self.as_ptr();
+        let mut vec = alloc::vec::Vec::with_capacity(self.byte_size());
+        for i in 0..self.byte_size() {
+            vec.push(unsafe { *ptr.add(i) })
+        }
+        vec
+    }
+}

+ 6 - 0
multiboot2/src/lib.rs

@@ -32,6 +32,9 @@
 //! ## MSRV
 //! The MSRV is 1.56.1 stable.
 
+#[cfg(feature = "builder")]
+extern crate alloc;
+
 // this crate can use std in tests only
 #[cfg_attr(test, macro_use)]
 #[cfg(test)]
@@ -81,6 +84,9 @@ mod smbios;
 mod tag_type;
 mod vbe_info;
 
+#[cfg(feature = "builder")]
+pub mod builder;
+
 /// Magic number that a multiboot2-compliant boot loader will store in `eax` register
 /// right before handoff to the payload (the kernel). This value can be used to check,
 /// that the kernel was indeed booted via multiboot2.