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}