Skip to main content

multiboot2_header/
tags.rs

1//! Definition for all types of "Multiboot2 header tags". The values are taken from the example C
2//! code at the end of the official Multiboot2 spec. These tags follow in memory right after
3//! [`crate::Multiboot2BasicHeader`].
4
5use multiboot2_common::Header;
6
7/// ISA/ARCH in Multiboot2 header.
8#[repr(u32)]
9#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
10pub enum HeaderTagISA {
11    /// Spec: "means 32-bit (protected) mode of i386".
12    /// Caution: This is confusing. If you use the EFI64-tag
13    /// on an UEFI system, the machine will boot into `64-bit long mode`.
14    /// Therefore this tag should be understood as "arch=x86|x86_64".
15    I386 = 0,
16    /// 32-bit MIPS
17    MIPS32 = 4,
18}
19
20/// Possible types for header tags of a Multiboot2 header.
21///
22/// The names and values are taken from the example C code at the bottom of the
23/// Multiboot2 specification. This value stands in the `typ` property of
24/// [`HeaderTagHeader`].
25#[repr(u16)]
26#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
27pub enum HeaderTagType {
28    /// Type for [`crate::EndHeaderTag`].
29    End = 0,
30    /// Type for [`crate::InformationRequestHeaderTag`].
31    InformationRequest = 1,
32    /// Type for [`crate::AddressHeaderTag`].
33    Address = 2,
34    /// Type for [`crate::EntryAddressHeaderTag`].
35    EntryAddress = 3,
36    /// Type for [`crate::ConsoleHeaderTag`].
37    ConsoleFlags = 4,
38    /// Type for [`crate::FramebufferHeaderTag`].
39    Framebuffer = 5,
40    /// Type for [`crate::ModuleAlignHeaderTag`].
41    ModuleAlign = 6,
42    /// Type for [`crate::EfiBootServiceHeaderTag`].
43    EfiBS = 7,
44    /// Type for [`crate::EntryEfi32HeaderTag`].
45    EntryAddressEFI32 = 8,
46    /// Type for [`crate::EntryEfi64HeaderTag`].
47    EntryAddressEFI64 = 9,
48    /// Type for [`crate::RelocatableHeaderTag`].
49    Relocatable = 10,
50}
51
52impl HeaderTagType {
53    /// Returns the number of possible variants.
54    #[must_use]
55    pub const fn count() -> u32 {
56        11
57    }
58}
59
60/// Flags for Multiboot2 header tags.
61#[repr(u16)]
62#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
63pub enum HeaderTagFlag {
64    /// Bootloader must provide this tag. If this is not possible, the
65    /// bootloader will fail loading the kernel.
66    Required = 0,
67    /// Bootloader should provide the tag if possible.
68    Optional = 1,
69}
70
71/// The common header that all header tags share. Specific tags may have
72/// additional fields that depend on the `typ` and the `size` field.
73#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
74#[repr(C, align(8))]
75pub struct HeaderTagHeader {
76    typ: HeaderTagType,   /* u16 */
77    flags: HeaderTagFlag, /* u16 */
78    size: u32,
79    // Followed by optional additional tag-specific fields.
80}
81
82impl HeaderTagHeader {
83    /// Creates a new header.
84    #[must_use]
85    pub const fn new(typ: HeaderTagType, flags: HeaderTagFlag, size: u32) -> Self {
86        Self { typ, flags, size }
87    }
88
89    /// Returns the [`HeaderTagType`].
90    #[must_use]
91    pub const fn typ(&self) -> HeaderTagType {
92        self.typ
93    }
94
95    /// Returns the [`HeaderTagFlag`]s.
96    #[must_use]
97    pub const fn flags(&self) -> HeaderTagFlag {
98        self.flags
99    }
100
101    /// Returns the size.
102    #[must_use]
103    pub const fn size(&self) -> u32 {
104        self.size
105    }
106}
107
108impl Header for HeaderTagHeader {
109    fn total_size(&self) -> usize {
110        self.size as usize
111    }
112
113    fn set_size(&mut self, total_size: usize) {
114        self.size = total_size as u32;
115    }
116}
117
118#[cfg(test)]
119mod tests {
120    use crate::HeaderTagHeader;
121
122    #[test]
123    fn test_assert_size() {
124        assert_eq!(size_of::<HeaderTagHeader>(), 2 + 2 + 4);
125    }
126}