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