diff --git a/.github/workflows/integrationtest.yml b/.github/workflows/integrationtest.yml index 2386694d..b0851385 100644 --- a/.github/workflows/integrationtest.yml +++ b/.github/workflows/integrationtest.yml @@ -11,6 +11,10 @@ name: "Integration Test" # Run on every push (tag, branch) and pull_request on: [ pull_request, push, merge_group ] +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + env: CARGO_TERM_COLOR: always diff --git a/.github/workflows/qa.yml b/.github/workflows/qa.yml index ed022c2e..0267453c 100644 --- a/.github/workflows/qa.yml +++ b/.github/workflows/qa.yml @@ -2,6 +2,10 @@ name: QA on: [pull_request, push, merge_group] +concurrency: + group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }} + cancel-in-progress: true + jobs: spellcheck: name: Spellcheck @@ -9,4 +13,4 @@ jobs: steps: - uses: actions/checkout@v4 # Executes "typos ." - - uses: crate-ci/typos@v1.23.6 + - uses: crate-ci/typos@v1.24.3 diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index 70715b72..3c914f55 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -24,7 +24,7 @@ jobs: name: build (msrv) uses: ./.github/workflows/_build-rust.yml with: - rust-version: 1.70.0 # MSRV + rust-version: 1.75.0 # MSRV do-style-check: false features: builder @@ -50,7 +50,7 @@ jobs: needs: build_msrv uses: ./.github/workflows/_build-rust.yml with: - rust-version: 1.70.0 # MSRV + rust-version: 1.75.0 # MSRV do-style-check: false rust-target: thumbv7em-none-eabihf features: builder @@ -107,7 +107,7 @@ jobs: needs: build_msrv uses: ./.github/workflows/_build-rust.yml with: - rust-version: 1.70.0 # MSRV + rust-version: 1.75.0 # MSRV do-style-check: true do-test: false features: builder diff --git a/Cargo.lock b/Cargo.lock index 40ee3afd..357c5f9c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -10,13 +10,23 @@ checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "derive_more" -version = "0.99.18" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", - "syn 2.0.74", + "syn 2.0.77", + "unicode-xid", ] [[package]] @@ -27,7 +37,7 @@ checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" [[package]] name = "multiboot2" -version = "0.22.2" +version = "0.23.0" dependencies = [ "bitflags", "derive_more", @@ -39,7 +49,7 @@ dependencies = [ [[package]] name = "multiboot2-common" -version = "0.1.2" +version = "0.2.0" dependencies = [ "derive_more", "ptr_meta", @@ -47,7 +57,7 @@ dependencies = [ [[package]] name = "multiboot2-header" -version = "0.5.1" +version = "0.6.0" dependencies = [ "derive_more", "log", @@ -87,9 +97,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.36" +version = "1.0.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "b5b9d34b8991d19d98081b46eacdd8eb58c6f2b201139f7c5f643cc155a633af" dependencies = [ "proc-macro2", ] @@ -107,9 +117,9 @@ dependencies = [ [[package]] name = "syn" -version = "2.0.74" +version = "2.0.77" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1fceb41e3d546d0bd83421d3409b1460cc7444cd389341a4c880fe7a042cb3d7" +checksum = "9f35bcdf61fd8e7be6caf75f429fdca8beb3ed76584befb503b1569faee373ed" dependencies = [ "proc-macro2", "quote", @@ -118,9 +128,9 @@ dependencies = [ [[package]] name = "uefi-raw" -version = "0.5.2" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efa8716f52e8cab8bcedfd5052388a0f263b69fe5cc2561548dc6a530678333c" +checksum = "b463030b802e1265a3800fab24df95d3229c202c2e408832a206f05b4d1496ca" dependencies = [ "bitflags", "ptr_meta", @@ -135,6 +145,12 @@ checksum = "ab14ea9660d240e7865ce9d54ecdbd1cd9fa5802ae6f4512f093c7907e921533" [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.13" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e91b56cd4cadaeb79bbf1a5645f6b4f8dc5bde8834ad5894a8db35fda9efa1fe" + +[[package]] +name = "unicode-xid" +version = "0.2.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" diff --git a/Cargo.toml b/Cargo.toml index 49bd0ea7..f361d21b 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,10 +11,11 @@ exclude = [ [workspace.dependencies] bitflags = "2.6.0" -derive_more = { version = "~0.99.18", default-features = false, features = ["display"] } +derive_more = { version = "1.0.0", default-features = false, features = ["display"] } log = { version = "~0.4", default-features = false } -multiboot2 = { version = "0.22.2", default-features = false } -multiboot2-common = { version = "0.1.2", default-features = false } +multiboot2 = { version = "0.23.0", default-features = false } +multiboot2-common = { version = "0.2.0", default-features = false } +# Warn: 0.3 has multiple very breaking changes ptr_meta = { version = "~0.2", default-features = false } # This way, the corresponding crate dependency can be normalley referenced by diff --git a/integration-test/bins/Cargo.lock b/integration-test/bins/Cargo.lock index dff4de92..3f508fec 100644 --- a/integration-test/bins/Cargo.lock +++ b/integration-test/bins/Cargo.lock @@ -34,13 +34,23 @@ checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" [[package]] name = "derive_more" -version = "0.99.18" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f33878137e4dafd7fa914ad4e259e18a4e8e532b9617a2d0150262bf53abfce" +checksum = "4a9b99b9cbbe49445b21764dc0625032a89b145a2642e67603e1c936f5458d05" +dependencies = [ + "derive_more-impl", +] + +[[package]] +name = "derive_more-impl" +version = "1.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cb7330aeadfbe296029522e6c40f315320aba36fc43a5b3632f3795348f3bd22" dependencies = [ "proc-macro2", "quote", "syn 2.0.74", + "unicode-xid", ] [[package]] @@ -96,7 +106,7 @@ dependencies = [ [[package]] name = "multiboot2" -version = "0.22.2" +version = "0.23.0" dependencies = [ "bitflags 2.6.0", "derive_more", @@ -108,7 +118,7 @@ dependencies = [ [[package]] name = "multiboot2-common" -version = "0.1.2" +version = "0.2.0" dependencies = [ "derive_more", "ptr_meta", @@ -116,7 +126,7 @@ dependencies = [ [[package]] name = "multiboot2-header" -version = "0.5.1" +version = "0.6.0" dependencies = [ "derive_more", "log", @@ -258,9 +268,9 @@ dependencies = [ [[package]] name = "uefi-raw" -version = "0.5.2" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "efa8716f52e8cab8bcedfd5052388a0f263b69fe5cc2561548dc6a530678333c" +checksum = "b463030b802e1265a3800fab24df95d3229c202c2e408832a206f05b4d1496ca" dependencies = [ "bitflags 2.6.0", "ptr_meta", @@ -279,6 +289,12 @@ version = "1.0.12" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +[[package]] +name = "unicode-xid" +version = "0.2.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "229730647fbc343e3a80e463c1db7f78f3855d3f3739bee0dda773c9a037c90a" + [[package]] name = "util" version = "0.1.0" diff --git a/multiboot2-common/CHANGELOG.md b/multiboot2-common/CHANGELOG.md index d2ecb870..bc3fd61b 100644 --- a/multiboot2-common/CHANGELOG.md +++ b/multiboot2-common/CHANGELOG.md @@ -1,9 +1,16 @@ # Changelog for Crate `multiboot2-common` +## Unreleased + +## v0.2.0 (2024-09-17) + +- dependency updates +- **Breaking:** MSRV is now 1.75 +- misc metadata fixes + ## v0.1.2 (2024-08-24) - Documentation improvements -- ## 0.1.0 / 0.1.1 (2024-08-20) diff --git a/multiboot2-common/Cargo.toml b/multiboot2-common/Cargo.toml index 5ea30f70..73d040cc 100644 --- a/multiboot2-common/Cargo.toml +++ b/multiboot2-common/Cargo.toml @@ -3,7 +3,7 @@ name = "multiboot2-common" description = """ Common helpers for the `multiboot2` and `multiboot2-header` crates. """ -version = "0.1.2" +version = "0.2.0" authors = [ "Philipp Schuster " ] @@ -17,10 +17,10 @@ keywords = [ "Multiboot2" ] readme = "README.md" -homepage = "https://github.com/rust-osdev/multiboot2" +homepage = "https://github.com/rust-osdev/multiboot2/tree/main/multiboot2-common" repository = "https://github.com/rust-osdev/multiboot2" documentation = "https://docs.rs/multiboot2-common" -rust-version = "1.70" +rust-version = "1.75" [features] default = ["builder"] diff --git a/multiboot2-common/README.md b/multiboot2-common/README.md index 7a2282ed..4694864f 100644 --- a/multiboot2-common/README.md +++ b/multiboot2-common/README.md @@ -24,7 +24,7 @@ ABI-compatible rusty types. ## MSRV -The MSRV is 1.70.0 stable. +The MSRV is 1.75.0 stable. ## License & Contribution diff --git a/multiboot2-common/architecture.drawio.png b/multiboot2-common/architecture.drawio.png index a3d0e18c..de80e91e 100644 Binary files a/multiboot2-common/architecture.drawio.png and b/multiboot2-common/architecture.drawio.png differ diff --git a/multiboot2-common/architecture.drawio.xml b/multiboot2-common/architecture.drawio.xml index 1e87a57d..ab1dc7eb 100644 --- a/multiboot2-common/architecture.drawio.xml +++ b/multiboot2-common/architecture.drawio.xml @@ -1,160 +1,150 @@ - + - + - + - + - + - + - + - + - + - + - + - + - + - + - - + + - - + + - + - - + + - + - - + + - + - - + + - + - + - + - - + + - - + + - - + + - - + + - + - - + + - - - - - - - - - - - - + + - + - - + + - - - + + + - + - - + + - - - + + + - - + + @@ -164,8 +154,8 @@ - - + + @@ -175,8 +165,8 @@ - - + + @@ -185,31 +175,43 @@ - + - - + + - - + + - + - + - - + + - - + + - + + + + + + + + + + + + + diff --git a/multiboot2-common/src/boxed.rs b/multiboot2-common/src/boxed.rs index bbd45ad4..24a8906d 100644 --- a/multiboot2-common/src/boxed.rs +++ b/multiboot2-common/src/boxed.rs @@ -7,10 +7,11 @@ use core::mem; use core::ops::Deref; use core::ptr; -/// Creates a new tag implementing [`MaybeDynSized`] on the heap. This works for -/// sized and unsized tags. However, it only makes sense to use this for tags -/// that are DSTs (unsized). For regular sized structs, you can just create a -/// typical constructor and box the result. +/// Creates a new tag implementing [`MaybeDynSized`] on the heap. +/// +/// This works for sized and unsized tags. However, it only makes sense to use +/// this for tags that are DSTs (unsized). For regular sized structs, you can +/// just create a typical constructor and box the result. /// /// The provided `header`' total size (see [`Header`]) will be set dynamically /// by this function using [`Header::set_size`]. However, it must contain all diff --git a/multiboot2-common/src/bytes_ref.rs b/multiboot2-common/src/bytes_ref.rs index 45907418..f2291408 100644 --- a/multiboot2-common/src/bytes_ref.rs +++ b/multiboot2-common/src/bytes_ref.rs @@ -6,7 +6,11 @@ use core::mem; use core::ops::Deref; /// Wraps a byte slice representing a Multiboot2 structure including an optional -/// terminating padding, if necessary. It guarantees that the memory +/// terminating padding, if necessary. +/// +/// This type helps that casts to a specific tag from the underlying bytes are +/// either same-size casts or down-size casts, but never upsize-casts, which are +/// illegal and UB! Instances of this type guarantee that the memory /// requirements promised in the crates description are respected. #[derive(Clone, Debug, PartialEq, Eq)] #[repr(transparent)] diff --git a/multiboot2-common/src/lib.rs b/multiboot2-common/src/lib.rs index 5bc7d5e9..d4ed7e18 100644 --- a/multiboot2-common/src/lib.rs +++ b/multiboot2-common/src/lib.rs @@ -226,10 +226,12 @@ use core::slice; /// The alignment of all Multiboot2 data structures. pub const ALIGNMENT: usize = 8; -/// A sized header type for [`DynSizedStructure`]. Note that `header` refers to -/// the header pattern. Thus, depending on the use case, this is not just a -/// tag header. Instead, it refers to all bytes that are fixed and not part of -/// any optional terminating dynamic `[u8]` slice in a [`DynSizedStructure`]. +/// A sized header type for [`DynSizedStructure`]. +/// +/// Note that `header` refers to the header pattern. Thus, depending on the use +/// case, this is not just a tag header. Instead, it refers to all bytes that +/// are fixed and not part of any optional terminating dynamic `[u8]` slice in a +/// [`DynSizedStructure`]. /// /// The alignment of implementors **must** be the compatible with the demands /// for the corresponding structure, which typically is [`ALIGNMENT`]. @@ -251,9 +253,11 @@ pub trait Header: Clone + Sized + PartialEq + Eq + Debug { } /// An C ABI-compatible dynamically sized type with a common sized [`Header`] -/// and a dynamic amount of bytes. This structures owns all its bytes, unlike -/// [`Header`]. Instances guarantees that the memory requirements promised in -/// the crates description are respected. +/// and a dynamic amount of bytes. +/// +/// This structures owns all its bytes, unlike [`Header`]. Instances guarantees +/// that the memory requirements promised in the crates description are +/// respected. /// /// This can be a Multiboot2 header tag, information tag, boot information, or /// a Multiboot2 header. Depending on the context, the [`Header`] is different. @@ -263,6 +267,11 @@ pub trait Header: Clone + Sized + PartialEq + Eq + Debug { /// Further, there is a variable amount of payload bytes. Thus, this type can /// only exist on the heap or references to it can be made by cast via fat /// pointers. +/// +/// As there might be padding necessary for the proper Rust layout, +/// `size_of_val(&self)` might report additional padding bytes that are not +/// reflected by the actual payload. These additional padding bytes however +/// will be reflected in corresponding [`BytesRef`] instances. #[derive(Debug, PartialEq, Eq, ptr_meta::Pointee)] #[repr(C, align(8))] pub struct DynSizedStructure { @@ -330,14 +339,16 @@ impl DynSizedStructure { /// Performs a memory-safe same-size cast from the base-structure to a /// specific [`MaybeDynSized`]. The idea here is to cast the generic /// mostly semantic-free version to a specific type with fields that have - /// a semantic. + /// a clear semantic. /// /// The provided `T` of type [`MaybeDynSized`] might be may be sized type - /// or DST. This depends on the type. + /// or DST. This depends on the type. However, the source and the target + /// both will have the same actual payload size and the same + /// [`size_of_val`]. /// /// # Panic /// Panics if base assumptions are violated. For example, the - /// `T` of type [`MaybeDynSized`] must allow a proper casting to it. + /// `T` of type [`MaybeDynSized`] must allow proper same-size casting to it. /// /// # Safety /// This function is safe due to various sanity checks and the overall @@ -346,6 +357,8 @@ impl DynSizedStructure { /// # Panics /// This panics if there is a size mismatch. However, this should never be /// the case if all types follow their documented requirements. + /// + /// [`size_of_val`]: mem::size_of_val pub fn cast + ?Sized>(&self) -> &T { let base_ptr = ptr::addr_of!(*self); @@ -386,9 +399,10 @@ pub enum MemoryError { impl core::error::Error for MemoryError {} /// Increases the given size to the next alignment boundary, if it is not a -/// multiple of the alignment yet. This is relevant as in Rust's [type layout], -/// the allocated size of a type is always a multiple of the alignment, even -/// if the type is smaller. +/// multiple of the alignment yet. +/// +/// This is relevant as in Rust's [type layout], the allocated size of a type is +/// always a multiple of the alignment, even if the type is smaller. /// /// [type layout]: https://doc.rust-lang.org/reference/type-layout.html #[must_use] diff --git a/multiboot2-common/src/tag.rs b/multiboot2-common/src/tag.rs index 29a4da53..1501ede5 100644 --- a/multiboot2-common/src/tag.rs +++ b/multiboot2-common/src/tag.rs @@ -9,9 +9,15 @@ use ptr_meta::Pointee; /// casting a [`DynSizedStructure`] to sized or unsized structures using /// [`DynSizedStructure::cast`]. /// -/// Structs that are a DST must provide a **correct** -/// [`MaybeDynSized::dst_len`] implementation. Further, implementors **must** -/// use `#[repr(C)]`. +/// Structs that are a DST must provide a **correct** [`MaybeDynSized::dst_len`] +/// implementation. +/// +/// # ABI +/// Implementors **must** use `#[repr(C)]`. As there might be padding necessary +/// for the proper Rust layout, `size_of_val(&self)` might report additional +/// padding bytes that are not reflected by the actual payload. These additional +/// padding bytes however will be reflected in corresponding [`BytesRef`] +/// instances. /// /// [`ID`]: Tag::ID /// [`DynSizedStructure`]: crate::DynSizedStructure diff --git a/multiboot2-common/src/test_utils.rs b/multiboot2-common/src/test_utils.rs index c81cec8d..1a4cfc1e 100644 --- a/multiboot2-common/src/test_utils.rs +++ b/multiboot2-common/src/test_utils.rs @@ -8,8 +8,10 @@ use core::mem; use core::ops::Deref; /// Helper to 8-byte align the underlying bytes, as mandated in the Multiboot2 -/// spec. With this type, one can create manual and raw Multiboot2 boot -/// information or just the bytes for simple tags, in a manual and raw approach. +/// spec. +/// +/// With this type, one can create manual and raw Multiboot2 boot information or +/// just the bytes for simple tags, in a manual and raw approach. #[derive(Debug)] #[repr(C, align(8))] pub struct AlignedBytes(pub [u8; N]); diff --git a/multiboot2-header/CHANGELOG.md b/multiboot2-header/CHANGELOG.md index d18a5953..defc36d3 100644 --- a/multiboot2-header/CHANGELOG.md +++ b/multiboot2-header/CHANGELOG.md @@ -1,5 +1,13 @@ # Changelog for Crate `multiboot2-header` +## Unreleased + +## v0.6.0 (2024-09-17) + +- dependency updates +- **Breaking:** MSRV is now 1.75 +- misc metadata fixes + ## v0.5.1 (2024-08-24) - Documentation improvements diff --git a/multiboot2-header/Cargo.toml b/multiboot2-header/Cargo.toml index c8ca8787..b5d33ea3 100644 --- a/multiboot2-header/Cargo.toml +++ b/multiboot2-header/Cargo.toml @@ -6,7 +6,7 @@ contained header tags. Usable in no_std environments, such as a bootloader. An optional builder feature also allows the construction of the corresponding structures. """ -version = "0.5.1" +version = "0.6.0" authors = [ "Philipp Schuster " ] @@ -26,10 +26,10 @@ keywords = [ # without this, sometimes crates.io doesn't show the preview of the README # I expeciended this multiple times in the past readme = "README.md" -homepage = "https://github.com/rust-osdev/multiboot2-header" +homepage = "https://github.com/rust-osdev/multiboot2/tree/main/multiboot2-header" repository = "https://github.com/rust-osdev/multiboot2" documentation = "https://docs.rs/multiboot2-header" -rust-version = "1.70" +rust-version = "1.75" [[example]] name = "minimal" @@ -37,10 +37,10 @@ required-features = ["builder"] [features] default = ["builder"] -alloc = [] -builder = ["alloc"] +alloc = ["multiboot2-common/alloc"] +builder = ["alloc", "multiboot2-common/builder"] # Nightly-only features, which will eventually be stabilized. -unstable = [] +unstable = ["multiboot2-common/unstable"] [dependencies] derive_more.workspace = true diff --git a/multiboot2-header/README.md b/multiboot2-header/README.md index b33cfb92..170615f6 100644 --- a/multiboot2-header/README.md +++ b/multiboot2-header/README.md @@ -1,6 +1,5 @@ # multiboot2-header -![Build](https://github.com/rust-osdev/multiboot2/actions/workflows/rust.yml/badge.svg) [![crates.io](https://img.shields.io/crates/v/multiboot2-header.svg)](https://crates.io/crates/multiboot2-header) [![docs](https://docs.rs/multiboot2-header/badge.svg)](https://docs.rs/multiboot2-header/) @@ -86,7 +85,7 @@ bytes of the ELF. See Multiboot2 specification. ## MSRV -The MSRV is 1.70.0 stable. +The MSRV is 1.75.0 stable. ## License & Contribution diff --git a/multiboot2-header/src/address.rs b/multiboot2-header/src/address.rs index 70d7c0ef..1bfe7fd8 100644 --- a/multiboot2-header/src/address.rs +++ b/multiboot2-header/src/address.rs @@ -2,6 +2,8 @@ use crate::{HeaderTagFlag, HeaderTagHeader, HeaderTagType}; use core::mem::size_of; use multiboot2_common::{MaybeDynSized, Tag}; +/// Binary address information for non-ELF images. +/// /// This information does not need to be provided if the kernel image is in ELF /// format, but it must be provided if the image is in a.out format or in some /// other format. Required for legacy boot (BIOS). diff --git a/multiboot2-header/src/entry_efi_32.rs b/multiboot2-header/src/entry_efi_32.rs index d62d346b..34a8d26f 100644 --- a/multiboot2-header/src/entry_efi_32.rs +++ b/multiboot2-header/src/entry_efi_32.rs @@ -4,6 +4,8 @@ use core::fmt::{Debug, Formatter}; use core::mem; use multiboot2_common::{MaybeDynSized, Tag}; +/// Contains the entry address for EFI i386 machine state. +/// /// This tag is taken into account only on EFI i386 platforms when Multiboot2 image header /// contains EFI boot services tag. Then entry point specified in ELF header and the entry address /// tag of Multiboot2 header are ignored. diff --git a/multiboot2-header/src/entry_efi_64.rs b/multiboot2-header/src/entry_efi_64.rs index 6b855d5b..1a673496 100644 --- a/multiboot2-header/src/entry_efi_64.rs +++ b/multiboot2-header/src/entry_efi_64.rs @@ -4,6 +4,8 @@ use core::fmt::{Debug, Formatter}; use core::mem; use multiboot2_common::{MaybeDynSized, Tag}; +/// Contains the entry address for EFI amd64 machine state. +/// /// This tag is taken into account only on EFI amd64 platforms when Multiboot2 image header /// contains EFI boot services tag. Then entry point specified in ELF header and the entry address /// tag of Multiboot2 header are ignored. diff --git a/multiboot2-header/src/header.rs b/multiboot2-header/src/header.rs index a55b14e4..53963e5e 100644 --- a/multiboot2-header/src/header.rs +++ b/multiboot2-header/src/header.rs @@ -15,6 +15,7 @@ use multiboot2_common::{DynSizedStructure, Header, MemoryError, Tag, ALIGNMENT}; pub const MAGIC: u32 = 0xe85250d6; /// Wrapper type around a pointer to the Multiboot2 header. +/// /// The Multiboot2 header is the [`Multiboot2BasicHeader`] followed /// by all tags (see [`crate::tags::HeaderTagType`]). /// Use this if you get a pointer to the header and just want diff --git a/multiboot2-header/src/lib.rs b/multiboot2-header/src/lib.rs index e2121b68..d4066dca 100644 --- a/multiboot2-header/src/lib.rs +++ b/multiboot2-header/src/lib.rs @@ -23,7 +23,7 @@ //! //! ## MSRV //! -//! The MSRV is 1.70.0 stable. +//! The MSRV is 1.75.0 stable. #![no_std] #![cfg_attr(feature = "unstable", feature(error_in_core))] diff --git a/multiboot2-header/src/relocatable.rs b/multiboot2-header/src/relocatable.rs index df54e981..987030c7 100644 --- a/multiboot2-header/src/relocatable.rs +++ b/multiboot2-header/src/relocatable.rs @@ -4,10 +4,11 @@ use core::fmt::{Debug, Formatter}; use core::mem; use multiboot2_common::{MaybeDynSized, Tag}; -/// It contains load address placement suggestion for boot loader. Boot loader -/// should follow it. ‘0’ means none, ‘1’ means load image at lowest possible address -/// but not lower than min addr and ‘2’ means load image at highest possible -/// address but not higher than max addr. +/// It contains load address placement suggestion for bootloader. +/// +/// Bootloader should follow it. ‘0’ means none, ‘1’ means load image at lowest +/// possible address 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, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum RelocatableHeaderTagPreference { diff --git a/multiboot2-header/src/tags.rs b/multiboot2-header/src/tags.rs index 9d9f5aa6..862eea45 100644 --- a/multiboot2-header/src/tags.rs +++ b/multiboot2-header/src/tags.rs @@ -18,9 +18,11 @@ pub enum HeaderTagISA { MIPS32 = 4, } -/// Possible types for header tags of a Multiboot2 header. The names and values are taken -/// from the example C code at the bottom of the Multiboot2 specification. This value -/// stands in the `typ` property of [`HeaderTagHeader`]. +/// Possible types for header tags of a Multiboot2 header. +/// +/// The names and values are taken from the example C code at the bottom of the +/// Multiboot2 specification. This value stands in the `typ` property of +/// [`HeaderTagHeader`]. #[repr(u16)] #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum HeaderTagType { diff --git a/multiboot2/CHANGELOG.md b/multiboot2/CHANGELOG.md index 6a875fe4..592a6b8f 100644 --- a/multiboot2/CHANGELOG.md +++ b/multiboot2/CHANGELOG.md @@ -1,5 +1,18 @@ # Changelog for Crate `multiboot2` +## Unreleased + +## v0.23.0 (2024-09-17) + +- dependency updates +- **Breaking:** MSRV is now 1.75 +- Added missing tags along with getters for on `BootInformation`: + - `ApmTag` + - `BootdevTag` + - `NetworkTag` +- `BootInformation::tags` iterator is now public +- misc metadata fixes + ## v0.22.2 (2024-08-24) - Documentation improvements @@ -67,7 +80,6 @@ release and you'll be fine!** references instead of owned values - **Breaking:** The `BoxedDst` has been removed in favor of a normal Rust `Box`. This only affects you if you use the `builder` feature. -- **Breaking:** MSRV is 1.75 - **Breaking:** Introduced new `TagHeader` type as replacement for the `Tag` type that will be changed in the next step. `Tag` has been renamed to an internal-only `GenericTag` type. diff --git a/multiboot2/Cargo.toml b/multiboot2/Cargo.toml index 05ff43cb..3ce6ef71 100644 --- a/multiboot2/Cargo.toml +++ b/multiboot2/Cargo.toml @@ -6,7 +6,7 @@ structures and the contained information tags. Usable in `no_std` environments, such as a kernel. An optional builder feature also allows the construction of the corresponding structures. """ -version = "0.22.2" +version = "0.23.0" authors = [ "Philipp Oppermann ", "Calvin Lee ", @@ -29,10 +29,10 @@ keywords = [ # without this, sometimes crates.io doesn't show the preview of the README # I expeciended this multiple times in the past readme = "README.md" -homepage = "https://github.com/rust-osdev/multiboot2" +homepage = "https://github.com/rust-osdev/multiboot2/tree/main/multiboot2" repository = "https://github.com/rust-osdev/multiboot2" documentation = "https://docs.rs/multiboot2" -rust-version = "1.70" +rust-version = "1.75" [features] default = ["builder"] @@ -47,11 +47,7 @@ derive_more.workspace = true log.workspace = true ptr_meta.workspace = true multiboot2-common.workspace = true -# We only use a very basic type definition from this crate. To prevent MSRV -# bumps from uefi-raw, I restrict this here. Upstream users are likely to have -# two versions of this library in it, which is no problem, as we only use the -# type definition. -uefi-raw = { version = "~0.5", default-features = false } +uefi-raw = { version = "~0.8.0", default-features = false } [package.metadata.docs.rs] all-features = true diff --git a/multiboot2/README.md b/multiboot2/README.md index 5c15d837..efd4694f 100644 --- a/multiboot2/README.md +++ b/multiboot2/README.md @@ -47,7 +47,7 @@ There are many different types of tags, but they all have the same beginning: ## MSRV -The MSRV is 1.70.0 stable. +The MSRV is 1.75.0 stable. ## License & Contribution diff --git a/multiboot2/src/apm.rs b/multiboot2/src/apm.rs new file mode 100644 index 00000000..11211a36 --- /dev/null +++ b/multiboot2/src/apm.rs @@ -0,0 +1,126 @@ +//! Module for [`ApmTag`]. + +use crate::{TagHeader, TagType}; +use core::mem; +use multiboot2_common::{MaybeDynSized, Tag}; + +/// The Advanced Power Management (APM) tag. +#[derive(Debug)] +#[repr(C, align(8))] +pub struct ApmTag { + header: TagHeader, + version: u16, + cseg: u16, + offset: u32, + cset_16: u16, + dseg: u16, + flags: u16, + cseg_len: u16, + cseg_16_len: u16, + dseg_len: u16, +} + +impl ApmTag { + /// Creates a new tag. + #[allow(clippy::too_many_arguments)] + #[must_use] + pub fn new( + version: u16, + cseg: u16, + offset: u32, + cset_16: u16, + dset: u16, + flags: u16, + cseg_len: u16, + cseg_16_len: u16, + dseg_len: u16, + ) -> Self { + Self { + header: TagHeader::new(TagType::Apm, mem::size_of::() as u32), + version, + cseg, + offset, + cset_16, + dseg: dset, + flags, + cseg_len, + cseg_16_len, + dseg_len, + } + } + + /// The version number of the APM BIOS. + #[must_use] + pub const fn version(&self) -> u16 { + self.version + } + + /// Contains the 16-bit code segment (CS) address for the APM entry point. + #[must_use] + pub const fn cseg(&self) -> u16 { + self.cseg + } + + /// Represents the offset address within the code segment (`cseg`) for the + /// APM entry point. + #[must_use] + pub const fn offset(&self) -> u32 { + self.offset + } + + /// Contains the 16-bit code segment (CS) address used for 16-bit protected + /// mode APM functions. + #[must_use] + pub const fn cset_16(&self) -> u16 { + self.cset_16 + } + + /// Holds the 16-bit data segment (DS) address used by the APM BIOS for + /// data operations. + #[must_use] + pub const fn dseg(&self) -> u16 { + self.dseg + } + + /// Indicates the status and characteristics of the APM connection, such as + /// if APM is present and its capabilities. + #[must_use] + pub const fn flags(&self) -> u16 { + self.flags + } + + /// Indicates the length, in bytes, of the data segment (`dseg`) used by + /// the APM BIOS + #[must_use] + pub const fn cseg_len(&self) -> u16 { + self.cseg_len + } + + /// Provides the length, in bytes, of the 16-bit code segment (`cseg_16`) + /// used for APM functions. + #[must_use] + pub const fn cseg_16_len(&self) -> u16 { + self.cseg_16_len + } + + /// Indicates the length, in bytes, of the data segment (`dseg`) used by + /// the APM BIOS. + #[must_use] + pub const fn dseg_len(&self) -> u16 { + self.dseg_len + } +} + +impl MaybeDynSized for ApmTag { + type Header = TagHeader; + + const BASE_SIZE: usize = mem::size_of::(); + + fn dst_len(_: &TagHeader) {} +} + +impl Tag for ApmTag { + type IDType = TagType; + + const ID: TagType = TagType::Apm; +} diff --git a/multiboot2/src/boot_information.rs b/multiboot2/src/boot_information.rs index 6eb6628d..0bf40116 100644 --- a/multiboot2/src/boot_information.rs +++ b/multiboot2/src/boot_information.rs @@ -3,10 +3,11 @@ use crate::framebuffer::UnknownFramebufferType; use crate::tag::TagHeader; use crate::{ - module, BasicMemoryInfoTag, BootLoaderNameTag, CommandLineTag, EFIBootServicesNotExitedTag, - EFIImageHandle32Tag, EFIImageHandle64Tag, EFIMemoryMapTag, EFISdt32Tag, EFISdt64Tag, - ElfSectionIter, ElfSectionsTag, EndTag, FramebufferTag, ImageLoadPhysAddrTag, MemoryMapTag, - ModuleIter, RsdpV1Tag, RsdpV2Tag, SmbiosTag, TagIter, TagType, VBEInfoTag, + module, ApmTag, BasicMemoryInfoTag, BootLoaderNameTag, BootdevTag, CommandLineTag, + EFIBootServicesNotExitedTag, EFIImageHandle32Tag, EFIImageHandle64Tag, EFIMemoryMapTag, + EFISdt32Tag, EFISdt64Tag, ElfSectionIter, ElfSectionsTag, EndTag, FramebufferTag, + ImageLoadPhysAddrTag, MemoryMapTag, ModuleIter, NetworkTag, RsdpV1Tag, RsdpV2Tag, SmbiosTag, + TagIter, TagType, VBEInfoTag, }; #[cfg(feature = "unstable")] use core::error::Error; @@ -165,44 +166,46 @@ impl<'a> BootInformation<'a> { // ###################################################### // ### BEGIN OF TAG GETTERS (in alphabetical order) - /*fn apm(&self) { - // also add to debug output - todo!() - }*/ + /// Search for the [`ApmTag`]. + #[must_use] + pub fn apm_tag(&self) -> Option<&ApmTag> { + self.get_tag::() + } - /// Search for the basic memory info tag. + /// Search for the [`BasicMemoryInfoTag`]. #[must_use] pub fn basic_memory_info_tag(&self) -> Option<&BasicMemoryInfoTag> { self.get_tag::() } - /// Search for the BootLoader name tag. + /// Search for the [`BootLoaderNameTag`]. #[must_use] pub fn boot_loader_name_tag(&self) -> Option<&BootLoaderNameTag> { self.get_tag::() } - /*fn bootdev(&self) { - // also add to debug output - todo!() - }*/ + /// Search for the [`BootdevTag`]. + #[must_use] + pub fn bootdev_tag(&self) -> Option<&BootdevTag> { + self.get_tag::() + } - /// Search for the Command line tag. + /// Search for the [`CommandLineTag`]. #[must_use] pub fn command_line_tag(&self) -> Option<&CommandLineTag> { self.get_tag::() } - /// Search for the EFI boot services not exited tag. + /// Search for the [`EFIBootServicesNotExitedTag`]. #[must_use] pub fn efi_bs_not_exited_tag(&self) -> Option<&EFIBootServicesNotExitedTag> { self.get_tag::() } - /// Search for the EFI Memory map tag, if the boot services were exited. + /// Search for the [`EFIMemoryMapTag`], if the boot services were exited. /// Otherwise, if the [`TagType::EfiBs`] tag is present, this returns `None` - /// as it is strictly recommended to get the memory map from the `uefi` - /// services. + /// as it is strictly recommended to get the memory map from `uefi` + /// instead. /// /// [`TagType::EfiBs`]: crate::TagType::EfiBs #[must_use] @@ -216,25 +219,25 @@ impl<'a> BootInformation<'a> { }) } - /// Search for the EFI 32-bit SDT tag. + /// Search for the [`EFISdt32Tag`]. #[must_use] pub fn efi_sdt32_tag(&self) -> Option<&EFISdt32Tag> { self.get_tag::() } - /// Search for the EFI 64-bit SDT tag. + /// Search for the [`EFISdt64Tag`]. #[must_use] pub fn efi_sdt64_tag(&self) -> Option<&EFISdt64Tag> { self.get_tag::() } - /// Search for the EFI 32-bit image handle pointer tag. + /// Search for the [`EFIImageHandle32Tag`]. #[must_use] pub fn efi_ih32_tag(&self) -> Option<&EFIImageHandle32Tag> { self.get_tag::() } - /// Search for the EFI 64-bit image handle pointer tag. + /// Search for the [`EFIImageHandle64Tag`]. #[must_use] pub fn efi_ih64_tag(&self) -> Option<&EFIImageHandle64Tag> { self.get_tag::() @@ -266,61 +269,62 @@ impl<'a> BootInformation<'a> { }) } - /// Search for the VBE framebuffer tag. The result is `Some(Err(e))`, if the + /// Search for the [`FramebufferTag`]. The result is `Some(Err(e))`, if the /// framebuffer type is unknown, while the framebuffer tag is present. #[must_use] pub fn framebuffer_tag(&self) -> Option> { self.get_tag::() - // TODO temporarily. Someone needs to fix the framebuffer thingy. - .map(Ok) - /*.map(|tag| match tag.buffer_type() { - Ok(_) => Ok(tag), - Err(e) => Err(e), - })*/ + .map(|tag| match tag.buffer_type() { + Ok(_) => Ok(tag), + Err(e) => Err(e), + }) } - /// Search for the Image Load Base Physical Address tag. + /// Search for the [`ImageLoadPhysAddrTag`]. #[must_use] pub fn load_base_addr_tag(&self) -> Option<&ImageLoadPhysAddrTag> { self.get_tag::() } - /// Search for the Memory map tag. + /// Search for the [`MemoryMapTag`]. #[must_use] pub fn memory_map_tag(&self) -> Option<&MemoryMapTag> { self.get_tag::() } - /// Get an iterator of all module tags. + /// Get an iterator of all [`ModuleTag`]s. + /// + /// [`ModuleTag`]: crate::ModuleTag #[must_use] pub fn module_tags(&self) -> ModuleIter { module::module_iter(self.tags()) } - /*fn network_tag(&self) { - // also add to debug output - todo!() - }*/ + /// Search for the [`NetworkTag`]. + #[must_use] + pub fn network_tag(&self) -> Option<&NetworkTag> { + self.get_tag::() + } - /// Search for the (ACPI 1.0) RSDP tag. + /// Search for the [`RsdpV1Tag`]. #[must_use] pub fn rsdp_v1_tag(&self) -> Option<&RsdpV1Tag> { self.get_tag::() } - /// Search for the (ACPI 2.0 or later) RSDP tag. + /// Search for the [`RsdpV2Tag`]. #[must_use] pub fn rsdp_v2_tag(&self) -> Option<&RsdpV2Tag> { self.get_tag::() } - /// Search for the SMBIOS tag. + /// Search for the [`SmbiosTag`]. #[must_use] pub fn smbios_tag(&self) -> Option<&SmbiosTag> { self.get_tag::() } - /// Search for the VBE information tag. + /// Search for the [`VBEInfoTag`]. #[must_use] pub fn vbe_info_tag(&self) -> Option<&VBEInfoTag> { self.get_tag::() @@ -403,7 +407,12 @@ impl<'a> BootInformation<'a> { } /// Returns an iterator over all tags. - pub(crate) fn tags(&self) -> TagIter { + /// + /// This is public to enable users to iterate over tags that appear multiple + /// times, even tho this is unusual. However, it is recommended to use the + /// tag getters as normal bootloaders provide most tags only once. + #[must_use] + pub fn tags(&self) -> TagIter { TagIter::new(self.0.payload()) } } diff --git a/multiboot2/src/bootdev.rs b/multiboot2/src/bootdev.rs new file mode 100644 index 00000000..14640e16 --- /dev/null +++ b/multiboot2/src/bootdev.rs @@ -0,0 +1,67 @@ +//! Module for [`BootdevTag`]. + +use crate::{TagHeader, TagType}; +use core::mem; +use multiboot2_common::{MaybeDynSized, Tag}; + +/// The end tag ends the information struct. +#[derive(Debug)] +#[repr(C, align(8))] +pub struct BootdevTag { + header: TagHeader, + biosdev: u32, + slice: u32, + part: u32, +} + +impl BootdevTag { + /// Creates a new tag. + #[must_use] + pub fn new(biosdev: u32, slice: u32, part: u32) -> Self { + Self { + header: TagHeader::new(TagType::Apm, mem::size_of::() as u32), + biosdev, + slice, + part, + } + } + + /// Returns the bios device from which the device was booted from. + /// `0x00` represents the first floppy disk. + /// `0x80` represents the first hard disk, 0x81 the second hard disk, and + /// so on. + #[must_use] + pub const fn biosdev(&self) -> u32 { + self.biosdev + } + + /// The slice field identifies the partition (also known as a "slice" in BSD + /// terminology) on the BIOS device from which the operating system was + /// booted. + #[must_use] + pub const fn slice(&self) -> u32 { + self.slice + } + + /// The part field denotes the subpartition or logical partition within the + /// primary partition (if applicable) from which the operating system was + /// booted. + #[must_use] + pub const fn part(&self) -> u32 { + self.part + } +} + +impl MaybeDynSized for BootdevTag { + type Header = TagHeader; + + const BASE_SIZE: usize = mem::size_of::(); + + fn dst_len(_: &TagHeader) {} +} + +impl Tag for BootdevTag { + type IDType = TagType; + + const ID: TagType = TagType::Bootdev; +} diff --git a/multiboot2/src/builder.rs b/multiboot2/src/builder.rs index 6ee4dea6..0ddab5de 100644 --- a/multiboot2/src/builder.rs +++ b/multiboot2/src/builder.rs @@ -1,5 +1,8 @@ //! Module for [`Builder`]. +use crate::apm::ApmTag; +use crate::bootdev::BootdevTag; +use crate::network::NetworkTag; use crate::{ BasicMemoryInfoTag, BootInformationHeader, BootLoaderNameTag, CommandLineTag, EFIBootServicesNotExitedTag, EFIImageHandle32Tag, EFIImageHandle64Tag, EFIMemoryMapTag, @@ -18,18 +21,18 @@ pub struct Builder { bootloader: Option>, modules: Vec>, meminfo: Option, - // missing bootdev: Option + bootdev: Option, mmap: Option>, vbe: Option, framebuffer: Option>, elf_sections: Option>, - // missing apm: + apm: Option, efi32: Option, efi64: Option, smbios: Vec>, rsdpv1: Option, rsdpv2: Option, - // missing: network + network: Option>, efi_mmap: Option>, efi_bs: Option, efi32_ih: Option, @@ -53,16 +56,19 @@ impl Builder { bootloader: None, modules: vec![], meminfo: None, + bootdev: None, mmap: None, vbe: None, framebuffer: None, elf_sections: None, + apm: None, efi32: None, efi64: None, smbios: vec![], rsdpv1: None, rsdpv2: None, efi_mmap: None, + network: None, efi_bs: None, efi32_ih: None, efi64_ih: None, @@ -99,6 +105,13 @@ impl Builder { self } + /// Sets the [`BootdevTag`] tag. + #[must_use] + pub const fn bootdev(mut self, bootdev: BootdevTag) -> Self { + self.bootdev = Some(bootdev); + self + } + /// Sets the [`MemoryMapTag`] tag. #[must_use] pub fn mmap(mut self, mmap: Box) -> Self { @@ -127,6 +140,13 @@ impl Builder { self } + /// Sets the [`ApmTag`] tag. + #[must_use] + pub const fn apm(mut self, apm: ApmTag) -> Self { + self.apm = Some(apm); + self + } + /// Sets the [`EFISdt32Tag`] tag. #[must_use] pub const fn efi32(mut self, efi32: EFISdt32Tag) -> Self { @@ -169,6 +189,13 @@ impl Builder { self } + /// Sets the [`NetworkTag`] tag. + #[must_use] + pub fn network(mut self, network: Box) -> Self { + self.network = Some(network); + self + } + /// Sets the [`EFIBootServicesNotExitedTag`] tag. #[must_use] pub const fn efi_bs(mut self, efi_bs: EFIBootServicesNotExitedTag) -> Self { @@ -226,6 +253,9 @@ impl Builder { if let Some(tag) = self.meminfo.as_ref() { byte_refs.push(tag.as_bytes().as_ref()); } + if let Some(tag) = self.bootdev.as_ref() { + byte_refs.push(tag.as_bytes().as_ref()); + } if let Some(tag) = self.mmap.as_ref() { byte_refs.push(tag.as_bytes().as_ref()); } @@ -238,6 +268,9 @@ impl Builder { if let Some(tag) = self.elf_sections.as_ref() { byte_refs.push(tag.as_bytes().as_ref()); } + if let Some(tag) = self.apm.as_ref() { + byte_refs.push(tag.as_bytes().as_ref()); + } if let Some(tag) = self.efi32.as_ref() { byte_refs.push(tag.as_bytes().as_ref()); } @@ -293,6 +326,7 @@ mod tests { .add_module(ModuleTag::new(0x1000, 0x2000, "module 1")) .add_module(ModuleTag::new(0x3000, 0x4000, "module 2")) .meminfo(BasicMemoryInfoTag::new(0x4000, 0x5000)) + .bootdev(BootdevTag::new(0x00, 0x00, 0x00)) .mmap(MemoryMapTag::new(&[MemoryArea::new( 0x1000000, 0x1000, @@ -316,6 +350,7 @@ mod tests { FramebufferType::Text, )) .elf_sections(ElfSectionsTag::new(0, 32, 0, &[])) + .apm(ApmTag::new(0, 0, 0, 0, 0, 0, 0, 0, 0)) .efi32(EFISdt32Tag::new(0x1000)) .efi64(EFISdt64Tag::new(0x1000)) .add_smbios(SmbiosTag::new(0, 0, &[1, 2, 3])) @@ -326,6 +361,7 @@ mod tests { MemoryDescriptor::default(), MemoryDescriptor::default(), ])) + .network(NetworkTag::new(&[0; 1500])) .efi_bs(EFIBootServicesNotExitedTag::new()) .efi32_ih(EFIImageHandle32Tag::new(0x1000)) .efi64_ih(EFIImageHandle64Tag::new(0x1000)) diff --git a/multiboot2/src/end.rs b/multiboot2/src/end.rs index d8f900c4..23707d0b 100644 --- a/multiboot2/src/end.rs +++ b/multiboot2/src/end.rs @@ -1,6 +1,6 @@ //! Module for [`EndTag`]. -use crate::{TagHeader, TagType, TagTypeId}; +use crate::{TagHeader, TagType}; use core::mem; use multiboot2_common::{MaybeDynSized, Tag}; @@ -8,15 +8,13 @@ use multiboot2_common::{MaybeDynSized, Tag}; #[derive(Debug)] #[repr(C, align(8))] pub struct EndTag { - typ: TagTypeId, - size: u32, + header: TagHeader, } impl Default for EndTag { fn default() -> Self { Self { - typ: TagType::End.into(), - size: 8, + header: TagHeader::new(TagType::End, mem::size_of::() as u32), } } } diff --git a/multiboot2/src/framebuffer.rs b/multiboot2/src/framebuffer.rs index 1e480fd6..78b5da0e 100644 --- a/multiboot2/src/framebuffer.rs +++ b/multiboot2/src/framebuffer.rs @@ -371,9 +371,11 @@ pub struct FramebufferField { pub size: u8, } -/// A framebuffer color descriptor in the palette. On the ABI level, multiple -/// values are consecutively without padding bytes. The spec is not precise in -/// that regard, but looking at Limine's and GRUB's source code confirm that. +/// A framebuffer color descriptor in the palette. +/// +/// On the ABI level, multiple values are consecutively without padding bytes. +/// The spec is not precise in that regard, but looking at Limine's and GRUB's +/// source code confirm that. #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] #[repr(C)] // no align(8) here is correct pub struct FramebufferColor { @@ -389,7 +391,7 @@ pub struct FramebufferColor { /// Error when an unknown [`FramebufferTypeId`] is found. #[derive(Debug, Copy, Clone, Display, PartialEq, Eq)] -#[display(fmt = "Unknown framebuffer type {}", _0)] +#[display("Unknown framebuffer type {}", _0)] pub struct UnknownFramebufferType(u8); #[cfg(feature = "unstable")] diff --git a/multiboot2/src/lib.rs b/multiboot2/src/lib.rs index 8027c79a..cd13f558 100644 --- a/multiboot2/src/lib.rs +++ b/multiboot2/src/lib.rs @@ -42,7 +42,7 @@ //! ``` //! //! ## MSRV -//! The MSRV is 1.70.0 stable. +//! The MSRV is 1.75.0 stable. #[cfg_attr(feature = "builder", macro_use)] #[cfg(feature = "builder")] @@ -66,8 +66,10 @@ pub type TagIter<'a> = multiboot2_common::TagIter<'a, TagHeader>; #[cfg(test)] pub type GenericInfoTag = multiboot2_common::DynSizedStructure; +mod apm; mod boot_information; mod boot_loader_name; +mod bootdev; mod command_line; mod efi; mod elf_sections; @@ -76,6 +78,7 @@ mod framebuffer; mod image_load_addr; mod memory_map; mod module; +mod network; mod rsdp; mod smbios; mod tag; @@ -85,8 +88,10 @@ mod vbe_info; pub use multiboot2_common::{DynSizedStructure, MaybeDynSized, Tag}; +pub use apm::ApmTag; pub use boot_information::{BootInformation, BootInformationHeader, LoadError}; pub use boot_loader_name::BootLoaderNameTag; +pub use bootdev::BootdevTag; #[cfg(feature = "builder")] pub use builder::Builder; pub use command_line::CommandLineTag; @@ -104,6 +109,7 @@ pub use memory_map::{ MemoryArea, MemoryAreaType, MemoryAreaTypeId, MemoryMapTag, }; pub use module::{ModuleIter, ModuleTag}; +pub use network::NetworkTag; pub use ptr_meta::Pointee; pub use rsdp::{RsdpV1Tag, RsdpV2Tag}; pub use smbios::SmbiosTag; @@ -131,7 +137,6 @@ mod tests { /// This test is relevant to give library users flexebility in passing the /// struct around. #[test] - #[allow(clippy::missing_const_for_fn)] // only in Rust 1.70 necessary fn boot_information_is_send_and_sync() { fn accept(_: T) {} let bytes = AlignedBytes([ diff --git a/multiboot2/src/network.rs b/multiboot2/src/network.rs new file mode 100644 index 00000000..1cea90b7 --- /dev/null +++ b/multiboot2/src/network.rs @@ -0,0 +1,43 @@ +//! Module for [`NetworkTag`]. + +use crate::{TagHeader, TagType, TagTypeId}; +use core::mem; +use multiboot2_common::{MaybeDynSized, Tag}; +use ptr_meta::Pointee; +#[cfg(feature = "builder")] +use {alloc::boxed::Box, multiboot2_common::new_boxed}; + +/// The end tag ends the information struct. +#[derive(Debug, Pointee)] +#[repr(C, align(8))] +pub struct NetworkTag { + typ: TagTypeId, + size: u32, + dhcpack: [u8], +} + +impl NetworkTag { + /// Create a new network tag from the given DHCP package. + #[cfg(feature = "builder")] + #[must_use] + pub fn new(dhcp_pack: &[u8]) -> Box { + let header = TagHeader::new(Self::ID, 0); + new_boxed(header, &[dhcp_pack]) + } +} + +impl MaybeDynSized for NetworkTag { + type Header = TagHeader; + + const BASE_SIZE: usize = mem::size_of::(); + + fn dst_len(header: &TagHeader) -> usize { + header.size as usize - Self::BASE_SIZE + } +} + +impl Tag for NetworkTag { + type IDType = TagType; + + const ID: TagType = TagType::Network; +} diff --git a/multiboot2/src/tag_type.rs b/multiboot2/src/tag_type.rs index f7ae50df..3d5921c4 100644 --- a/multiboot2/src/tag_type.rs +++ b/multiboot2/src/tag_type.rs @@ -6,8 +6,10 @@ use core::fmt::{Debug, Formatter}; use core::hash::Hash; /// Serialized form of [`TagType`] that matches the binary representation -/// (`u32`). The abstraction corresponds to the `typ`/`type` field of a -/// Multiboot2 [`TagHeader`]. This type can easily be created from or converted to +/// (`u32`). +/// +/// The abstraction corresponds to the `typ`/`type` field of a Multiboot2 +/// [`TagHeader`]. This type can easily be created from or converted to /// [`TagType`]. /// /// [`TagHeader`]: crate::TagHeader @@ -31,9 +33,10 @@ impl Debug for TagTypeId { } /// Higher level abstraction for [`TagTypeId`] that assigns each possible value -/// to a specific semantic according to the specification. Additionally, it -/// allows to use the [`TagType::Custom`] variant. It is **not binary compatible** -/// with [`TagTypeId`]. +/// to a specific semantic according to the specification. +/// +/// Additionally, it allows to use the [`TagType::Custom`] variant. It is +/// **not binary compatible** with [`TagTypeId`]. #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)] pub enum TagType { /// Tag `0`: Marks the end of the tags.