Skip to content

Commit 3d1fdf7

Browse files
committed
multiboot2: add BootdevTag
1 parent 17e48f8 commit 3d1fdf7

File tree

4 files changed

+87
-5
lines changed

4 files changed

+87
-5
lines changed

multiboot2/CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
- **Breaking:** MSRV is now 1.75
77
- Added missing tags:
88
- `ApmTag`
9+
- `BootdevTag`
910

1011
## v0.22.2 (2024-08-24)
1112

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

+17-5
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
//! Module for [`Builder`].
22
33
use crate::apm::ApmTag;
4+
use crate::bootdev::BootdevTag;
45
use crate::{
56
BasicMemoryInfoTag, BootInformationHeader, BootLoaderNameTag, CommandLineTag,
67
EFIBootServicesNotExitedTag, EFIImageHandle32Tag, EFIImageHandle64Tag, EFIMemoryMapTag,
@@ -19,7 +20,7 @@ pub struct Builder {
1920
bootloader: Option<Box<BootLoaderNameTag>>,
2021
modules: Vec<Box<ModuleTag>>,
2122
meminfo: Option<BasicMemoryInfoTag>,
22-
// missing bootdev: Option<BootDevice>
23+
bootdev: Option<BootdevTag>,
2324
mmap: Option<Box<MemoryMapTag>>,
2425
vbe: Option<VBEInfoTag>,
2526
framebuffer: Option<Box<FramebufferTag>>,
@@ -54,6 +55,7 @@ impl Builder {
5455
bootloader: None,
5556
modules: vec![],
5657
meminfo: None,
58+
bootdev: None,
5759
mmap: None,
5860
vbe: None,
5961
framebuffer: None,
@@ -101,6 +103,13 @@ impl Builder {
101103
self
102104
}
103105

106+
/// Sets the [`BootdevTag`] tag.
107+
#[must_use]
108+
pub const fn bootdev(mut self, bootdev: BootdevTag) -> Self {
109+
self.bootdev = Some(bootdev);
110+
self
111+
}
112+
104113
/// Sets the [`MemoryMapTag`] tag.
105114
#[must_use]
106115
pub fn mmap(mut self, mmap: Box<MemoryMapTag>) -> Self {
@@ -131,7 +140,7 @@ impl Builder {
131140

132141
/// Sets the [`ApmTag`] tag.
133142
#[must_use]
134-
pub fn apm(mut self, apm: ApmTag) -> Self {
143+
pub const fn apm(mut self, apm: ApmTag) -> Self {
135144
self.apm = Some(apm);
136145
self
137146
}
@@ -223,9 +232,6 @@ impl Builder {
223232
pub fn build(self) -> Box<DynSizedStructure<BootInformationHeader>> {
224233
let header = BootInformationHeader::new(0);
225234
let mut byte_refs = Vec::new();
226-
if let Some(tag) = self.apm.as_ref() {
227-
byte_refs.push(tag.as_bytes().as_ref());
228-
}
229235
if let Some(tag) = self.cmdline.as_ref() {
230236
byte_refs.push(tag.as_bytes().as_ref());
231237
}
@@ -238,6 +244,9 @@ impl Builder {
238244
if let Some(tag) = self.meminfo.as_ref() {
239245
byte_refs.push(tag.as_bytes().as_ref());
240246
}
247+
if let Some(tag) = self.bootdev.as_ref() {
248+
byte_refs.push(tag.as_bytes().as_ref());
249+
}
241250
if let Some(tag) = self.mmap.as_ref() {
242251
byte_refs.push(tag.as_bytes().as_ref());
243252
}
@@ -308,6 +317,7 @@ mod tests {
308317
.add_module(ModuleTag::new(0x1000, 0x2000, "module 1"))
309318
.add_module(ModuleTag::new(0x3000, 0x4000, "module 2"))
310319
.meminfo(BasicMemoryInfoTag::new(0x4000, 0x5000))
320+
.bootdev(BootdevTag::new(0x00, 0x00, 0x00))
311321
.mmap(MemoryMapTag::new(&[MemoryArea::new(
312322
0x1000000,
313323
0x1000,
@@ -331,6 +341,7 @@ mod tests {
331341
FramebufferType::Text,
332342
))
333343
.elf_sections(ElfSectionsTag::new(0, 32, 0, &[]))
344+
.apm(ApmTag::new(0, 0, 0, 0, 0, 0, 0, 0, 0))
334345
.efi32(EFISdt32Tag::new(0x1000))
335346
.efi64(EFISdt64Tag::new(0x1000))
336347
.add_smbios(SmbiosTag::new(0, 0, &[1, 2, 3]))
@@ -341,6 +352,7 @@ mod tests {
341352
MemoryDescriptor::default(),
342353
MemoryDescriptor::default(),
343354
]))
355+
.network(NetworkTag::new(&[0; 1500]))
344356
.efi_bs(EFIBootServicesNotExitedTag::new())
345357
.efi32_ih(EFIImageHandle32Tag::new(0x1000))
346358
.efi64_ih(EFIImageHandle64Tag::new(0x1000))

multiboot2/src/lib.rs

+2
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,7 @@ pub type GenericInfoTag = multiboot2_common::DynSizedStructure<TagHeader>;
6969
mod apm;
7070
mod boot_information;
7171
mod boot_loader_name;
72+
mod bootdev;
7273
mod command_line;
7374
mod efi;
7475
mod elf_sections;
@@ -89,6 +90,7 @@ pub use multiboot2_common::{DynSizedStructure, MaybeDynSized, Tag};
8990
pub use apm::ApmTag;
9091
pub use boot_information::{BootInformation, BootInformationHeader, LoadError};
9192
pub use boot_loader_name::BootLoaderNameTag;
93+
pub use bootdev::BootdevTag;
9294
#[cfg(feature = "builder")]
9395
pub use builder::Builder;
9496
pub use command_line::CommandLineTag;

0 commit comments

Comments
 (0)