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}