Skip to content

Commit 4c05ff3

Browse files
committed
multiboot2: add BootdevTag
1 parent 9a654c4 commit 4c05ff3

File tree

4 files changed

+81
-4
lines changed

4 files changed

+81
-4
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

+63
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
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+
pub fn new(biosdev: u32, slice: u32, part: u32) -> Self {
20+
Self {
21+
header: TagHeader::new(TagType::Apm, mem::size_of::<Self>() as u32),
22+
biosdev,
23+
slice,
24+
part,
25+
}
26+
}
27+
28+
/// Returns the bios device from which the device was booted from.
29+
/// `0x00` represents the first floppy disk.
30+
/// `0x80` represents the first hard disk, 0x81 the second hard disk, and
31+
/// so on.
32+
pub fn biosdev(&self) -> u32 {
33+
self.biosdev
34+
}
35+
36+
/// The slice field identifies the partition (also known as a "slice" in BSD
37+
/// terminology) on the BIOS device from which the operating system was
38+
/// booted.
39+
pub fn slice(&self) -> u32 {
40+
self.slice
41+
}
42+
43+
/// The part field denotes the subpartition or logical partition within the
44+
/// primary partition (if applicable) from which the operating system was
45+
/// booted.
46+
pub fn part(&self) -> u32 {
47+
self.part
48+
}
49+
}
50+
51+
impl MaybeDynSized for BootdevTag {
52+
type Header = TagHeader;
53+
54+
const BASE_SIZE: usize = mem::size_of::<Self>();
55+
56+
fn dst_len(_: &TagHeader) {}
57+
}
58+
59+
impl Tag for BootdevTag {
60+
type IDType = TagType;
61+
62+
const ID: TagType = TagType::Bootdev;
63+
}

multiboot2/src/builder.rs

+16-4
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 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 {
@@ -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

+1
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;

0 commit comments

Comments
 (0)