فهرست منبع

Merge pull request #141 from rust-osdev/dev

treewide: code improvements and other stuff
Philipp Schuster 1 سال پیش
والد
کامیت
4908653d70

+ 6 - 6
.github/workflows/_build-rust.yml

@@ -80,27 +80,27 @@ jobs:
           key: ${{ runner.os }}-rust-${{ inputs.rust-version }}-cargo-${{ hashFiles('**/Cargo.toml', '**/Cargo.lock') }}
           key: ${{ runner.os }}-rust-${{ inputs.rust-version }}-cargo-${{ hashFiles('**/Cargo.toml', '**/Cargo.lock') }}
       - run: cargo version
       - run: cargo version
       - name: Build (library)
       - name: Build (library)
-        run: cargo build --target ${{ inputs.rust-target }} --features ${{ inputs.features }}
+        run: cargo build --target ${{ inputs.rust-target }} --features ${{ inputs.features }} --no-default-features
       - name: Build (all targets)
       - name: Build (all targets)
-        run: cargo build --all-targets --features ${{ inputs.features }}
+        run: cargo build --all-targets --features ${{ inputs.features }} --no-default-features
       - name: Code Formatting
       - name: Code Formatting
         if: inputs.do-style-check
         if: inputs.do-style-check
         run: cargo fmt --all -- --check
         run: cargo fmt --all -- --check
       - name: Code Style and Doc Style
       - name: Code Style and Doc Style
         if: inputs.do-style-check
         if: inputs.do-style-check
         run: |
         run: |
-          cargo doc --document-private-items --features ${{ inputs.features }}
-          cargo clippy --all-targets --features ${{ inputs.features }}
+          cargo doc --document-private-items --features ${{ inputs.features }} --no-default-features
+          cargo clippy --all-targets --features ${{ inputs.features }} --no-default-features
       - name: Unit Test (UNIX)
       - name: Unit Test (UNIX)
         if: inputs.do-test && runner.os != 'Windows'
         if: inputs.do-test && runner.os != 'Windows'
         run: |
         run: |
           curl -LsSf https://get.nexte.st/latest/linux | tar zxf -
           curl -LsSf https://get.nexte.st/latest/linux | tar zxf -
           chmod u+x cargo-nextest
           chmod u+x cargo-nextest
-          ./cargo-nextest nextest run --features ${{ inputs.features }}
+          ./cargo-nextest nextest run --features ${{ inputs.features }} --no-default-features
       - name: Unit Test (Windows)
       - name: Unit Test (Windows)
         if: inputs.do-test && runner.os == 'Windows'
         if: inputs.do-test && runner.os == 'Windows'
         run: |
         run: |
           Invoke-WebRequest https://get.nexte.st/latest/windows -OutFile cargo-nextest.zip
           Invoke-WebRequest https://get.nexte.st/latest/windows -OutFile cargo-nextest.zip
           Expand-Archive .\cargo-nextest.zip
           Expand-Archive .\cargo-nextest.zip
           cp .\cargo-nextest/cargo-nextest.exe .
           cp .\cargo-nextest/cargo-nextest.exe .
-          .\cargo-nextest.exe nextest run --features ${{ inputs.features }}
+          .\cargo-nextest.exe nextest run --features ${{ inputs.features }} --no-default-features

+ 25 - 8
.github/workflows/rust.yml

@@ -20,8 +20,9 @@ jobs:
     name: build (msrv)
     name: build (msrv)
     uses: ./.github/workflows/_build-rust.yml
     uses: ./.github/workflows/_build-rust.yml
     with:
     with:
-      rust-version: 1.56.1
+      rust-version: 1.68.0 # MSRV
       do-style-check: false
       do-style-check: false
+      features: builder
 
 
   build_stable:
   build_stable:
     name: build (stable)
     name: build (stable)
@@ -29,6 +30,7 @@ jobs:
     with:
     with:
       rust-version: stable
       rust-version: stable
       do-style-check: false
       do-style-check: false
+      features: builder
 
 
   build_nightly:
   build_nightly:
     name: build (nightly)
     name: build (nightly)
@@ -36,7 +38,7 @@ jobs:
     with:
     with:
       rust-version: nightly
       rust-version: nightly
       do-style-check: false
       do-style-check: false
-      features: unstable
+      features: builder,unstable
 
 
   ### no-std Build   #########################
   ### no-std Build   #########################
   build_nostd_msrv:
   build_nostd_msrv:
@@ -44,9 +46,10 @@ jobs:
     needs: build_msrv
     needs: build_msrv
     uses: ./.github/workflows/_build-rust.yml
     uses: ./.github/workflows/_build-rust.yml
     with:
     with:
-      rust-version: 1.56.1
+      rust-version: 1.68.0 # MSRV
       do-style-check: false
       do-style-check: false
       rust-target: thumbv7em-none-eabihf
       rust-target: thumbv7em-none-eabihf
+      features: builder
 
 
   build_nostd_stable:
   build_nostd_stable:
     name: build no_std (stable)
     name: build no_std (stable)
@@ -56,6 +59,17 @@ jobs:
       rust-version: stable
       rust-version: stable
       do-style-check: false
       do-style-check: false
       rust-target: thumbv7em-none-eabihf
       rust-target: thumbv7em-none-eabihf
+      features: builder
+
+  # Also tests the build one time without the "builder" feature.
+  build_nostd_stable_no_builder:
+    name: build no_std (stable) [w/o builder]
+    needs: build_stable
+    uses: ./.github/workflows/_build-rust.yml
+    with:
+      rust-version: stable
+      do-style-check: false
+      rust-target: thumbv7em-none-eabihf
 
 
   # We perform one single run also in Windows. This should be sufficient to
   # We perform one single run also in Windows. This should be sufficient to
   # check that devs can also use this on Windows.
   # check that devs can also use this on Windows.
@@ -65,11 +79,12 @@ jobs:
     with:
     with:
       runs-on: windows-latest
       runs-on: windows-latest
       # Quirk for the Windows powershell and its handling of empty arguments.
       # Quirk for the Windows powershell and its handling of empty arguments.
-      features: >
-        '""'
+      # features: >
+      #   '""'
       rust-version: stable
       rust-version: stable
       do-style-check: false
       do-style-check: false
       rust-target: thumbv7em-none-eabihf
       rust-target: thumbv7em-none-eabihf
+      features: builder
 
 
   build_nostd_nightly:
   build_nostd_nightly:
     name: build no_std (nightly)
     name: build no_std (nightly)
@@ -79,7 +94,7 @@ jobs:
       rust-version: nightly
       rust-version: nightly
       do-style-check: false
       do-style-check: false
       rust-target: thumbv7em-none-eabihf
       rust-target: thumbv7em-none-eabihf
-      features: unstable
+      features: builder,unstable
 
 
   ### Style Checks + Doc #####################
   ### Style Checks + Doc #####################
   style_msrv:
   style_msrv:
@@ -87,9 +102,10 @@ jobs:
     needs: build_msrv
     needs: build_msrv
     uses: ./.github/workflows/_build-rust.yml
     uses: ./.github/workflows/_build-rust.yml
     with:
     with:
-      rust-version: 1.56.1
+      rust-version: 1.68.0 # MSRV
       do-style-check: true
       do-style-check: true
       do-test: false
       do-test: false
+      features: builder
 
 
   style_stable:
   style_stable:
     name: style (stable)
     name: style (stable)
@@ -99,6 +115,7 @@ jobs:
       rust-version: stable
       rust-version: stable
       do-style-check: true
       do-style-check: true
       do-test: false
       do-test: false
+      features: builder
 
 
   style_nightly:
   style_nightly:
     name: style (nightly)
     name: style (nightly)
@@ -108,4 +125,4 @@ jobs:
       rust-version: nightly
       rust-version: nightly
       do-style-check: true
       do-style-check: true
       do-test: false
       do-test: false
-      features: unstable
+      features: builder,unstable

+ 26 - 2
Cargo.lock

@@ -8,6 +8,12 @@ version = "1.3.2"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a"
 
 
+[[package]]
+name = "bitflags"
+version = "2.3.2"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "6dbe3c979c178231552ecba20214a8272df4e09f232a87aef4320cf06539aded"
+
 [[package]]
 [[package]]
 name = "cfg-if"
 name = "cfg-if"
 version = "1.0.0"
 version = "1.0.0"
@@ -40,17 +46,18 @@ version = "0.13.3"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 source = "registry+https://github.com/rust-lang/crates.io-index"
 checksum = "d408e10189a4b0e1d488a24a19c5c8c9786f011b30c824c8ab02d3ebf5f62ca2"
 checksum = "d408e10189a4b0e1d488a24a19c5c8c9786f011b30c824c8ab02d3ebf5f62ca2"
 dependencies = [
 dependencies = [
- "bitflags",
+ "bitflags 1.3.2",
 ]
 ]
 
 
 [[package]]
 [[package]]
 name = "multiboot2"
 name = "multiboot2"
 version = "0.15.1"
 version = "0.15.1"
 dependencies = [
 dependencies = [
- "bitflags",
+ "bitflags 2.3.2",
  "derive_more",
  "derive_more",
  "log",
  "log",
  "ptr_meta",
  "ptr_meta",
+ "uefi-raw",
 ]
 ]
 
 
 [[package]]
 [[package]]
@@ -109,6 +116,23 @@ dependencies = [
  "unicode-ident",
  "unicode-ident",
 ]
 ]
 
 
+[[package]]
+name = "uefi-raw"
+version = "0.2.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "d73e08d8e944b7c7e90a7c8a53213bdd71ceb7b414ee664f522c1cc579888c25"
+dependencies = [
+ "bitflags 2.3.2",
+ "ptr_meta",
+ "uguid",
+]
+
+[[package]]
+name = "uguid"
+version = "2.0.0"
+source = "registry+https://github.com/rust-lang/crates.io-index"
+checksum = "594cc87e268a7b43d625d46c63cf1605d0e61bf66e4b1cd58c058ec0191e1f81"
+
 [[package]]
 [[package]]
 name = "unicode-ident"
 name = "unicode-ident"
 version = "1.0.8"
 version = "1.0.8"

+ 9 - 3
multiboot2-header/Cargo.toml

@@ -26,12 +26,18 @@ readme = "README.md"
 homepage = "https://github.com/rust-osdev/multiboot2-header"
 homepage = "https://github.com/rust-osdev/multiboot2-header"
 repository = "https://github.com/rust-osdev/multiboot2"
 repository = "https://github.com/rust-osdev/multiboot2"
 documentation = "https://docs.rs/multiboot2-header"
 documentation = "https://docs.rs/multiboot2-header"
+rust-version = "1.60"
+
+[[example]]
+name = "minimal"
+required-features = ["builder"]
 
 
 [features]
 [features]
-# by default, builder is included
 default = ["builder"]
 default = ["builder"]
-std = []
-builder = ["std"]
+alloc = []
+builder = ["alloc"]
+# Nightly-only features, which will eventually be stabilized.
+unstable = []
 
 
 [dependencies]
 [dependencies]
 # used for MBI tags
 # used for MBI tags

+ 4 - 1
multiboot2-header/Changelog.md

@@ -1,7 +1,10 @@
 # CHANGELOG for crate `multiboot2-header`
 # CHANGELOG for crate `multiboot2-header`
 
 
 ## Unreleased
 ## Unreleased
-- MSRV is 1.56.1
+- MSRV is 1.68.0
+- renamed the `std` feature to `alloc`
+- added the optional `unstable` feature (requires nightly)
+  - implement `core::error::Error` for `LoadError`
 
 
 ## v0.2.0 (2022-05-03)
 ## v0.2.0 (2022-05-03)
 - **BREAKING** renamed `EntryHeaderTag` to `EntryAddressHeaderTag`
 - **BREAKING** renamed `EntryHeaderTag` to `EntryAddressHeaderTag`

+ 5 - 4
multiboot2-header/README.md

@@ -15,10 +15,11 @@ What this library is good for:
 What this library is not optimal for:
 What this library is not optimal for:
 - compiling a Multiboot2 header statically into an object file using only Rust code
 - compiling a Multiboot2 header statically into an object file using only Rust code
 
 
-## Features and Usage in `no_std`
-This library is always `no_std`. However, the `builder`-feature requires the `alloc`-crate
-to be available. You need the `builder` only if you want to construct new headers. For parsing,
-this is not relevant.
+## Features and `no_std` Compatibility
+This library is always `no_std`. However, the default `builder`-feature requires
+the `alloc`-crate to be available. You need the `builder` only if you want to
+construct new headers at run time. For parsing, this is not relevant, and you
+can deactivate the default feature.
 
 
 ```toml
 ```toml
 # without `builder`-feature (and without `alloc`-crate)
 # without `builder`-feature (and without `alloc`-crate)

+ 4 - 6
multiboot2-header/src/builder/traits.rs

@@ -5,6 +5,7 @@ use crate::{
     EntryAddressHeaderTag, EntryEfi32HeaderTag, EntryEfi64HeaderTag, FramebufferHeaderTag,
     EntryAddressHeaderTag, EntryEfi32HeaderTag, EntryEfi64HeaderTag, FramebufferHeaderTag,
     InformationRequestHeaderTag, ModuleAlignHeaderTag, Multiboot2BasicHeader, RelocatableHeaderTag,
     InformationRequestHeaderTag, ModuleAlignHeaderTag, Multiboot2BasicHeader, RelocatableHeaderTag,
 };
 };
+use alloc::vec::Vec;
 use core::mem::size_of;
 use core::mem::size_of;
 
 
 /// Trait for all tags that helps to create a byte array from the tag.
 /// Trait for all tags that helps to create a byte array from the tag.
@@ -24,13 +25,10 @@ pub(crate) trait StructAsBytes: Sized {
 
 
     /// Returns the structure as a vector of its bytes.
     /// Returns the structure as a vector of its bytes.
     /// The length is determined by [`Self::byte_size`].
     /// The length is determined by [`Self::byte_size`].
-    fn struct_as_bytes(&self) -> alloc::vec::Vec<u8> {
+    fn struct_as_bytes(&self) -> Vec<u8> {
         let ptr = self.as_ptr();
         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
+        let bytes = unsafe { core::slice::from_raw_parts(ptr, self.byte_size()) };
+        Vec::from(bytes)
     }
     }
 }
 }
 
 

+ 10 - 1
multiboot2-header/src/header.rs

@@ -5,7 +5,7 @@ use crate::{
     RelocatableHeaderTag,
     RelocatableHeaderTag,
 };
 };
 use core::convert::TryInto;
 use core::convert::TryInto;
-use core::fmt::{Debug, Formatter};
+use core::fmt::{Debug, Display, Formatter};
 use core::mem::size_of;
 use core::mem::size_of;
 
 
 /// Magic value for a [`Multiboot2Header`], as defined in spec.
 /// Magic value for a [`Multiboot2Header`], as defined in spec.
@@ -212,6 +212,15 @@ pub enum LoadError {
     TooSmall,
     TooSmall,
 }
 }
 
 
+impl Display for LoadError {
+    fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
+        write!(f, "{:?}", self)
+    }
+}
+
+#[cfg(feature = "unstable")]
+impl core::error::Error for LoadError {}
+
 /// **Use this only if you know what you do. You probably want to use
 /// **Use this only if you know what you do. You probably want to use
 /// [`Multiboot2Header`] instead.**
 /// [`Multiboot2Header`] instead.**
 ///
 ///

+ 2 - 2
multiboot2-header/src/lib.rs

@@ -34,6 +34,7 @@
 //! The MSRV is 1.56.1 stable.
 //! The MSRV is 1.56.1 stable.
 
 
 #![no_std]
 #![no_std]
+#![cfg_attr(feature = "unstable", feature(error_in_core))]
 #![deny(rustdoc::all)]
 #![deny(rustdoc::all)]
 #![deny(clippy::all)]
 #![deny(clippy::all)]
 #![deny(clippy::missing_const_for_fn)]
 #![deny(clippy::missing_const_for_fn)]
@@ -77,6 +78,5 @@ pub use self::relocatable::*;
 pub use self::tags::*;
 pub use self::tags::*;
 pub use self::uefi_bs::*;
 pub use self::uefi_bs::*;
 
 
-/// Re-export of [`multiboot2::TagType`] from `multiboot2`-crate as `MbiTagType`, i.e. tags that
-/// describe the entries in the Multiboot2 Information Structure (MBI).
+/// Re-export of [`multiboot2::TagType`] from `multiboot2`-crate.
 pub use multiboot2::TagType as MbiTagType;
 pub use multiboot2::TagType as MbiTagType;

+ 7 - 5
multiboot2/Cargo.toml

@@ -23,6 +23,7 @@ keywords = [
     "Multiboot2",
     "Multiboot2",
     "kernel",
     "kernel",
     "boot",
     "boot",
+    "bootloader",
 ]
 ]
 # without this, sometimes crates.io doesn't show the preview of the README
 # without this, sometimes crates.io doesn't show the preview of the README
 # I expeciended this multiple times in the past
 # I expeciended this multiple times in the past
@@ -30,17 +31,18 @@ readme = "README.md"
 homepage = "https://github.com/rust-osdev/multiboot2"
 homepage = "https://github.com/rust-osdev/multiboot2"
 repository = "https://github.com/rust-osdev/multiboot2"
 repository = "https://github.com/rust-osdev/multiboot2"
 documentation = "https://docs.rs/multiboot2"
 documentation = "https://docs.rs/multiboot2"
+rust-version = "1.60"
 
 
 [features]
 [features]
-# by default, builder is included
 default = ["builder"]
 default = ["builder"]
-std = []
-builder = ["std"]
-# Nightly-only features that will eventually be stabilized.
+alloc = []
+builder = ["alloc"]
+# Nightly-only features, which will eventually be stabilized.
 unstable = []
 unstable = []
 
 
 [dependencies]
 [dependencies]
-bitflags = "1"
+bitflags = "2"
 derive_more = { version = "0.99", default-features = false, features = ["display"] }
 derive_more = { version = "0.99", default-features = false, features = ["display"] }
 log = { version = "0.4", default-features = false }
 log = { version = "0.4", default-features = false }
+uefi-raw = { version = "0.2.0", default-features = false }
 ptr_meta = { version = "0.2.0", default-features = false }
 ptr_meta = { version = "0.2.0", default-features = false }

+ 8 - 0
multiboot2/Changelog.md

@@ -6,6 +6,14 @@
   name tag. However, this might also be relevant for users of custom multiboot2
   name tag. However, this might also be relevant for users of custom multiboot2
   tags that use DSTs as types. See the example provided in the doc of the
   tags that use DSTs as types. See the example provided in the doc of the
   `get_tag` method.
   `get_tag` method.
+- renamed `MULTIBOOT2_BOOTLOADER_MAGIC` to `MAGIC`
+- added a `builder` feature and a `builder` module with a `Multiboot2InformationBuilder`
+  struct
+- `EFIMemoryDesc` was removed and is now an alias of
+  `uefi_raw::table::boot::MemoryDescriptor`
+- `EFIMemoryAreaType` was removed and is now an alias of
+  `uefi_raw::table::boot::MemoryType`
+- MSRV is 1.68.0
 
 
 ## 0.15.1 (2023-03-18)
 ## 0.15.1 (2023-03-18)
 - **BREAKING** `MemoryMapTag::all_memory_areas()` was renamed to `memory_areas`
 - **BREAKING** `MemoryMapTag::all_memory_areas()` was renamed to `memory_areas`

+ 6 - 0
multiboot2/README.md

@@ -10,6 +10,12 @@ used in a Multiboot2-kernel.
 
 
 It follows the Multiboot 2.0 specification at https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html and the ELF 64 specification at http://www.uclibc.org/docs/elf-64-gen.pdf.
 It follows the Multiboot 2.0 specification at https://www.gnu.org/software/grub/manual/multiboot2/multiboot.html and the ELF 64 specification at http://www.uclibc.org/docs/elf-64-gen.pdf.
 
 
+## Features and `no_std` Compatibility
+This library is always `no_std`. However, the default `builder`-feature requires
+the `alloc`-crate to be available. You need the `builder` only if you want to
+construct new boot information structures at run time. For parsing, this is not
+relevant, and you can deactivate the default feature.
+
 ## Background: The Multiboot 2 Information Structure
 ## Background: The Multiboot 2 Information Structure
 The Multiboot information structure looks like this:
 The Multiboot information structure looks like this:
 
 

+ 3 - 3
multiboot2/src/boot_loader_name.rs

@@ -1,12 +1,12 @@
-use crate::{Tag, TagTrait, TagType, TagTypeId};
+use crate::{Tag, TagTrait, TagTypeId};
 use core::fmt::{Debug, Formatter};
 use core::fmt::{Debug, Formatter};
 use core::mem::size_of;
 use core::mem::size_of;
 use core::str::Utf8Error;
 use core::str::Utf8Error;
 
 
 #[cfg(feature = "builder")]
 #[cfg(feature = "builder")]
 use {
 use {
-    crate::builder::boxed_dst_tag, crate::builder::traits::StructAsBytes, alloc::boxed::Box,
-    alloc::vec::Vec,
+    crate::builder::boxed_dst_tag, crate::builder::traits::StructAsBytes, crate::TagType,
+    alloc::boxed::Box, alloc::vec::Vec,
 };
 };
 
 
 const METADATA_SIZE: usize = size_of::<TagTypeId>() + size_of::<u32>();
 const METADATA_SIZE: usize = size_of::<TagTypeId>() + size_of::<u32>();

+ 5 - 6
multiboot2/src/builder/traits.rs

@@ -1,5 +1,7 @@
 //! Module for the helper trait [`StructAsBytes`].
 //! Module for the helper trait [`StructAsBytes`].
 
 
+use alloc::vec::Vec;
+
 /// Trait for all tags that helps to create a byte array from the tag.
 /// Trait for all tags that helps to create a byte array from the tag.
 /// Useful in builders to construct a byte vector that
 /// Useful in builders to construct a byte vector that
 /// represents the Multiboot2 information with all its tags.
 /// represents the Multiboot2 information with all its tags.
@@ -16,12 +18,9 @@ pub(crate) trait StructAsBytes {
 
 
     /// Returns the structure as a vector of its bytes.
     /// Returns the structure as a vector of its bytes.
     /// The length is determined by [`Self::byte_size`].
     /// The length is determined by [`Self::byte_size`].
-    fn struct_as_bytes(&self) -> alloc::vec::Vec<u8> {
+    fn struct_as_bytes(&self) -> Vec<u8> {
         let ptr = self.as_ptr();
         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
+        let bytes = unsafe { core::slice::from_raw_parts(ptr, self.byte_size()) };
+        Vec::from(bytes)
     }
     }
 }
 }

+ 3 - 4
multiboot2/src/command_line.rs

@@ -1,16 +1,15 @@
 //! Module for [CommandLineTag].
 //! Module for [CommandLineTag].
 
 
-use crate::{Tag, TagTrait, TagType, TagTypeId};
+use crate::{Tag, TagTrait, TagTypeId};
 
 
-use core::convert::TryInto;
 use core::fmt::{Debug, Formatter};
 use core::fmt::{Debug, Formatter};
 use core::mem;
 use core::mem;
 use core::str;
 use core::str;
 
 
 #[cfg(feature = "builder")]
 #[cfg(feature = "builder")]
 use {
 use {
-    crate::builder::boxed_dst_tag, crate::builder::traits::StructAsBytes, alloc::boxed::Box,
-    alloc::vec::Vec,
+    crate::builder::boxed_dst_tag, crate::builder::traits::StructAsBytes, crate::TagType,
+    alloc::boxed::Box, alloc::vec::Vec, core::convert::TryInto,
 };
 };
 
 
 pub(crate) const METADATA_SIZE: usize = mem::size_of::<TagTypeId>() + mem::size_of::<u32>();
 pub(crate) const METADATA_SIZE: usize = mem::size_of::<TagTypeId>() + mem::size_of::<u32>();

+ 1 - 1
multiboot2/src/efi.rs

@@ -136,7 +136,7 @@ impl StructAsBytes for EFIImageHandle64 {
     }
     }
 }
 }
 
 
-#[cfg(test)]
+#[cfg(all(test, feature = "builder"))]
 mod tests {
 mod tests {
     use super::{EFIImageHandle32, EFIImageHandle64, EFISdt32, EFISdt64};
     use super::{EFIImageHandle32, EFIImageHandle64, EFISdt32, EFISdt64};
 
 

+ 7 - 2
multiboot2/src/elf_sections.rs

@@ -1,11 +1,14 @@
-use crate::{Tag, TagTrait, TagType, TagTypeId};
+use crate::{Tag, TagTrait, TagTypeId};
 
 
 use core::fmt::{Debug, Formatter};
 use core::fmt::{Debug, Formatter};
 use core::mem::size_of;
 use core::mem::size_of;
 use core::str::Utf8Error;
 use core::str::Utf8Error;
 
 
 #[cfg(feature = "builder")]
 #[cfg(feature = "builder")]
-use {crate::builder::boxed_dst_tag, crate::builder::traits::StructAsBytes, alloc::boxed::Box};
+use {
+    crate::builder::boxed_dst_tag, crate::builder::traits::StructAsBytes, crate::TagType,
+    alloc::boxed::Box,
+};
 
 
 const METADATA_SIZE: usize = size_of::<TagTypeId>() + 4 * size_of::<u32>();
 const METADATA_SIZE: usize = size_of::<TagTypeId>() + 4 * size_of::<u32>();
 
 
@@ -409,6 +412,8 @@ pub enum ElfSectionType {
 
 
 bitflags! {
 bitflags! {
     /// ELF Section bitflags.
     /// ELF Section bitflags.
+    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
+    #[repr(transparent)]
     pub struct ElfSectionFlags: u64 {
     pub struct ElfSectionFlags: u64 {
         /// The section contains data that should be writable during program execution.
         /// The section contains data that should be writable during program execution.
         const WRITABLE = 0x1;
         const WRITABLE = 0x1;

+ 24 - 11
multiboot2/src/framebuffer.rs

@@ -1,4 +1,4 @@
-use crate::{Reader, Tag, TagTrait, TagType, TagTypeId};
+use crate::{Reader, Tag, TagTrait, TagTypeId};
 
 
 use core::fmt::Debug;
 use core::fmt::Debug;
 use core::mem::size_of;
 use core::mem::size_of;
@@ -7,8 +7,8 @@ use derive_more::Display;
 
 
 #[cfg(feature = "builder")]
 #[cfg(feature = "builder")]
 use {
 use {
-    crate::builder::boxed_dst_tag, crate::builder::traits::StructAsBytes, alloc::boxed::Box,
-    alloc::vec::Vec,
+    crate::builder::boxed_dst_tag, crate::builder::traits::StructAsBytes, crate::TagType,
+    alloc::boxed::Box, alloc::vec::Vec,
 };
 };
 
 
 const METADATA_SIZE: usize = size_of::<TagTypeId>()
 const METADATA_SIZE: usize = size_of::<TagTypeId>()
@@ -104,8 +104,9 @@ impl FramebufferTag {
     /// The type of framebuffer, one of: `Indexed`, `RGB` or `Text`.
     /// The type of framebuffer, one of: `Indexed`, `RGB` or `Text`.
     pub fn buffer_type(&self) -> Result<FramebufferType, UnknownFramebufferType> {
     pub fn buffer_type(&self) -> Result<FramebufferType, UnknownFramebufferType> {
         let mut reader = Reader::new(self.buffer.as_ptr());
         let mut reader = Reader::new(self.buffer.as_ptr());
-        match self.type_no {
-            0 => {
+        let typ = FramebufferTypeId::try_from(self.type_no)?;
+        match typ {
+            FramebufferTypeId::Indexed => {
                 let num_colors = reader.read_u32();
                 let num_colors = reader.read_u32();
                 let palette = unsafe {
                 let palette = unsafe {
                     slice::from_raw_parts(
                     slice::from_raw_parts(
@@ -115,7 +116,7 @@ impl FramebufferTag {
                 } as &'static [FramebufferColor];
                 } as &'static [FramebufferColor];
                 Ok(FramebufferType::Indexed { palette })
                 Ok(FramebufferType::Indexed { palette })
             }
             }
-            1 => {
+            FramebufferTypeId::RGB => {
                 let red_pos = reader.read_u8(); // These refer to the bit positions of the LSB of each field
                 let red_pos = reader.read_u8(); // These refer to the bit positions of the LSB of each field
                 let red_mask = reader.read_u8(); // And then the length of the field from LSB to MSB
                 let red_mask = reader.read_u8(); // And then the length of the field from LSB to MSB
                 let green_pos = reader.read_u8();
                 let green_pos = reader.read_u8();
@@ -137,8 +138,7 @@ impl FramebufferTag {
                     },
                     },
                 })
                 })
             }
             }
-            2 => Ok(FramebufferType::Text),
-            no => Err(UnknownFramebufferType(no)),
+            FramebufferTypeId::Text => Ok(FramebufferType::Text),
         }
         }
     }
     }
 }
 }
@@ -187,16 +187,29 @@ impl PartialEq for FramebufferTag {
 }
 }
 
 
 /// Helper struct for [`FramebufferType`].
 /// Helper struct for [`FramebufferType`].
-#[derive(Debug, PartialEq, Eq)]
+#[derive(Copy, Clone, Debug, PartialEq, Eq)]
 #[repr(u8)]
 #[repr(u8)]
 #[allow(clippy::upper_case_acronyms)]
 #[allow(clippy::upper_case_acronyms)]
-pub enum FramebufferTypeId {
+enum FramebufferTypeId {
     Indexed = 0,
     Indexed = 0,
     RGB = 1,
     RGB = 1,
     Text = 2,
     Text = 2,
     // spec says: there may be more variants in the future
     // spec says: there may be more variants in the future
 }
 }
 
 
+impl TryFrom<u8> for FramebufferTypeId {
+    type Error = UnknownFramebufferType;
+
+    fn try_from(value: u8) -> Result<Self, Self::Error> {
+        match value {
+            0 => Ok(Self::Indexed),
+            1 => Ok(Self::RGB),
+            2 => Ok(Self::Text),
+            val => Err(UnknownFramebufferType(val)),
+        }
+    }
+}
+
 /// The type of framebuffer.
 /// The type of framebuffer.
 #[derive(Debug, PartialEq, Eq)]
 #[derive(Debug, PartialEq, Eq)]
 pub enum FramebufferType<'a> {
 pub enum FramebufferType<'a> {
@@ -224,8 +237,8 @@ pub enum FramebufferType<'a> {
     Text,
     Text,
 }
 }
 
 
+#[cfg(feature = "builder")]
 impl<'a> FramebufferType<'a> {
 impl<'a> FramebufferType<'a> {
-    #[cfg(feature = "builder")]
     fn to_bytes(&self) -> Vec<u8> {
     fn to_bytes(&self) -> Vec<u8> {
         let mut v = Vec::new();
         let mut v = Vec::new();
         match self {
         match self {

+ 6 - 6
multiboot2/src/image_load_addr.rs

@@ -1,9 +1,9 @@
-use core::convert::TryInto;
-use core::mem::size_of;
-
+use crate::tag_type::TagTypeId;
 #[cfg(feature = "builder")]
 #[cfg(feature = "builder")]
-use crate::builder::traits::StructAsBytes;
-use crate::tag_type::{TagType, TagTypeId};
+use {
+    crate::builder::traits::StructAsBytes, crate::TagType, core::convert::TryInto,
+    core::mem::size_of,
+};
 
 
 /// If the image has relocatable header tag, this tag contains the image's
 /// If the image has relocatable header tag, this tag contains the image's
 /// base physical address.
 /// base physical address.
@@ -38,7 +38,7 @@ impl StructAsBytes for ImageLoadPhysAddr {
     }
     }
 }
 }
 
 
-#[cfg(test)]
+#[cfg(all(test, feature = "builder"))]
 mod tests {
 mod tests {
     use super::ImageLoadPhysAddr;
     use super::ImageLoadPhysAddr;
 
 

+ 5 - 13
multiboot2/src/lib.rs

@@ -96,7 +96,7 @@ pub mod builder;
 /// Caution: You might need some assembly code (e.g. GAS or NASM) first, which
 /// Caution: You might need some assembly code (e.g. GAS or NASM) first, which
 /// moves `eax` to another register, like `edi`. Otherwise it probably happens,
 /// moves `eax` to another register, like `edi`. Otherwise it probably happens,
 /// that the Rust compiler output changes `eax` before you can access it.
 /// that the Rust compiler output changes `eax` before you can access it.
-pub const MULTIBOOT2_BOOTLOADER_MAGIC: u32 = 0x36d76289;
+pub const MAGIC: u32 = 0x36d76289;
 
 
 /// Load the multiboot boot information struct from an address.
 /// Load the multiboot boot information struct from an address.
 ///
 ///
@@ -206,6 +206,7 @@ struct BootInformationInner {
 }
 }
 
 
 impl BootInformationInner {
 impl BootInformationInner {
+    #[cfg(feature = "builder")]
     fn new(total_size: u32) -> Self {
     fn new(total_size: u32) -> Self {
         Self {
         Self {
             total_size,
             total_size,
@@ -527,14 +528,6 @@ impl Reader {
         self.read_u16() as u32 | (self.read_u16() as u32) << 16
         self.read_u16() as u32 | (self.read_u16() as u32) << 16
     }
     }
 
 
-    pub(crate) fn read_u64(&mut self) -> u64 {
-        self.read_u32() as u64 | (self.read_u32() as u64) << 32
-    }
-
-    pub(crate) fn skip(&mut self, n: usize) {
-        self.off += n;
-    }
-
     pub(crate) fn current_address(&self) -> usize {
     pub(crate) fn current_address(&self) -> usize {
         unsafe { self.ptr.add(self.off) as usize }
         unsafe { self.ptr.add(self.off) as usize }
     }
     }
@@ -1482,7 +1475,6 @@ mod tests {
 
 
     #[test]
     #[test]
     fn efi_memory_map() {
     fn efi_memory_map() {
-        use memory_map::EFIMemoryAreaType;
         #[repr(C, align(8))]
         #[repr(C, align(8))]
         struct Bytes([u8; 72]);
         struct Bytes([u8; 72]);
         // test that the EFI memory map is detected.
         // test that the EFI memory map is detected.
@@ -1515,9 +1507,9 @@ mod tests {
         let efi_memory_map = bi.efi_memory_map_tag().unwrap();
         let efi_memory_map = bi.efi_memory_map_tag().unwrap();
         let mut efi_mmap_iter = efi_memory_map.memory_areas();
         let mut efi_mmap_iter = efi_memory_map.memory_areas();
         let desc = efi_mmap_iter.next().unwrap();
         let desc = efi_mmap_iter.next().unwrap();
-        assert_eq!(desc.physical_address(), 0x100000);
-        assert_eq!(desc.size(), 16384);
-        assert_eq!(desc.typ(), EFIMemoryAreaType::EfiConventionalMemory);
+        assert_eq!(desc.phys_start, 0x100000);
+        assert_eq!(desc.page_count, 4);
+        assert_eq!(desc.ty, EFIMemoryAreaType::CONVENTIONAL);
         // test that the EFI memory map is not detected if the boot services
         // test that the EFI memory map is not detected if the boot services
         // are not exited.
         // are not exited.
         struct Bytes2([u8; 80]);
         struct Bytes2([u8; 80]);

+ 3 - 143
multiboot2/src/memory_map.rs

@@ -1,10 +1,12 @@
 use crate::{Tag, TagTrait, TagType, TagTypeId};
 use crate::{Tag, TagTrait, TagType, TagTypeId};
-
 use core::convert::TryInto;
 use core::convert::TryInto;
 use core::fmt::Debug;
 use core::fmt::Debug;
 use core::marker::PhantomData;
 use core::marker::PhantomData;
 use core::mem;
 use core::mem;
 
 
+pub use uefi_raw::table::boot::MemoryDescriptor as EFIMemoryDesc;
+pub use uefi_raw::table::boot::MemoryType as EFIMemoryAreaType;
+
 #[cfg(feature = "builder")]
 #[cfg(feature = "builder")]
 use {crate::builder::boxed_dst_tag, crate::builder::traits::StructAsBytes, alloc::boxed::Box};
 use {crate::builder::boxed_dst_tag, crate::builder::traits::StructAsBytes, alloc::boxed::Box};
 
 
@@ -296,18 +298,6 @@ impl StructAsBytes for EFIMemoryMapTag {
     }
     }
 }
 }
 
 
-/// EFI Boot Memory Map Descriptor
-#[derive(Debug, Clone)]
-#[repr(C)]
-pub struct EFIMemoryDesc {
-    typ: u32,
-    _padding: u32,
-    phys_addr: u64,
-    virt_addr: u64,
-    num_pages: u64,
-    attr: u64,
-}
-
 #[cfg(feature = "builder")]
 #[cfg(feature = "builder")]
 impl StructAsBytes for EFIMemoryDesc {
 impl StructAsBytes for EFIMemoryDesc {
     fn byte_size(&self) -> usize {
     fn byte_size(&self) -> usize {
@@ -315,136 +305,6 @@ impl StructAsBytes for EFIMemoryDesc {
     }
     }
 }
 }
 
 
-/// An enum of possible reported region types.
-#[derive(Debug, PartialEq, Eq)]
-pub enum EFIMemoryAreaType {
-    /// Unusable.
-    EfiReservedMemoryType,
-    /// Code area of a UEFI application.
-    EfiLoaderCode,
-    /// Data area of a UEFI application.
-    EfiLoaderData,
-    /// Code area of a UEFI Boot Service Driver.
-    EfiBootServicesCode,
-    /// Data area of a UEFI Boot Service Driver.
-    EfiBootServicesData,
-    /// Code area of a UEFI Runtime Driver.
-    ///
-    /// Must be preserved in working and ACPI S1-S3 states.
-    EfiRuntimeServicesCode,
-    /// Data area of a UEFI Runtime Driver.
-    ///
-    /// Must be preserved in working and ACPI S1-S3 states.
-    EfiRuntimeServicesData,
-    /// Available memory.
-    EfiConventionalMemory,
-    /// Memory with errors, treat as unusable.
-    EfiUnusableMemory,
-    /// Memory containing the ACPI tables.
-    ///
-    /// Must be preserved in working and ACPI S1-S3 states.
-    EfiACPIReclaimMemory,
-    /// Memory reserved by firmware.
-    ///
-    /// Must be preserved in working and ACPI S1-S3 states.
-    EfiACPIMemoryNVS,
-    /// Memory used by firmware for requesting memory mapping of IO.
-    ///
-    /// Should not be used by the OS. Use the ACPI tables for memory mapped IO
-    /// information.
-    EfiMemoryMappedIO,
-    /// Memory used to translate memory cycles to IO cycles.
-    ///
-    /// Should not be used by the OS. Use the ACPI tables for memory mapped IO
-    /// information.
-    EfiMemoryMappedIOPortSpace,
-    /// Memory used by the processor.
-    ///
-    /// Must be preserved in working and ACPI S1-S4 states. Processor defined
-    /// otherwise.
-    EfiPalCode,
-    /// Available memory supporting byte-addressable non-volatility.
-    EfiPersistentMemory,
-    /// Unknown region type, treat as unusable.
-    EfiUnknown,
-}
-
-impl From<EFIMemoryAreaType> for u32 {
-    fn from(area: EFIMemoryAreaType) -> Self {
-        match area {
-            EFIMemoryAreaType::EfiReservedMemoryType => 0,
-            EFIMemoryAreaType::EfiLoaderCode => 1,
-            EFIMemoryAreaType::EfiLoaderData => 2,
-            EFIMemoryAreaType::EfiBootServicesCode => 3,
-            EFIMemoryAreaType::EfiBootServicesData => 4,
-            EFIMemoryAreaType::EfiRuntimeServicesCode => 5,
-            EFIMemoryAreaType::EfiRuntimeServicesData => 6,
-            EFIMemoryAreaType::EfiConventionalMemory => 7,
-            EFIMemoryAreaType::EfiUnusableMemory => 8,
-            EFIMemoryAreaType::EfiACPIReclaimMemory => 9,
-            EFIMemoryAreaType::EfiACPIMemoryNVS => 10,
-            EFIMemoryAreaType::EfiMemoryMappedIO => 11,
-            EFIMemoryAreaType::EfiMemoryMappedIOPortSpace => 12,
-            EFIMemoryAreaType::EfiPalCode => 13,
-            EFIMemoryAreaType::EfiPersistentMemory => 14,
-            EFIMemoryAreaType::EfiUnknown => panic!("unknown type"),
-        }
-    }
-}
-
-impl EFIMemoryDesc {
-    /// The physical address of the memory region.
-    pub fn physical_address(&self) -> u64 {
-        self.phys_addr
-    }
-
-    /// The virtual address of the memory region.
-    pub fn virtual_address(&self) -> u64 {
-        self.virt_addr
-    }
-
-    /// The size in bytes of the memory region.
-    pub fn size(&self) -> u64 {
-        // Spec says this is number of 4KiB pages.
-        self.num_pages * 4096
-    }
-
-    /// The type of the memory region.
-    pub fn typ(&self) -> EFIMemoryAreaType {
-        match self.typ {
-            0 => EFIMemoryAreaType::EfiReservedMemoryType,
-            1 => EFIMemoryAreaType::EfiLoaderCode,
-            2 => EFIMemoryAreaType::EfiLoaderData,
-            3 => EFIMemoryAreaType::EfiBootServicesCode,
-            4 => EFIMemoryAreaType::EfiBootServicesData,
-            5 => EFIMemoryAreaType::EfiRuntimeServicesCode,
-            6 => EFIMemoryAreaType::EfiRuntimeServicesData,
-            7 => EFIMemoryAreaType::EfiConventionalMemory,
-            8 => EFIMemoryAreaType::EfiUnusableMemory,
-            9 => EFIMemoryAreaType::EfiACPIReclaimMemory,
-            10 => EFIMemoryAreaType::EfiACPIMemoryNVS,
-            11 => EFIMemoryAreaType::EfiMemoryMappedIO,
-            12 => EFIMemoryAreaType::EfiMemoryMappedIOPortSpace,
-            13 => EFIMemoryAreaType::EfiPalCode,
-            14 => EFIMemoryAreaType::EfiPersistentMemory,
-            _ => EFIMemoryAreaType::EfiUnknown,
-        }
-    }
-}
-
-impl Default for EFIMemoryDesc {
-    fn default() -> Self {
-        Self {
-            typ: EFIMemoryAreaType::EfiReservedMemoryType.into(),
-            _padding: 0,
-            phys_addr: 0,
-            virt_addr: 0,
-            num_pages: 0,
-            attr: 0,
-        }
-    }
-}
-
 /// EFI ExitBootServices was not called
 /// EFI ExitBootServices was not called
 #[derive(Debug)]
 #[derive(Debug)]
 #[repr(C)]
 #[repr(C)]

+ 9 - 6
multiboot2/src/rsdp.rs

@@ -8,15 +8,17 @@
 //!
 //!
 //! Even though the bootloader should give the address of the real RSDP/XSDT, the checksum and
 //! Even though the bootloader should give the address of the real RSDP/XSDT, the checksum and
 //! signature should be manually verified.
 //! signature should be manually verified.
-#[cfg(feature = "builder")]
-use crate::builder::traits::StructAsBytes;
-use crate::tag_type::{TagType, TagTypeId};
+//!
 
 
-use core::convert::TryInto;
-use core::mem::size_of;
+use crate::tag_type::TagTypeId;
 use core::slice;
 use core::slice;
 use core::str;
 use core::str;
 use core::str::Utf8Error;
 use core::str::Utf8Error;
+#[cfg(feature = "builder")]
+use {
+    crate::builder::traits::StructAsBytes, crate::TagType, core::convert::TryInto,
+    core::mem::size_of,
+};
 
 
 const RSDPV1_LENGTH: usize = 20;
 const RSDPV1_LENGTH: usize = 20;
 
 
@@ -105,7 +107,8 @@ pub struct RsdpV2Tag {
     revision: u8,
     revision: u8,
     rsdt_address: u32,
     rsdt_address: u32,
     length: u32,
     length: u32,
-    xsdt_address: u64, // This is the PHYSICAL address of the XSDT
+    xsdt_address: u64,
+    // This is the PHYSICAL address of the XSDT
     ext_checksum: u8,
     ext_checksum: u8,
     _reserved: [u8; 3],
     _reserved: [u8; 3],
 }
 }

+ 5 - 5
multiboot2/src/smbios.rs

@@ -1,10 +1,10 @@
-use crate::{Tag, TagTrait, TagType, TagTypeId};
-
-use core::convert::TryInto;
+use crate::{Tag, TagTrait, TagTypeId};
 use core::fmt::Debug;
 use core::fmt::Debug;
-
 #[cfg(feature = "builder")]
 #[cfg(feature = "builder")]
-use {crate::builder::boxed_dst_tag, crate::builder::traits::StructAsBytes, alloc::boxed::Box};
+use {
+    crate::builder::boxed_dst_tag, crate::builder::traits::StructAsBytes, crate::TagType,
+    alloc::boxed::Box, core::convert::TryInto,
+};
 
 
 const METADATA_SIZE: usize = core::mem::size_of::<TagTypeId>()
 const METADATA_SIZE: usize = core::mem::size_of::<TagTypeId>()
     + core::mem::size_of::<u32>()
     + core::mem::size_of::<u32>()

+ 8 - 0
multiboot2/src/vbe_info.rs

@@ -247,6 +247,8 @@ pub struct VBEField {
 
 
 bitflags! {
 bitflags! {
     /// The Capabilities field indicates the support of specific features in the graphics environment.
     /// The Capabilities field indicates the support of specific features in the graphics environment.
+    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
+    #[repr(transparent)]
     pub struct VBECapabilities: u32 {
     pub struct VBECapabilities: u32 {
         /// Can the DAC be switched between 6 and 8 bit modes.
         /// Can the DAC be switched between 6 and 8 bit modes.
         const SWITCHABLE_DAC = 0x1;
         const SWITCHABLE_DAC = 0x1;
@@ -263,6 +265,8 @@ bitflags! {
 
 
 bitflags! {
 bitflags! {
     /// A Mode attributes bitfield.
     /// A Mode attributes bitfield.
+    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
+    #[repr(transparent)]
     pub struct VBEModeAttributes: u16 {
     pub struct VBEModeAttributes: u16 {
         /// Mode supported by hardware configuration.
         /// Mode supported by hardware configuration.
         const SUPPORTED = 0x1;
         const SUPPORTED = 0x1;
@@ -294,6 +298,8 @@ bitflags! {
 bitflags! {
 bitflags! {
     /// The WindowAttributes describe the characteristics of the CPU windowing
     /// The WindowAttributes describe the characteristics of the CPU windowing
     /// scheme such as whether the windows exist and are read/writeable, as follows:
     /// scheme such as whether the windows exist and are read/writeable, as follows:
+    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
+    #[repr(transparent)]
     pub struct VBEWindowAttributes: u8 {
     pub struct VBEWindowAttributes: u8 {
         /// Relocatable window(s) supported?
         /// Relocatable window(s) supported?
         const RELOCATABLE = 0x1;
         const RELOCATABLE = 0x1;
@@ -317,6 +323,8 @@ bitflags! {
     /// (it is assumed all color ramp data is 8 bits per primary).
     /// (it is assumed all color ramp data is 8 bits per primary).
     /// Bit D1 specifies whether the bits in the Rsvd field of the direct color
     /// Bit D1 specifies whether the bits in the Rsvd field of the direct color
     /// pixel can be used by the application or are reserved, and thus unusable.
     /// pixel can be used by the application or are reserved, and thus unusable.
+    #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, PartialOrd, Ord)]
+    #[repr(transparent)]
     pub struct VBEDirectColorAttributes: u8 {
     pub struct VBEDirectColorAttributes: u8 {
         /// Color ramp is fixed when cleared and programmable when set.
         /// Color ramp is fixed when cleared and programmable when set.
         const PROGRAMMABLE = 0x1;
         const PROGRAMMABLE = 0x1;