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}