diff --git a/.github/workflows/rust.yml b/.github/workflows/rust.yml index f6c052cc..bcf41503 100644 --- a/.github/workflows/rust.yml +++ b/.github/workflows/rust.yml @@ -75,6 +75,7 @@ jobs: # check that devs can also use this on Windows. build_nostd_stable_windows: name: build no_std (stable) [Windows] + needs: build_stable uses: ./.github/workflows/_build-rust.yml with: runs-on: windows-latest diff --git a/Cargo.lock b/Cargo.lock index 91109f43..3838d459 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,24 +2,12 @@ # It is not intended for manual editing. version = 3 -[[package]] -name = "bitflags" -version = "1.3.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" - [[package]] name = "bitflags" version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "6dbe3c979c178231552ecba20214a8272df4e09f232a87aef4320cf06539aded" -[[package]] -name = "cfg-if" -version = "1.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" - [[package]] name = "derive_more" version = "0.99.17" @@ -33,27 +21,15 @@ dependencies = [ [[package]] name = "log" -version = "0.4.17" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abb12e687cfb44aa40f41fc3978ef76448f9b6038cad6aef4259d3c095a2382e" -dependencies = [ - "cfg-if", -] - -[[package]] -name = "multiboot2" -version = "0.13.3" +version = "0.4.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d408e10189a4b0e1d488a24a19c5c8c9786f011b30c824c8ab02d3ebf5f62ca2" -dependencies = [ - "bitflags 1.3.2", -] +checksum = "b06a4cde4c0f271a446782e3eff8de789548ce57dbc8eca9292c27f4a42004b4" [[package]] name = "multiboot2" -version = "0.15.1" +version = "0.16.0" dependencies = [ - "bitflags 2.3.2", + "bitflags", "derive_more", "log", "ptr_meta", @@ -62,16 +38,16 @@ dependencies = [ [[package]] name = "multiboot2-header" -version = "0.2.0" +version = "0.3.0" dependencies = [ - "multiboot2 0.13.3", + "multiboot2", ] [[package]] name = "proc-macro2" -version = "1.0.53" +version = "1.0.60" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba466839c78239c09faf015484e5cc04860f88242cff4d03eb038f04b4699b73" +checksum = "dec2b086b7a862cf4de201096214fa870344cf922b2b30c167badb3af3195406" dependencies = [ "unicode-ident", ] @@ -98,9 +74,9 @@ dependencies = [ [[package]] name = "quote" -version = "1.0.26" +version = "1.0.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4424af4bf778aae2051a77b60283332f386554255d722233d09fbfc7e30da2fc" +checksum = "1b9ab9c7eadfd8df19006f1cf1a4aed13540ed5cbc047010ece5826e10825488" dependencies = [ "proc-macro2", ] @@ -122,7 +98,7 @@ version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d73e08d8e944b7c7e90a7c8a53213bdd71ceb7b414ee664f522c1cc579888c25" dependencies = [ - "bitflags 2.3.2", + "bitflags", "ptr_meta", "uguid", ] @@ -135,6 +111,6 @@ checksum = "594cc87e268a7b43d625d46c63cf1605d0e61bf66e4b1cd58c058ec0191e1f81" [[package]] name = "unicode-ident" -version = "1.0.8" +version = "1.0.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e5464a87b239f13a63a501f2701565754bae92d243d4bb7eb12f6d57d2269bf4" +checksum = "b15811caf2415fb889178633e7724bad2509101cde276048e013b9def5e51fa0" diff --git a/Cargo.toml b/Cargo.toml index 6cc2b2ff..79c9ee88 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,5 +1,13 @@ [workspace] +resolver = "2" members = [ "multiboot2", "multiboot2-header", ] + + +# This way, the "multiboot2" dependency in the multiboot2-header crate can be +# referenced by version, while still the repository version is used +# transparently during local development. +[patch.crates-io] +multiboot2 = { path = "multiboot2" } diff --git a/multiboot2-header/Cargo.toml b/multiboot2-header/Cargo.toml index dcbbe82a..1080eaba 100644 --- a/multiboot2-header/Cargo.toml +++ b/multiboot2-header/Cargo.toml @@ -4,7 +4,7 @@ description = """ Library with type definitions and parsing functions for Multiboot2 headers. This library is `no_std` and can be used in bootloaders. """ -version = "0.2.0" +version = "0.3.0" authors = [ "Philipp Schuster " ] @@ -41,4 +41,4 @@ unstable = [] [dependencies] # used for MBI tags -multiboot2 = "0.13.2" +multiboot2 = "0.16.0" diff --git a/multiboot2-header/Changelog.md b/multiboot2-header/Changelog.md index 35ac2995..66908054 100644 --- a/multiboot2-header/Changelog.md +++ b/multiboot2-header/Changelog.md @@ -1,24 +1,25 @@ # CHANGELOG for crate `multiboot2-header` -## Unreleased +## 0.3.0 (xxxx-xx-xx) - MSRV is 1.68.0 - renamed the `std` feature to `alloc` - added the optional `unstable` feature (requires nightly) - implement `core::error::Error` for `LoadError` +- depends on `multiboot2@v0.16.0` -## v0.2.0 (2022-05-03) +## 0.2.0 (2022-05-03) - **BREAKING** renamed `EntryHeaderTag` to `EntryAddressHeaderTag` - **BREAKING** some paths changed from `multiboot2_header::header` to `multiboot2_header::builder` -> thus, import paths are much more logically now - internal code improvements -## v0.1.1 (2022-05-02) +## 0.1.1 (2022-05-02) - fixed a bug that prevented the usage of the crate in `no_std` environments - added a new default `builder`-feature to Cargo which requires the `alloc`-crate (this feature can be disabled which will also remove the dependency to the `alloc` crate) -## v0.1.0 (2021-10-08) +## 0.1.0 (2021-10-08) - initial release -## v0.0.0 +## 0.0.0 Empty release to save the name on crates.io diff --git a/multiboot2-header/src/builder/information_request.rs b/multiboot2-header/src/builder/information_request.rs index 39f4cafb..849d822a 100644 --- a/multiboot2-header/src/builder/information_request.rs +++ b/multiboot2-header/src/builder/information_request.rs @@ -1,10 +1,11 @@ use super::traits::StructAsBytes; -use crate::InformationRequestHeaderTag; use crate::{HeaderTagFlag, MbiTagType}; +use crate::{InformationRequestHeaderTag, MbiTagTypeId}; use alloc::collections::BTreeSet; use alloc::vec::Vec; use core::fmt::Debug; use core::mem::size_of; +use multiboot2::TagTypeId; /// Helper to build the dynamically sized [`InformationRequestHeaderTag`] /// at runtime. The information request tag has a dedicated builder because this way one @@ -21,7 +22,6 @@ pub struct InformationRequestHeaderTagBuilder { #[cfg(feature = "builder")] impl InformationRequestHeaderTagBuilder { /// New builder. - #[allow(clippy::missing_const_for_fn)] // TODO remove once MSRV is higher than 1.65.0 pub fn new(flag: HeaderTagFlag) -> Self { Self { irs: BTreeSet::new(), @@ -31,10 +31,9 @@ impl InformationRequestHeaderTagBuilder { /// Returns the expected length of the information request tag, /// when the `build`-method gets called. - #[allow(clippy::missing_const_for_fn)] // TODO remove once MSRV is higher than 1.65.0 pub fn expected_len(&self) -> usize { let basic_header_size = size_of::>(); - let req_tags_size = self.irs.len() * size_of::(); + let req_tags_size = self.irs.len() * size_of::(); basic_header_size + req_tags_size } @@ -74,8 +73,13 @@ impl InformationRequestHeaderTagBuilder { ); } - for tag in &self.irs { - let bytes: [u8; 4] = (*tag as u32).to_ne_bytes(); + for tag_type in self + .irs + .into_iter() + // Transform to the ABI-compatible type + .map(TagTypeId::from) + { + let bytes: [u8; 4] = (u32::from(tag_type)).to_le_bytes(); data.extend(&bytes); } @@ -91,7 +95,7 @@ impl InformationRequestHeaderTagBuilder { #[cfg(test)] mod tests { use crate::builder::information_request::InformationRequestHeaderTagBuilder; - use crate::{HeaderTagFlag, InformationRequestHeaderTag, MbiTagType}; + use crate::{HeaderTagFlag, InformationRequestHeaderTag, MbiTagType, MbiTagTypeId}; #[test] fn test_builder() { @@ -111,11 +115,19 @@ mod tests { // type(u16) + flags(u16) + size(u32) + 3 tags (u32) assert_eq!(tag.size(), 2 + 2 + 4 + 3 * 4); assert_eq!(tag.dynamic_requests_size(), 3); - assert!(tag.requests().contains(&MbiTagType::EfiMmap)); - assert!(tag.requests().contains(&MbiTagType::BootLoaderName)); - assert!(tag.requests().contains(&MbiTagType::Cmdline)); + assert!(tag + .requests() + .contains(&MbiTagTypeId::from(MbiTagType::EfiMmap))); + assert!(tag + .requests() + .contains(&MbiTagTypeId::from(MbiTagType::BootLoaderName))); + assert!(tag + .requests() + .contains(&MbiTagTypeId::from(MbiTagType::Cmdline))); assert_eq!(tag.requests().len(), 3); - assert!(!tag.requests().contains(&MbiTagType::AcpiV1)); + assert!(!tag + .requests() + .contains(&MbiTagTypeId::from(MbiTagType::AcpiV1))); println!("{:#?}", tag); } } diff --git a/multiboot2-header/src/information_request.rs b/multiboot2-header/src/information_request.rs index 77146045..bf2f920b 100644 --- a/multiboot2-header/src/information_request.rs +++ b/multiboot2-header/src/information_request.rs @@ -1,9 +1,10 @@ -use crate::HeaderTagType; use crate::{HeaderTagFlag, MbiTagType}; +use crate::{HeaderTagType, MbiTagTypeId}; use core::fmt; use core::fmt::{Debug, Formatter}; use core::marker::PhantomData; use core::mem::size_of; +use multiboot2::TagType; /// Specifies what specific tag types the bootloader should provide /// inside the mbi. @@ -15,14 +16,14 @@ pub struct InformationRequestHeaderTag { size: u32, // Length is determined by size. // Must be parsed during runtime with unsafe pointer magic and the size field. - requests: [MbiTagType; N], + requests: [MbiTagTypeId; N], } impl InformationRequestHeaderTag { /// Creates a new object. The size parameter is the value of the size property. /// It doesn't have to match with `N` necessarily, because during compile time we /// can't know the size of the tag in all runtime situations. - pub fn new(flags: HeaderTagFlag, requests: [MbiTagType; N], size: Option) -> Self { + pub fn new(flags: HeaderTagFlag, requests: [MbiTagTypeId; N], size: Option) -> Self { InformationRequestHeaderTag { typ: HeaderTagType::InformationRequest, flags, @@ -44,7 +45,7 @@ impl InformationRequestHeaderTag { /// Returns the requests as array. Only works if the number of requests /// is known at compile time. For safety and correctness during runtime, /// you should use `req_iter()`. - pub const fn requests(&self) -> [MbiTagType; N] { + pub const fn requests(&self) -> [MbiTagTypeId; N] { // cheap to copy, otherwise difficult with lifetime self.requests } @@ -70,7 +71,7 @@ impl InformationRequestHeaderTag { let base_ptr = self as *const InformationRequestHeaderTag; let base_ptr = base_ptr as *const u8; let base_ptr = unsafe { base_ptr.add(base_struct_size) }; - let base_ptr = base_ptr as *const MbiTagType; + let base_ptr = base_ptr as *const MbiTagTypeId; InformationRequestHeaderTagIter::new(count, base_ptr) } } @@ -90,32 +91,32 @@ impl Debug for InformationRequestHeaderTag { /// that are requested. #[derive(Copy, Clone)] pub struct InformationRequestHeaderTagIter<'a> { - base_ptr: *const MbiTagType, + base_ptr: *const MbiTagTypeId, i: u32, count: u32, _marker: PhantomData<&'a ()>, } impl<'a> InformationRequestHeaderTagIter<'a> { - fn new(count: u32, base_ptr: *const MbiTagType) -> Self { - #[allow(clippy::default_constructed_unit_structs)] + const fn new(count: u32, base_ptr: *const MbiTagTypeId) -> Self { Self { i: 0, count, base_ptr, - _marker: PhantomData::default(), + _marker: PhantomData, } } } impl<'a> Iterator for InformationRequestHeaderTagIter<'a> { - type Item = &'a MbiTagType; + type Item = MbiTagType; fn next(&mut self) -> Option { if self.i < self.count { let ptr = unsafe { self.base_ptr.offset(self.i as isize) }; self.i += 1; - Some(unsafe { &*ptr }) + let tag_type_id = unsafe { *ptr }; + Some(TagType::from(tag_type_id)) } else { None } @@ -126,7 +127,7 @@ impl<'a> Debug for InformationRequestHeaderTagIter<'a> { fn fmt(&self, f: &mut Formatter<'_>) -> fmt::Result { let mut debug = f.debug_list(); (*self).for_each(|e| { - debug.entry(e); + debug.entry(&e); }); debug.finish() } diff --git a/multiboot2-header/src/lib.rs b/multiboot2-header/src/lib.rs index 7291c891..57d01249 100644 --- a/multiboot2-header/src/lib.rs +++ b/multiboot2-header/src/lib.rs @@ -79,4 +79,4 @@ pub use self::tags::*; pub use self::uefi_bs::*; /// Re-export of [`multiboot2::TagType`] from `multiboot2`-crate. -pub use multiboot2::TagType as MbiTagType; +pub use multiboot2::{TagType as MbiTagType, TagTypeId as MbiTagTypeId}; diff --git a/multiboot2/Cargo.toml b/multiboot2/Cargo.toml index 334ed56d..0078e282 100644 --- a/multiboot2/Cargo.toml +++ b/multiboot2/Cargo.toml @@ -6,7 +6,7 @@ Multiboot2-compliant bootloaders, like GRUB. It supports all tags from the speci including full support for the sections of ELF-64. This library is `no_std` and can be used in a Multiboot2-kernel. """ -version = "0.15.1" +version = "0.16.0" authors = [ "Philipp Oppermann ", "Calvin Lee ", diff --git a/multiboot2/Changelog.md b/multiboot2/Changelog.md index e4ba01bf..d0df3cc1 100644 --- a/multiboot2/Changelog.md +++ b/multiboot2/Changelog.md @@ -1,6 +1,6 @@ # CHANGELOG for crate `multiboot2` -## unreleased +## 0.16.0 (xxxx-xx-xx) - Add `TagTrait` trait which enables to use DSTs as multiboot2 tags. This is mostly relevant for the command line tag, the modules tag, and the bootloader name tag. However, this might also be relevant for users of custom multiboot2 diff --git a/multiboot2/src/boot_loader_name.rs b/multiboot2/src/boot_loader_name.rs index 3bb2c79d..9a4977f0 100644 --- a/multiboot2/src/boot_loader_name.rs +++ b/multiboot2/src/boot_loader_name.rs @@ -84,8 +84,8 @@ mod tests { // size is: 4 bytes for tag + 4 bytes for size + length of null-terminated string let size = (4 + 4 + MSG.as_bytes().len() + 1) as u32; [ - &((TagType::BootLoaderName.val()).to_ne_bytes()), - &size.to_ne_bytes(), + &((TagType::BootLoaderName.val()).to_le_bytes()), + &size.to_le_bytes(), MSG.as_bytes(), // Null Byte &[0], diff --git a/multiboot2/src/command_line.rs b/multiboot2/src/command_line.rs index 58b875a4..39e396a6 100644 --- a/multiboot2/src/command_line.rs +++ b/multiboot2/src/command_line.rs @@ -93,8 +93,8 @@ mod tests { // size is: 4 bytes for tag + 4 bytes for size + length of null-terminated string let size = (4 + 4 + MSG.as_bytes().len() + 1) as u32; [ - &((TagType::Cmdline.val()).to_ne_bytes()), - &size.to_ne_bytes(), + &((TagType::Cmdline.val()).to_le_bytes()), + &size.to_le_bytes(), MSG.as_bytes(), // Null Byte &[0], diff --git a/multiboot2/src/efi.rs b/multiboot2/src/efi.rs index 64da04e6..7cee3b54 100644 --- a/multiboot2/src/efi.rs +++ b/multiboot2/src/efi.rs @@ -162,7 +162,7 @@ mod tests { #[test] fn test_build_eftih64() { - let tag = EFIImageHandle32::new(ADDR.try_into().unwrap()); + let tag = EFIImageHandle64::new(ADDR.try_into().unwrap()); assert_eq!(tag.image_handle(), ADDR); } } diff --git a/multiboot2/src/framebuffer.rs b/multiboot2/src/framebuffer.rs index 7c2036fb..7bbcba73 100644 --- a/multiboot2/src/framebuffer.rs +++ b/multiboot2/src/framebuffer.rs @@ -1,4 +1,4 @@ -use crate::{Reader, Tag, TagTrait, TagTypeId}; +use crate::{Tag, TagTrait, TagTypeId}; use core::fmt::Debug; use core::mem::size_of; @@ -11,6 +11,39 @@ use { alloc::boxed::Box, alloc::vec::Vec, }; +/// Helper struct to read bytes from a raw pointer and increase the pointer +/// automatically. +struct Reader { + ptr: *const u8, + off: usize, +} + +impl Reader { + fn new(ptr: *const T) -> Reader { + Reader { + ptr: ptr as *const u8, + off: 0, + } + } + + fn read_u8(&mut self) -> u8 { + self.off += 1; + unsafe { *self.ptr.add(self.off - 1) } + } + + fn read_u16(&mut self) -> u16 { + self.read_u8() as u16 | (self.read_u8() as u16) << 8 + } + + fn read_u32(&mut self) -> u32 { + self.read_u16() as u32 | (self.read_u16() as u32) << 16 + } + + fn current_address(&self) -> usize { + unsafe { self.ptr.add(self.off) as usize } + } +} + const METADATA_SIZE: usize = size_of::() + 4 * size_of::() + size_of::() diff --git a/multiboot2/src/lib.rs b/multiboot2/src/lib.rs index 42346099..f2a00cd6 100644 --- a/multiboot2/src/lib.rs +++ b/multiboot2/src/lib.rs @@ -502,37 +502,6 @@ impl fmt::Debug for BootInformation { } } -pub(crate) struct Reader { - pub(crate) ptr: *const u8, - pub(crate) off: usize, -} - -impl Reader { - pub(crate) fn new(ptr: *const T) -> Reader { - Reader { - ptr: ptr as *const u8, - off: 0, - } - } - - pub(crate) fn read_u8(&mut self) -> u8 { - self.off += 1; - unsafe { *self.ptr.add(self.off - 1) } - } - - pub(crate) fn read_u16(&mut self) -> u16 { - self.read_u8() as u16 | (self.read_u8() as u16) << 8 - } - - pub(crate) fn read_u32(&mut self) -> u32 { - self.read_u16() as u32 | (self.read_u16() as u32) << 16 - } - - pub(crate) fn current_address(&self) -> usize { - unsafe { self.ptr.add(self.off) as usize } - } -} - /// A trait to abstract over all sized and unsized tags (DSTs). For sized tags, /// this trait does not much. For DSTs, a `TagTrait::dst_size` implementation /// must me provided, which returns the right size hint for the dynamically @@ -1573,10 +1542,10 @@ mod tests { 0, 0, 0, // end: padding; end of multiboot2 boot information begin - CUSTOM_TAG_ID.to_ne_bytes()[0], - CUSTOM_TAG_ID.to_ne_bytes()[1], - CUSTOM_TAG_ID.to_ne_bytes()[2], - CUSTOM_TAG_ID.to_ne_bytes()[3], // end: my custom tag id + CUSTOM_TAG_ID.to_le_bytes()[0], + CUSTOM_TAG_ID.to_le_bytes()[1], + CUSTOM_TAG_ID.to_le_bytes()[2], + CUSTOM_TAG_ID.to_le_bytes()[3], // end: my custom tag id 12, 0, 0, @@ -1649,10 +1618,10 @@ mod tests { 0, 0, 0, // end: padding; end of multiboot2 boot information begin - CUSTOM_TAG_ID.to_ne_bytes()[0], - CUSTOM_TAG_ID.to_ne_bytes()[1], - CUSTOM_TAG_ID.to_ne_bytes()[2], - CUSTOM_TAG_ID.to_ne_bytes()[3], // end: my custom tag id + CUSTOM_TAG_ID.to_le_bytes()[0], + CUSTOM_TAG_ID.to_le_bytes()[1], + CUSTOM_TAG_ID.to_le_bytes()[2], + CUSTOM_TAG_ID.to_le_bytes()[3], // end: my custom tag id 14, 0, 0, @@ -1699,10 +1668,10 @@ mod tests { 0, 0, 0, // reserved - TagType::Cmdline.val().to_ne_bytes()[0], - TagType::Cmdline.val().to_ne_bytes()[1], - TagType::Cmdline.val().to_ne_bytes()[2], - TagType::Cmdline.val().to_ne_bytes()[3], + TagType::Cmdline.val().to_le_bytes()[0], + TagType::Cmdline.val().to_le_bytes()[1], + TagType::Cmdline.val().to_le_bytes()[2], + TagType::Cmdline.val().to_le_bytes()[3], 13, 0, 0, diff --git a/multiboot2/src/module.rs b/multiboot2/src/module.rs index d1db91ed..a66b2024 100644 --- a/multiboot2/src/module.rs +++ b/multiboot2/src/module.rs @@ -136,10 +136,10 @@ mod tests { // 4 bytes mod_start + 4 bytes mod_end let size = (4 + 4 + 4 + 4 + MSG.as_bytes().len() + 1) as u32; [ - &((TagType::Module.val()).to_ne_bytes()), - &size.to_ne_bytes(), - &0_u32.to_ne_bytes(), - &0_u32.to_ne_bytes(), + &((TagType::Module.val()).to_le_bytes()), + &size.to_le_bytes(), + &0_u32.to_le_bytes(), + &0_u32.to_le_bytes(), MSG.as_bytes(), // Null Byte &[0], diff --git a/multiboot2/src/smbios.rs b/multiboot2/src/smbios.rs index 9025c99c..629c1b5a 100644 --- a/multiboot2/src/smbios.rs +++ b/multiboot2/src/smbios.rs @@ -67,7 +67,7 @@ mod tests { // + 6 bytes reserved + the actual tables let size = (4 + 4 + 1 + 1 + 6 + tables.len()) as u32; let typ: u32 = TagType::Smbios.into(); - let mut bytes = [typ.to_ne_bytes(), size.to_ne_bytes()].concat(); + let mut bytes = [typ.to_le_bytes(), size.to_le_bytes()].concat(); bytes.push(3); bytes.push(0); bytes.extend([0; 6]);