@@ -8,19 +8,18 @@ use core::convert::TryInto;
88use core:: fmt:: { Debug , Formatter } ;
99use core:: mem:: size_of;
1010
11- /// Magic value for a [`Multiboot2Header`], as defined in spec.
12- pub const MULTIBOOT2_HEADER_MAGIC : u32 = 0xe85250d6 ;
11+ /// Magic value for a [`Multiboot2Header`], as defined by the spec.
12+ pub const MAGIC : u32 = 0xe85250d6 ;
1313
1414/// Wrapper type around a pointer to the Multiboot2 header.
1515/// The Multiboot2 header is the [`Multiboot2BasicHeader`] followed
1616/// by all tags (see [`crate::tags::HeaderTagType`]).
1717/// Use this if you get a pointer to the header and just want
1818/// to parse it. If you want to construct the type by yourself,
19- /// please look at [`crate::builder::HeaderBuilder`].
19+ /// please look at [`crate::builder::HeaderBuilder`]..
20+ #[ derive( Debug ) ]
2021#[ repr( transparent) ]
21- pub struct Multiboot2Header < ' a > {
22- inner : & ' a Multiboot2BasicHeader ,
23- }
22+ pub struct Multiboot2Header < ' a > ( & ' a Multiboot2BasicHeader ) ;
2423
2524impl < ' a > Multiboot2Header < ' a > {
2625 /// Public constructor for this type with various validations.
@@ -35,37 +34,41 @@ impl<'a> Multiboot2Header<'a> {
3534 /// # Safety
3635 /// This function may produce undefined behaviour, if the provided `addr` is not a valid
3736 /// Multiboot2 header pointer.
38- // This function can be `const` on newer Rust versions.
39- #[ allow( clippy:: missing_const_for_fn) ]
40- pub unsafe fn from_addr ( addr : usize ) -> Result < Self , LoadError > {
41- if addr == 0 || addr % 8 != 0 {
37+ pub unsafe fn load ( ptr : * const Multiboot2BasicHeader ) -> Result < Self , LoadError > {
38+ // null or not aligned
39+ if ptr. is_null ( ) || ptr. align_offset ( 8 ) != 0 {
4240 return Err ( LoadError :: InvalidAddress ) ;
4341 }
44- let ptr = addr as * const Multiboot2BasicHeader ;
42+
4543 let reference = & * ptr;
46- if reference. header_magic ( ) != MULTIBOOT2_HEADER_MAGIC {
44+
45+ if reference. header_magic ( ) != MAGIC {
4746 return Err ( LoadError :: MagicNotFound ) ;
4847 }
48+
4949 if !reference. verify_checksum ( ) {
5050 return Err ( LoadError :: ChecksumMismatch ) ;
5151 }
52- Ok ( Self { inner : reference } )
52+
53+ Ok ( Self ( reference) )
5354 }
5455
5556 /// Find the header in a given slice.
5657 ///
5758 /// If it succeeds, it returns a tuple consisting of the subslice containing
5859 /// just the header and the index of the header in the given slice.
59- /// If it fails (either because the header is not properply 64-bit aligned
60+ /// If it fails (either because the header is not properly 64-bit aligned
6061 /// or because it is truncated), it returns a [`LoadError`].
6162 /// If there is no header, it returns `None`.
6263 pub fn find_header ( buffer : & [ u8 ] ) -> Result < Option < ( & [ u8 ] , u32 ) > , LoadError > {
63- // the magic is 32 bit aligned and inside the first 8192 bytes
64- assert ! ( buffer. len( ) >= 8192 ) ;
64+ if buffer. as_ptr ( ) . align_offset ( 4 ) != 0 {
65+ return Err ( LoadError :: InvalidAddress ) ;
66+ }
67+
6568 let mut windows = buffer[ 0 ..8192 ] . windows ( 4 ) ;
6669 let magic_index = match windows. position ( |vals| {
6770 u32:: from_le_bytes ( vals. try_into ( ) . unwrap ( ) ) // yes, there's 4 bytes here
68- == MULTIBOOT2_HEADER_MAGIC
71+ == MAGIC
6972 } ) {
7073 Some ( idx) => {
7174 if idx % 8 == 0 {
@@ -102,27 +105,27 @@ impl<'a> Multiboot2Header<'a> {
102105
103106 /// Wrapper around [`Multiboot2BasicHeader::verify_checksum`].
104107 pub const fn verify_checksum ( & self ) -> bool {
105- self . inner . verify_checksum ( )
108+ self . 0 . verify_checksum ( )
106109 }
107110 /// Wrapper around [`Multiboot2BasicHeader::header_magic`].
108111 pub const fn header_magic ( & self ) -> u32 {
109- self . inner . header_magic ( )
112+ self . 0 . header_magic ( )
110113 }
111114 /// Wrapper around [`Multiboot2BasicHeader::arch`].
112115 pub const fn arch ( & self ) -> HeaderTagISA {
113- self . inner . arch ( )
116+ self . 0 . arch ( )
114117 }
115118 /// Wrapper around [`Multiboot2BasicHeader::length`].
116119 pub const fn length ( & self ) -> u32 {
117- self . inner . length ( )
120+ self . 0 . length ( )
118121 }
119122 /// Wrapper around [`Multiboot2BasicHeader::checksum`].
120123 pub const fn checksum ( & self ) -> u32 {
121- self . inner . checksum ( )
124+ self . 0 . checksum ( )
122125 }
123126 /// Wrapper around [`Multiboot2BasicHeader::tag_iter`].
124127 pub fn iter ( & self ) -> Multiboot2HeaderTagIter {
125- self . inner . tag_iter ( )
128+ self . 0 . tag_iter ( )
126129 }
127130 /// Wrapper around [`Multiboot2BasicHeader::calc_checksum`].
128131 pub const fn calc_checksum ( magic : u32 , arch : HeaderTagISA , length : u32 ) -> u32 {
@@ -190,14 +193,6 @@ impl<'a> Multiboot2Header<'a> {
190193 }
191194}
192195
193- impl < ' a > Debug for Multiboot2Header < ' a > {
194- fn fmt ( & self , f : & mut Formatter < ' _ > ) -> core:: fmt:: Result {
195- // For debug fmt we only output the inner field
196- let reference = unsafe { & * ( self . inner as * const Multiboot2BasicHeader ) } ;
197- Debug :: fmt ( reference, f)
198- }
199- }
200-
201196/// Errors that can occur when parsing a header from a slice.
202197/// See [`Multiboot2Header::find_header`].
203198#[ derive( Copy , Clone , Debug , derive_more:: Display , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
@@ -215,28 +210,25 @@ pub enum LoadError {
215210#[ cfg( feature = "unstable" ) ]
216211impl core:: error:: Error for LoadError { }
217212
218- /// **Use this only if you know what you do. You probably want to use
219- /// [`Multiboot2Header`] instead.**
220- ///
221213/// The "basic" Multiboot2 header. This means only the properties, that are known during
222214/// compile time. All other information are derived during runtime from the size property.
223215#[ derive( Copy , Clone , PartialEq , Eq , PartialOrd , Ord , Hash ) ]
224216#[ repr( C ) ]
225217pub struct Multiboot2BasicHeader {
226- /// Must be the value of [`MULTIBOOT2_HEADER_MAGIC `].
218+ /// Must be the value of [`MAGIC `].
227219 header_magic : u32 ,
228220 arch : HeaderTagISA ,
229221 length : u32 ,
230222 checksum : u32 ,
231- // additional tags. .
232- // at minimum the end tag
223+ // Followed by dynamic amount of dynamically sized header tags.
224+ // At minimum, the end tag.
233225}
234226
235227impl Multiboot2BasicHeader {
236228 #[ cfg( feature = "builder" ) ]
237229 /// Constructor for the basic header.
238230 pub ( crate ) const fn new ( arch : HeaderTagISA , length : u32 ) -> Self {
239- let magic = MULTIBOOT2_HEADER_MAGIC ;
231+ let magic = MAGIC ;
240232 let checksum = Self :: calc_checksum ( magic, arch, length) ;
241233 Multiboot2BasicHeader {
242234 header_magic : magic,
@@ -257,7 +249,6 @@ impl Multiboot2BasicHeader {
257249 ( 0x100000000 - magic as u64 - arch as u64 - length as u64 ) as u32
258250 }
259251
260- /// Returns
261252 pub const fn header_magic ( & self ) -> u32 {
262253 self . header_magic
263254 }
0 commit comments