Skip to content

Commit 07e9a25

Browse files
committed
multiboot2: expose get_tag publicly to allow custom tags
1 parent 39435b8 commit 07e9a25

File tree

3 files changed

+39
-4
lines changed

3 files changed

+39
-4
lines changed

multiboot2/src/lib.rs

Lines changed: 37 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,8 @@ pub use memory_map::{
5555
};
5656
pub use module::{ModuleIter, ModuleTag};
5757
pub use rsdp::{RsdpV1Tag, RsdpV2Tag};
58-
pub use tag_type::{Tag, TagType, TagTypeId};
5958
use tag_type::TagIter;
59+
pub use tag_type::{Tag, TagType, TagTypeId};
6060
pub use vbe_info::{
6161
VBECapabilities, VBEControlInfo, VBEDirectColorAttributes, VBEField, VBEInfoTag,
6262
VBEMemoryModel, VBEModeAttributes, VBEModeInfo, VBEWindowAttributes,
@@ -319,7 +319,42 @@ impl BootInformation {
319319
unsafe { &*self.inner }
320320
}
321321

322-
fn get_tag(&self, typ: TagType) -> Option<&Tag> {
322+
/// Public getter to find any Multiboot tag by its type, including
323+
/// specified and custom ones.
324+
///
325+
/// # Specified or Custom Tags
326+
/// The Multiboot2 specification specifies a list of tags, see [`TagType`].
327+
/// However, it doesn't forbid to use custom tags. Because of this, there
328+
/// exists the [`TagType`] abstraction. It is recommended to use this
329+
/// getter only for custom tags. For specified tags, use getters, such as
330+
/// [`Self::efi_64_ih`].
331+
///
332+
/// ## Use Custom Tags
333+
/// The following example shows how you may use this interface to parse custom tags from
334+
/// the MBI.
335+
///
336+
/// ```ignore
337+
/// use multiboot2::TagTypeId;
338+
/// #[repr(C, align(8))]
339+
/// struct CustomTag {
340+
/// // new type from the lib: has repr(u32)
341+
/// tag: TagTypeId,
342+
/// size: u32,
343+
/// // begin of inline string
344+
/// name: u8,
345+
/// }
346+
///
347+
/// let tag = bi
348+
/// // this function is now public!
349+
/// .get_tag(0x1337.into())
350+
/// .unwrap()
351+
/// // type definition from end user; must be `Sized`!
352+
/// .cast_tag::<CustomTag>();
353+
/// let name = &tag.name as *const u8 as *const c_char;
354+
/// let str = unsafe { CStr::from_ptr(name).to_str().unwrap() };
355+
/// assert_eq!(str, "name");
356+
/// ```
357+
pub fn get_tag(&self, typ: TagType) -> Option<&Tag> {
323358
self.tags().find(|tag| tag.typ == typ)
324359
}
325360

multiboot2/src/module.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ impl<'a> Iterator for ModuleIter<'a> {
7676

7777
fn next(&mut self) -> Option<&'a ModuleTag> {
7878
self.iter
79-
.find(|x| x.typ == TagType::Module)
79+
.find(|tag| tag.typ == TagType::Module)
8080
.map(|tag| unsafe { &*(tag as *const Tag as *const ModuleTag) })
8181
}
8282
}

multiboot2/src/tag_type.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -291,7 +291,7 @@ mod partial_eq_impls {
291291
pub struct Tag {
292292
pub typ: TagTypeId, // u32
293293
pub size: u32,
294-
// tag specific fields
294+
// additional, tag specific fields
295295
}
296296

297297
impl Tag {

0 commit comments

Comments
 (0)