Skip to main content

multiboot2_header/
tags.rs

1//! Definition for all types of "Multiboot2 header tags". These tags follow in
2//! memory right after [`crate::Multiboot2BasicHeader`].
3
4use multiboot2_common::Header;
5
6multiboot2_common::raw_type! {
7    /// ABI compatible representation of the ISA/ARCH of a Multiboot2 header.
8    ///
9    /// This type matches the binary representation (`u32`) and stands in the
10    /// `arch` property of [`crate::Multiboot2BasicHeader`].
11    pub struct HeaderTagISARaw(u32);
12
13    /// The ISA/ARCH a Multiboot2 image targets.
14    ///
15    /// This is a higher level abstraction for [`HeaderTagISARaw`].
16    pub enum HeaderTagISA {
17        /// Spec: "means 32-bit (protected) mode of i386".
18        /// Caution: This is confusing. If you use the EFI64-tag
19        /// on an UEFI system, the machine will boot into `64-bit long mode`.
20        /// Therefore this tag should be understood as "arch=x86|x86_64".
21        I386 = 0,
22        /// 32-bit MIPS
23        MIPS32 = 4,
24    }
25}
26
27multiboot2_common::raw_type! {
28    /// ABI compatible representation of the type of a Multiboot2 header tag.
29    ///
30    /// This type matches the binary representation (`u16`) and stands in the
31    /// `typ` property of [`HeaderTagHeader`].
32    pub struct HeaderTagTypeRaw(u16);
33
34    /// The type of a Multiboot2 header tag.
35    ///
36    /// This is a higher level abstraction for [`HeaderTagTypeRaw`].
37    pub enum HeaderTagType {
38        /// Type for [`crate::EndHeaderTag`].
39        End = 0,
40        /// Type for [`crate::InformationRequestHeaderTag`].
41        InformationRequest = 1,
42        /// Type for [`crate::AddressHeaderTag`].
43        Address = 2,
44        /// Type for [`crate::EntryAddressHeaderTag`].
45        EntryAddress = 3,
46        /// Type for [`crate::ConsoleHeaderTag`].
47        ConsoleFlags = 4,
48        /// Type for [`crate::FramebufferHeaderTag`].
49        Framebuffer = 5,
50        /// Type for [`crate::ModuleAlignHeaderTag`].
51        ModuleAlign = 6,
52        /// Type for [`crate::EfiBootServiceHeaderTag`].
53        EfiBS = 7,
54        /// Type for [`crate::EntryEfi32HeaderTag`].
55        EntryAddressEFI32 = 8,
56        /// Type for [`crate::EntryEfi64HeaderTag`].
57        EntryAddressEFI64 = 9,
58        /// Type for [`crate::RelocatableHeaderTag`].
59        Relocatable = 10,
60    }
61}
62
63multiboot2_common::raw_type! {
64    /// ABI compatible representation of the flags of a Multiboot2 header
65    /// tag.
66    ///
67    /// This type matches the binary representation (`u16`) and stands in the
68    /// `flags` property of [`HeaderTagHeader`].
69    pub struct HeaderTagFlagRaw(u16);
70
71    /// Flags of a Multiboot2 header tag.
72    ///
73    /// These flags tell whether a tag is required or optional for the
74    /// bootloader.
75    ///
76    /// This is a higher level abstraction for [`HeaderTagFlagRaw`].
77    pub enum HeaderTagFlag {
78        /// The bootloader must provide this tag. If this is not possible, the
79        /// bootloader will fail to load the kernel.
80        Required = 0,
81        /// The bootloader should provide the tag if possible.
82        Optional = 1,
83    }
84}
85
86/// The common header that all header tags share. Specific tags may have
87/// additional fields that depend on the `typ` and the `size` field.
88#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
89#[repr(C, align(8))]
90pub struct HeaderTagHeader {
91    typ: HeaderTagTypeRaw,   /* u16 */
92    flags: HeaderTagFlagRaw, /* u16 */
93    size: u32,
94    // Followed by optional additional tag-specific fields.
95}
96
97const _: () = assert!(size_of::<HeaderTagHeader>() == 2 + 2 + 4);
98
99impl HeaderTagHeader {
100    /// Creates a new header.
101    #[must_use]
102    pub const fn new(typ: HeaderTagType, flags: HeaderTagFlag, size: u32) -> Self {
103        Self {
104            typ: HeaderTagTypeRaw::new(typ.val()),
105            flags: HeaderTagFlagRaw::new(flags.val()),
106            size,
107        }
108    }
109
110    /// Returns the [`HeaderTagType`].
111    #[must_use]
112    pub const fn typ(&self) -> HeaderTagType {
113        HeaderTagType::from_val(self.typ.get())
114    }
115
116    /// Returns the [`HeaderTagFlag`]s.
117    #[must_use]
118    pub const fn flags(&self) -> HeaderTagFlag {
119        HeaderTagFlag::from_val(self.flags.get())
120    }
121
122    /// Returns the size.
123    #[must_use]
124    pub const fn size(&self) -> u32 {
125        self.size
126    }
127}
128
129// SAFETY: The header is a padding-free repr(C) struct of raw integers, and
130// any bit pattern is valid for it.
131unsafe impl Header for HeaderTagHeader {
132    fn total_size(&self) -> usize {
133        self.size as usize
134    }
135
136    fn set_size(&mut self, total_size: usize) {
137        self.size = total_size as u32;
138    }
139}