Skip to content

Commit 8adc3e0

Browse files
authored
Merge pull request #99 from rust-osdev/mb2-ord-for-tag-type
multiboot2: `Ord` for `TagType`
2 parents 04670f2 + 3fe45b1 commit 8adc3e0

10 files changed

+58
-44
lines changed

multiboot2/Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ Multiboot2-compliant bootloaders, like GRUB. It supports all tags from the speci
66
including full support for the sections of ELF-64. This library is `no_std` and can be
77
used in a Multiboot2-kernel.
88
"""
9-
version = "0.13.1"
9+
version = "0.13.2"
1010
authors = [
1111
"Philipp Oppermann <[email protected]>",
1212
"Calvin Lee <[email protected]>",

multiboot2/Changelog.md

+4
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
# CHANGELOG for crate `multiboot2`
22

3+
## 0.13.2
4+
- `TagType` now implements `Ord` so that it can be used in `BTreeSet`
5+
- small internal improvements and restructuring of the code (no breaking changes to public API)
6+
37
## 0.13.1
48
- minor fix
59

multiboot2/src/boot_loader_name.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::TagType;
22

3-
/// This Tag contains the name of the bootloader that is booting the kernel.
3+
/// This tag contains the name of the bootloader that is booting the kernel.
44
///
55
/// The name is a normal C-style UTF-8 zero-terminated string that can be
66
/// obtained via the `name` method.

multiboot2/src/command_line.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
use crate::TagType;
22

3-
/// This Tag contains the command line string.
3+
/// This tag contains the command line string.
44
///
55
/// The string is a normal C-style UTF-8 zero-terminated string that can be
66
/// obtained via the `command_line` method.

multiboot2/src/elf_sections.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::header::Tag;
1+
use crate::tag_type::Tag;
22
use core::fmt::{Debug, Formatter};
33

44
/// This tag contains section header table from an ELF kernel.

multiboot2/src/framebuffer.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::header::Tag;
1+
use crate::tag_type::Tag;
22
use crate::Reader;
33
use core::slice;
44

multiboot2/src/lib.rs

+12-4
Original file line numberDiff line numberDiff line change
@@ -45,16 +45,15 @@ pub use elf_sections::{
4545
ElfSection, ElfSectionFlags, ElfSectionIter, ElfSectionType, ElfSectionsTag,
4646
};
4747
pub use framebuffer::{FramebufferColor, FramebufferField, FramebufferTag, FramebufferType};
48-
pub use header::TagType;
49-
pub use header::MULTIBOOT2_BOOTLOADER_MAGIC;
50-
use header::{Tag, TagIter};
5148
pub use image_load_addr::ImageLoadPhysAddr;
5249
pub use memory_map::{
5350
EFIMemoryAreaType, EFIMemoryDesc, EFIMemoryMapTag, MemoryArea, MemoryAreaIter, MemoryAreaType,
5451
MemoryMapTag,
5552
};
5653
pub use module::{ModuleIter, ModuleTag};
5754
pub use rsdp::{RsdpV1Tag, RsdpV2Tag};
55+
pub use tag_type::TagType;
56+
use tag_type::{Tag, TagIter};
5857
pub use vbe_info::{
5958
VBECapabilities, VBEControlInfo, VBEDirectColorAttributes, VBEField, VBEInfoTag,
6059
VBEMemoryModel, VBEModeAttributes, VBEModeInfo, VBEWindowAttributes,
@@ -68,13 +67,22 @@ mod command_line;
6867
mod efi;
6968
mod elf_sections;
7069
mod framebuffer;
71-
mod header;
7270
mod image_load_addr;
7371
mod memory_map;
7472
mod module;
7573
mod rsdp;
74+
mod tag_type;
7675
mod vbe_info;
7776

77+
/// Magic number that a multiboot2-compliant boot loader will store in `eax` register
78+
/// right before handoff to the payload (the kernel). This value can be used to check,
79+
/// that the kernel was indeed booted via multiboot2.
80+
///
81+
/// Caution: You might need some assembly code (e.g. GAS or NASM) first, which
82+
/// moves `eax` to another register, like `edi`. Otherwise it probably happens,
83+
/// that the Rust compiler output changes `eax` before you can access it.
84+
pub const MULTIBOOT2_BOOTLOADER_MAGIC: u32 = 0x36d76289;
85+
7886
/// Load the multiboot boot information struct from an address.
7987
///
8088
/// This is the same as `load_with_offset` but the offset is omitted and set

multiboot2/src/memory_map.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
use crate::TagType;
22
use core::marker::PhantomData;
33

4-
/// This Tag provides an initial host memory map.
4+
/// This tag provides an initial host memory map.
55
///
66
/// The map provided is guaranteed to list all standard RAM that should be
77
/// available for normal use. This type however includes the regions occupied

multiboot2/src/module.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use crate::header::{Tag, TagIter, TagType};
1+
use crate::tag_type::{Tag, TagIter, TagType};
22
use core::fmt::{Debug, Formatter};
33

44
/// This tag indicates to the kernel what boot module was loaded along with

multiboot2/src/header.rs multiboot2/src/tag_type.rs

+35-33
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,14 @@
1+
//! Module for [`TagType`].
2+
13
use core::fmt::{Debug, Formatter};
2-
use core::hash::{Hash, Hasher};
4+
use core::hash::Hash;
35
use core::marker::PhantomData;
46

5-
/// Magic number that a multiboot2-compliant boot loader will store in `eax` register
6-
/// right before handoff to the payload (the kernel). This value can be used to check,
7-
/// that the kernel was indeed booted via multiboot2.
8-
///
9-
/// Caution: You might need some assembly code (e.g. GAS or NASM) first, which
10-
/// moves `eax` to another register, like `edi`. Otherwise it probably happens,
11-
/// that the Rust compiler output changes `eax` before you can access it.
12-
pub const MULTIBOOT2_BOOTLOADER_MAGIC: u32 = 0x36d76289;
13-
147
/// Possible types of a Tag in the Multiboot2 Information Structure (MBI), therefore the value
158
/// of the the `typ` property. The names and values are taken from the example C code
169
/// at the bottom of the Multiboot2 specification.
1710
#[repr(u32)]
18-
#[derive(Copy, Clone, Debug, Eq)]
11+
#[derive(Copy, Clone, Debug, Eq, Ord, PartialOrd, PartialEq, Hash)]
1912
pub enum TagType {
2013
/// Marks the end of the tags.
2114
End = 0,
@@ -110,19 +103,6 @@ impl PartialEq<TagType> for u32 {
110103
}
111104
}
112105

113-
impl PartialEq<TagType> for TagType {
114-
fn eq(&self, other: &TagType) -> bool {
115-
*self as u32 == *other as u32
116-
}
117-
}
118-
119-
// impl required because this type is used in a hashmap in `multiboot2-header`
120-
impl Hash for TagType {
121-
fn hash<H: Hasher>(&self, state: &mut H) {
122-
state.write_u32(*self as u32);
123-
}
124-
}
125-
126106
/// All tags that could passed via the Multiboot2 information structure to a payload/program/kernel.
127107
/// Better not confuse this with the Multiboot2 header tags. They are something different.
128108
#[derive(Clone, Copy)]
@@ -185,14 +165,36 @@ mod tests {
185165
use super::*;
186166

187167
#[test]
188-
fn test_hash() {
189-
let mut hashset = std::collections::HashSet::new();
190-
hashset.insert(TagType::Cmdline);
191-
hashset.insert(TagType::ElfSections);
192-
hashset.insert(TagType::BootLoaderName);
193-
hashset.insert(TagType::LoadBaseAddr);
194-
hashset.insert(TagType::LoadBaseAddr);
195-
assert_eq!(hashset.len(), 4);
196-
println!("{:#?}", hashset);
168+
fn test_hashset() {
169+
let mut set = std::collections::HashSet::new();
170+
set.insert(TagType::Cmdline);
171+
set.insert(TagType::ElfSections);
172+
set.insert(TagType::BootLoaderName);
173+
set.insert(TagType::LoadBaseAddr);
174+
set.insert(TagType::LoadBaseAddr);
175+
assert_eq!(set.len(), 4);
176+
println!("{:#?}", set);
177+
}
178+
179+
#[test]
180+
fn test_btreeset() {
181+
let mut set = std::collections::BTreeSet::new();
182+
set.insert(TagType::Cmdline);
183+
set.insert(TagType::ElfSections);
184+
set.insert(TagType::BootLoaderName);
185+
set.insert(TagType::LoadBaseAddr);
186+
set.insert(TagType::LoadBaseAddr);
187+
assert_eq!(set.len(), 4);
188+
for (current, next) in set.iter().zip(set.iter().skip(1)) {
189+
assert!(current < next);
190+
}
191+
println!("{:#?}", set);
192+
}
193+
194+
/// Tests for equality when one type is u32 and the other the enum representation.
195+
#[test]
196+
fn test_partial_eq_u32() {
197+
assert_eq!(21, TagType::LoadBaseAddr);
198+
assert_eq!(TagType::LoadBaseAddr, 21);
197199
}
198200
}

0 commit comments

Comments
 (0)