Skip to content

Commit 2395918

Browse files
authored
Merge pull request #229 from rust-osdev/tags
multiboot2: add missing tags
2 parents 7694432 + b14070d commit 2395918

File tree

7 files changed

+288
-8
lines changed

7 files changed

+288
-8
lines changed

multiboot2/CHANGELOG.md

+4
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,10 @@
44

55
- dependency updates
66
- **Breaking:** MSRV is now 1.75
7+
- Added missing tags:
8+
- `ApmTag`
9+
- `BootdevTag`
10+
- `NetworkTag`
711

812
## v0.22.2 (2024-08-24)
913

multiboot2/src/apm.rs

+126
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,126 @@
1+
//! Module for [`ApmTag`].
2+
3+
use crate::{TagHeader, TagType};
4+
use core::mem;
5+
use multiboot2_common::{MaybeDynSized, Tag};
6+
7+
/// The Advanced Power Management (APM) tag.
8+
#[derive(Debug)]
9+
#[repr(C, align(8))]
10+
pub struct ApmTag {
11+
header: TagHeader,
12+
version: u16,
13+
cseg: u16,
14+
offset: u32,
15+
cset_16: u16,
16+
dseg: u16,
17+
flags: u16,
18+
cseg_len: u16,
19+
cseg_16_len: u16,
20+
dseg_len: u16,
21+
}
22+
23+
impl ApmTag {
24+
/// Creates a new tag.
25+
#[allow(clippy::too_many_arguments)]
26+
#[must_use]
27+
pub fn new(
28+
version: u16,
29+
cseg: u16,
30+
offset: u32,
31+
cset_16: u16,
32+
dset: u16,
33+
flags: u16,
34+
cseg_len: u16,
35+
cseg_16_len: u16,
36+
dseg_len: u16,
37+
) -> Self {
38+
Self {
39+
header: TagHeader::new(TagType::Apm, mem::size_of::<Self>() as u32),
40+
version,
41+
cseg,
42+
offset,
43+
cset_16,
44+
dseg: dset,
45+
flags,
46+
cseg_len,
47+
cseg_16_len,
48+
dseg_len,
49+
}
50+
}
51+
52+
/// The version number of the APM BIOS.
53+
#[must_use]
54+
pub const fn version(&self) -> u16 {
55+
self.version
56+
}
57+
58+
/// Contains the 16-bit code segment (CS) address for the APM entry point.
59+
#[must_use]
60+
pub const fn cseg(&self) -> u16 {
61+
self.cseg
62+
}
63+
64+
/// Represents the offset address within the code segment (`cseg`) for the
65+
/// APM entry point.
66+
#[must_use]
67+
pub const fn offset(&self) -> u32 {
68+
self.offset
69+
}
70+
71+
/// Contains the 16-bit code segment (CS) address used for 16-bit protected
72+
/// mode APM functions.
73+
#[must_use]
74+
pub const fn cset_16(&self) -> u16 {
75+
self.cset_16
76+
}
77+
78+
/// Holds the 16-bit data segment (DS) address used by the APM BIOS for
79+
/// data operations.
80+
#[must_use]
81+
pub const fn dseg(&self) -> u16 {
82+
self.dseg
83+
}
84+
85+
/// Indicates the status and characteristics of the APM connection, such as
86+
/// if APM is present and its capabilities.
87+
#[must_use]
88+
pub const fn flags(&self) -> u16 {
89+
self.flags
90+
}
91+
92+
/// Indicates the length, in bytes, of the data segment (`dseg`) used by
93+
/// the APM BIOS
94+
#[must_use]
95+
pub const fn cseg_len(&self) -> u16 {
96+
self.cseg_len
97+
}
98+
99+
/// Provides the length, in bytes, of the 16-bit code segment (`cseg_16`)
100+
/// used for APM functions.
101+
#[must_use]
102+
pub const fn cseg_16_len(&self) -> u16 {
103+
self.cseg_16_len
104+
}
105+
106+
/// Indicates the length, in bytes, of the data segment (`dseg`) used by
107+
/// the APM BIOS.
108+
#[must_use]
109+
pub const fn dseg_len(&self) -> u16 {
110+
self.dseg_len
111+
}
112+
}
113+
114+
impl MaybeDynSized for ApmTag {
115+
type Header = TagHeader;
116+
117+
const BASE_SIZE: usize = mem::size_of::<Self>();
118+
119+
fn dst_len(_: &TagHeader) {}
120+
}
121+
122+
impl Tag for ApmTag {
123+
type IDType = TagType;
124+
125+
const ID: TagType = TagType::Apm;
126+
}

multiboot2/src/bootdev.rs

+67
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
//! Module for [`BootdevTag`].
2+
3+
use crate::{TagHeader, TagType};
4+
use core::mem;
5+
use multiboot2_common::{MaybeDynSized, Tag};
6+
7+
/// The end tag ends the information struct.
8+
#[derive(Debug)]
9+
#[repr(C, align(8))]
10+
pub struct BootdevTag {
11+
header: TagHeader,
12+
biosdev: u32,
13+
slice: u32,
14+
part: u32,
15+
}
16+
17+
impl BootdevTag {
18+
/// Creates a new tag.
19+
#[must_use]
20+
pub fn new(biosdev: u32, slice: u32, part: u32) -> Self {
21+
Self {
22+
header: TagHeader::new(TagType::Apm, mem::size_of::<Self>() as u32),
23+
biosdev,
24+
slice,
25+
part,
26+
}
27+
}
28+
29+
/// Returns the bios device from which the device was booted from.
30+
/// `0x00` represents the first floppy disk.
31+
/// `0x80` represents the first hard disk, 0x81 the second hard disk, and
32+
/// so on.
33+
#[must_use]
34+
pub const fn biosdev(&self) -> u32 {
35+
self.biosdev
36+
}
37+
38+
/// The slice field identifies the partition (also known as a "slice" in BSD
39+
/// terminology) on the BIOS device from which the operating system was
40+
/// booted.
41+
#[must_use]
42+
pub const fn slice(&self) -> u32 {
43+
self.slice
44+
}
45+
46+
/// The part field denotes the subpartition or logical partition within the
47+
/// primary partition (if applicable) from which the operating system was
48+
/// booted.
49+
#[must_use]
50+
pub const fn part(&self) -> u32 {
51+
self.part
52+
}
53+
}
54+
55+
impl MaybeDynSized for BootdevTag {
56+
type Header = TagHeader;
57+
58+
const BASE_SIZE: usize = mem::size_of::<Self>();
59+
60+
fn dst_len(_: &TagHeader) {}
61+
}
62+
63+
impl Tag for BootdevTag {
64+
type IDType = TagType;
65+
66+
const ID: TagType = TagType::Bootdev;
67+
}

multiboot2/src/builder.rs

+39-3
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
//! Module for [`Builder`].
22
3+
use crate::apm::ApmTag;
4+
use crate::bootdev::BootdevTag;
5+
use crate::network::NetworkTag;
36
use crate::{
47
BasicMemoryInfoTag, BootInformationHeader, BootLoaderNameTag, CommandLineTag,
58
EFIBootServicesNotExitedTag, EFIImageHandle32Tag, EFIImageHandle64Tag, EFIMemoryMapTag,
@@ -18,18 +21,18 @@ pub struct Builder {
1821
bootloader: Option<Box<BootLoaderNameTag>>,
1922
modules: Vec<Box<ModuleTag>>,
2023
meminfo: Option<BasicMemoryInfoTag>,
21-
// missing bootdev: Option<BootDevice>
24+
bootdev: Option<BootdevTag>,
2225
mmap: Option<Box<MemoryMapTag>>,
2326
vbe: Option<VBEInfoTag>,
2427
framebuffer: Option<Box<FramebufferTag>>,
2528
elf_sections: Option<Box<ElfSectionsTag>>,
26-
// missing apm:
29+
apm: Option<ApmTag>,
2730
efi32: Option<EFISdt32Tag>,
2831
efi64: Option<EFISdt64Tag>,
2932
smbios: Vec<Box<SmbiosTag>>,
3033
rsdpv1: Option<RsdpV1Tag>,
3134
rsdpv2: Option<RsdpV2Tag>,
32-
// missing: network
35+
network: Option<Box<NetworkTag>>,
3336
efi_mmap: Option<Box<EFIMemoryMapTag>>,
3437
efi_bs: Option<EFIBootServicesNotExitedTag>,
3538
efi32_ih: Option<EFIImageHandle32Tag>,
@@ -53,16 +56,19 @@ impl Builder {
5356
bootloader: None,
5457
modules: vec![],
5558
meminfo: None,
59+
bootdev: None,
5660
mmap: None,
5761
vbe: None,
5862
framebuffer: None,
5963
elf_sections: None,
64+
apm: None,
6065
efi32: None,
6166
efi64: None,
6267
smbios: vec![],
6368
rsdpv1: None,
6469
rsdpv2: None,
6570
efi_mmap: None,
71+
network: None,
6672
efi_bs: None,
6773
efi32_ih: None,
6874
efi64_ih: None,
@@ -99,6 +105,13 @@ impl Builder {
99105
self
100106
}
101107

108+
/// Sets the [`BootdevTag`] tag.
109+
#[must_use]
110+
pub const fn bootdev(mut self, bootdev: BootdevTag) -> Self {
111+
self.bootdev = Some(bootdev);
112+
self
113+
}
114+
102115
/// Sets the [`MemoryMapTag`] tag.
103116
#[must_use]
104117
pub fn mmap(mut self, mmap: Box<MemoryMapTag>) -> Self {
@@ -127,6 +140,13 @@ impl Builder {
127140
self
128141
}
129142

143+
/// Sets the [`ApmTag`] tag.
144+
#[must_use]
145+
pub const fn apm(mut self, apm: ApmTag) -> Self {
146+
self.apm = Some(apm);
147+
self
148+
}
149+
130150
/// Sets the [`EFISdt32Tag`] tag.
131151
#[must_use]
132152
pub const fn efi32(mut self, efi32: EFISdt32Tag) -> Self {
@@ -169,6 +189,13 @@ impl Builder {
169189
self
170190
}
171191

192+
/// Sets the [`NetworkTag`] tag.
193+
#[must_use]
194+
pub fn network(mut self, network: Box<NetworkTag>) -> Self {
195+
self.network = Some(network);
196+
self
197+
}
198+
172199
/// Sets the [`EFIBootServicesNotExitedTag`] tag.
173200
#[must_use]
174201
pub const fn efi_bs(mut self, efi_bs: EFIBootServicesNotExitedTag) -> Self {
@@ -226,6 +253,9 @@ impl Builder {
226253
if let Some(tag) = self.meminfo.as_ref() {
227254
byte_refs.push(tag.as_bytes().as_ref());
228255
}
256+
if let Some(tag) = self.bootdev.as_ref() {
257+
byte_refs.push(tag.as_bytes().as_ref());
258+
}
229259
if let Some(tag) = self.mmap.as_ref() {
230260
byte_refs.push(tag.as_bytes().as_ref());
231261
}
@@ -238,6 +268,9 @@ impl Builder {
238268
if let Some(tag) = self.elf_sections.as_ref() {
239269
byte_refs.push(tag.as_bytes().as_ref());
240270
}
271+
if let Some(tag) = self.apm.as_ref() {
272+
byte_refs.push(tag.as_bytes().as_ref());
273+
}
241274
if let Some(tag) = self.efi32.as_ref() {
242275
byte_refs.push(tag.as_bytes().as_ref());
243276
}
@@ -293,6 +326,7 @@ mod tests {
293326
.add_module(ModuleTag::new(0x1000, 0x2000, "module 1"))
294327
.add_module(ModuleTag::new(0x3000, 0x4000, "module 2"))
295328
.meminfo(BasicMemoryInfoTag::new(0x4000, 0x5000))
329+
.bootdev(BootdevTag::new(0x00, 0x00, 0x00))
296330
.mmap(MemoryMapTag::new(&[MemoryArea::new(
297331
0x1000000,
298332
0x1000,
@@ -316,6 +350,7 @@ mod tests {
316350
FramebufferType::Text,
317351
))
318352
.elf_sections(ElfSectionsTag::new(0, 32, 0, &[]))
353+
.apm(ApmTag::new(0, 0, 0, 0, 0, 0, 0, 0, 0))
319354
.efi32(EFISdt32Tag::new(0x1000))
320355
.efi64(EFISdt64Tag::new(0x1000))
321356
.add_smbios(SmbiosTag::new(0, 0, &[1, 2, 3]))
@@ -326,6 +361,7 @@ mod tests {
326361
MemoryDescriptor::default(),
327362
MemoryDescriptor::default(),
328363
]))
364+
.network(NetworkTag::new(&[0; 1500]))
329365
.efi_bs(EFIBootServicesNotExitedTag::new())
330366
.efi32_ih(EFIImageHandle32Tag::new(0x1000))
331367
.efi64_ih(EFIImageHandle64Tag::new(0x1000))

multiboot2/src/end.rs

+3-5
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,20 @@
11
//! Module for [`EndTag`].
22
3-
use crate::{TagHeader, TagType, TagTypeId};
3+
use crate::{TagHeader, TagType};
44
use core::mem;
55
use multiboot2_common::{MaybeDynSized, Tag};
66

77
/// The end tag ends the information struct.
88
#[derive(Debug)]
99
#[repr(C, align(8))]
1010
pub struct EndTag {
11-
typ: TagTypeId,
12-
size: u32,
11+
header: TagHeader,
1312
}
1413

1514
impl Default for EndTag {
1615
fn default() -> Self {
1716
Self {
18-
typ: TagType::End.into(),
19-
size: 8,
17+
header: TagHeader::new(TagType::End, mem::size_of::<Self>() as u32),
2018
}
2119
}
2220
}

0 commit comments

Comments
 (0)