Skip to content

Commit ec0e777

Browse files
authored
Merge pull request #167 from rust-osdev/foobar
multiboot2: cleanup of debug format output
2 parents 5de87ae + 46a90f9 commit ec0e777

File tree

5 files changed

+144
-108
lines changed

5 files changed

+144
-108
lines changed

integration-test/bins/multiboot2_payload/src/verify/mod.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ use alloc::vec::Vec;
66
use multiboot2::BootInformation;
77

88
pub fn run(mbi: &BootInformation) -> anyhow::Result<()> {
9-
println!("{mbi:#?}");
9+
println!("{mbi:#x?}");
1010
println!();
1111

1212
let bootloader = mbi

multiboot2/Changelog.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,16 @@
99
only effects you when you wrote a custom DST tag.
1010
- **BREAKING** Removed deprecated functions `load` and `load_with_offset`. Use
1111
`BootInformation::load` instead.
12+
- **BREAKING** Renamed `BootInformation::efi_32_ih_tag` to
13+
`BootInformation::efi_ih32_tag` for consistency.
14+
- **BREAKING** Renamed `BootInformation::efi_64_ih_tag` to
15+
`BootInformation::efi_ih64_tag` for consistency.
16+
- **BREAKING** Renamed `BootInformation::efi_std_32_tag` to
17+
`BootInformation::efi_std32_tag` for consistency.
18+
- **BREAKING** Renamed `BootInformation::efi_std_64_tag` to
19+
`BootInformation::efi_std64_tag` for consistency.
20+
- Better debug output of `BootInformation` and `MemoryArea`
21+
- Internal code cleanup.
1222

1323
## 0.17.0 (2023-07-12)
1424
- **BREAKING** Make functions of `InformationBuilder` chainable. They now consume the builder.

multiboot2/src/lib.rs

Lines changed: 118 additions & 102 deletions
Original file line numberDiff line numberDiff line change
@@ -263,11 +263,72 @@ impl<'a> BootInformation<'a> {
263263
self.0.header.total_size as usize
264264
}
265265

266+
// ######################################################
267+
// ### BEGIN OF TAG GETTERS (in alphabetical order)
268+
269+
/*fn apm(&self) {
270+
// also add to debug output
271+
todo!()
272+
}*/
273+
266274
/// Search for the basic memory info tag.
267275
pub fn basic_memory_info_tag(&self) -> Option<&BasicMemoryInfoTag> {
268276
self.get_tag::<BasicMemoryInfoTag>()
269277
}
270278

279+
/// Search for the BootLoader name tag.
280+
pub fn boot_loader_name_tag(&self) -> Option<&BootLoaderNameTag> {
281+
self.get_tag::<BootLoaderNameTag>()
282+
}
283+
284+
/*fn bootdev(&self) {
285+
// also add to debug output
286+
todo!()
287+
}*/
288+
289+
/// Search for the Command line tag.
290+
pub fn command_line_tag(&self) -> Option<&CommandLineTag> {
291+
self.get_tag::<CommandLineTag>()
292+
}
293+
294+
/// Search for the EFI boot services not exited tag.
295+
pub fn efi_bs_not_exited_tag(&self) -> Option<&EFIBootServicesNotExitedTag> {
296+
self.get_tag::<EFIBootServicesNotExitedTag>()
297+
}
298+
299+
/// Search for the EFI Memory map tag, if the boot services were exited.
300+
/// Otherwise, if the [`TagType::EfiBs`] tag is present, this returns `None`
301+
/// as it is strictly recommended to get the memory map from the `uefi`
302+
/// services.
303+
pub fn efi_memory_map_tag(&self) -> Option<&EFIMemoryMapTag> {
304+
// If the EFIBootServicesNotExited is present, then we should not use
305+
// the memory map, as it could still be in use.
306+
match self.get_tag::<EFIBootServicesNotExitedTag>() {
307+
Some(_tag) => None,
308+
None => self.get_tag::<EFIMemoryMapTag>(),
309+
}
310+
}
311+
312+
/// Search for the EFI 32-bit SDT tag.
313+
pub fn efi_sdt32_tag(&self) -> Option<&EFISdt32Tag> {
314+
self.get_tag::<EFISdt32Tag>()
315+
}
316+
317+
/// Search for the EFI 64-bit SDT tag.
318+
pub fn efi_sdt64_tag(&self) -> Option<&EFISdt64Tag> {
319+
self.get_tag::<EFISdt64Tag>()
320+
}
321+
322+
/// Search for the EFI 32-bit image handle pointer tag.
323+
pub fn efi_ih32_tag(&self) -> Option<&EFIImageHandle32Tag> {
324+
self.get_tag::<EFIImageHandle32Tag>()
325+
}
326+
327+
/// Search for the EFI 64-bit image handle pointer tag.
328+
pub fn efi_ih64_tag(&self) -> Option<&EFIImageHandle64Tag> {
329+
self.get_tag::<EFIImageHandle64Tag>()
330+
}
331+
271332
/// Returns an [`ElfSectionIter`] iterator over the ELF Sections, if the
272333
/// [`ElfSectionsTag`] is present.
273334
///
@@ -293,26 +354,6 @@ impl<'a> BootInformation<'a> {
293354
})
294355
}
295356

296-
/// Search for the Memory map tag.
297-
pub fn memory_map_tag(&self) -> Option<&MemoryMapTag> {
298-
self.get_tag::<MemoryMapTag>()
299-
}
300-
301-
/// Get an iterator of all module tags.
302-
pub fn module_tags(&self) -> ModuleIter {
303-
module::module_iter(self.tags())
304-
}
305-
306-
/// Search for the BootLoader name tag.
307-
pub fn boot_loader_name_tag(&self) -> Option<&BootLoaderNameTag> {
308-
self.get_tag::<BootLoaderNameTag>()
309-
}
310-
311-
/// Search for the Command line tag.
312-
pub fn command_line_tag(&self) -> Option<&CommandLineTag> {
313-
self.get_tag::<CommandLineTag>()
314-
}
315-
316357
/// Search for the VBE framebuffer tag. The result is `Some(Err(e))`, if the
317358
/// framebuffer type is unknown, while the framebuffer tag is present.
318359
pub fn framebuffer_tag(&self) -> Option<Result<&FramebufferTag, UnknownFramebufferType>> {
@@ -323,16 +364,26 @@ impl<'a> BootInformation<'a> {
323364
})
324365
}
325366

326-
/// Search for the EFI 32-bit SDT tag.
327-
pub fn efi_sdt_32_tag(&self) -> Option<&EFISdt32Tag> {
328-
self.get_tag::<EFISdt32Tag>()
367+
/// Search for the Image Load Base Physical Address tag.
368+
pub fn load_base_addr_tag(&self) -> Option<&ImageLoadPhysAddrTag> {
369+
self.get_tag::<ImageLoadPhysAddrTag>()
329370
}
330371

331-
/// Search for the EFI 64-bit SDT tag.
332-
pub fn efi_sdt_64_tag(&self) -> Option<&EFISdt64Tag> {
333-
self.get_tag::<EFISdt64Tag>()
372+
/// Search for the Memory map tag.
373+
pub fn memory_map_tag(&self) -> Option<&MemoryMapTag> {
374+
self.get_tag::<MemoryMapTag>()
334375
}
335376

377+
/// Get an iterator of all module tags.
378+
pub fn module_tags(&self) -> ModuleIter {
379+
module::module_iter(self.tags())
380+
}
381+
382+
/*fn network_tag(&self) {
383+
// also add to debug output
384+
todo!()
385+
}*/
386+
336387
/// Search for the (ACPI 1.0) RSDP tag.
337388
pub fn rsdp_v1_tag(&self) -> Option<&RsdpV1Tag> {
338389
self.get_tag::<RsdpV1Tag>()
@@ -343,60 +394,28 @@ impl<'a> BootInformation<'a> {
343394
self.get_tag::<RsdpV2Tag>()
344395
}
345396

346-
/// Search for the EFI Memory map tag, if the boot services were exited.
347-
/// Otherwise, if the [`TagType::EfiBs`] tag is present, this returns `None`
348-
/// as it is strictly recommended to get the memory map from the `uefi`
349-
/// services.
350-
pub fn efi_memory_map_tag(&self) -> Option<&EFIMemoryMapTag> {
351-
// If the EFIBootServicesNotExited is present, then we should not use
352-
// the memory map, as it could still be in use.
353-
match self.get_tag::<EFIBootServicesNotExitedTag>() {
354-
Some(_tag) => None,
355-
None => self.get_tag::<EFIMemoryMapTag>(),
356-
}
357-
}
358-
359-
/// Search for the EFI 32-bit image handle pointer tag.
360-
pub fn efi_32_ih_tag(&self) -> Option<&EFIImageHandle32Tag> {
361-
self.get_tag::<EFIImageHandle32Tag>()
362-
}
363-
364-
/// Search for the EFI 64-bit image handle pointer tag.
365-
pub fn efi_64_ih_tag(&self) -> Option<&EFIImageHandle64Tag> {
366-
self.get_tag::<EFIImageHandle64Tag>()
367-
}
368-
369-
/// Search for the EFI boot services not exited tag.
370-
pub fn efi_bs_not_exited_tag(&self) -> Option<&EFIBootServicesNotExitedTag> {
371-
self.get_tag::<EFIBootServicesNotExitedTag>()
372-
}
373-
374-
/// Search for the Image Load Base Physical Address tag.
375-
pub fn load_base_addr_tag(&self) -> Option<&ImageLoadPhysAddrTag> {
376-
self.get_tag::<ImageLoadPhysAddrTag>()
397+
/// Search for the SMBIOS tag.
398+
pub fn smbios_tag(&self) -> Option<&SmbiosTag> {
399+
self.get_tag::<SmbiosTag>()
377400
}
378401

379402
/// Search for the VBE information tag.
380403
pub fn vbe_info_tag(&self) -> Option<&VBEInfoTag> {
381404
self.get_tag::<VBEInfoTag>()
382405
}
383406

384-
/// Search for the SMBIOS tag.
385-
pub fn smbios_tag(&self) -> Option<&SmbiosTag> {
386-
self.get_tag::<SmbiosTag>()
387-
}
407+
// ### END OF TAG GETTERS
408+
// ######################################################
388409

389410
/// Public getter to find any Multiboot tag by its type, including
390411
/// specified and custom ones.
391412
///
392-
/// The parameter can be of type `u32`, [`TagType`], or [`TagTypeId`].
393-
///
394413
/// # Specified or Custom Tags
395414
/// The Multiboot2 specification specifies a list of tags, see [`TagType`].
396415
/// However, it doesn't forbid to use custom tags. Because of this, there
397416
/// exists the [`TagType`] abstraction. It is recommended to use this
398417
/// getter only for custom tags. For specified tags, use getters, such as
399-
/// [`Self::efi_64_ih_tag`].
418+
/// [`Self::efi_ih64_tag`].
400419
///
401420
/// ## Use Custom Tags
402421
/// The following example shows how you may use this interface to parse
@@ -462,50 +481,47 @@ impl fmt::Debug for BootInformation<'_> {
462481
/// Limit how many Elf-Sections should be debug-formatted.
463482
/// Can be thousands of sections for a Rust binary => this is useless output.
464483
/// If the user really wants this, they should debug-format the field directly.
465-
const ELF_SECTIONS_LIMIT: usize = 17;
484+
const ELF_SECTIONS_LIMIT: usize = 7;
466485

467-
let mut debug = f.debug_struct("Multiboot2 Boot Information");
486+
let mut debug = f.debug_struct("Multiboot2BootInformation");
468487
debug
469-
.field("start_address", &(self.start_address() as *const u64))
470-
.field("end_address", &(self.end_address() as *const u64))
471-
.field("total_size", &(self.total_size() as *const u64))
472-
.field(
473-
"boot_loader_name_tag",
474-
&self
475-
.boot_loader_name_tag()
476-
.and_then(|x| x.name().ok())
477-
.unwrap_or("<unknown>"),
478-
)
479-
.field(
480-
"command_line",
481-
&self
482-
.command_line_tag()
483-
.and_then(|x| x.cmdline().ok())
484-
.unwrap_or(""),
485-
)
486-
.field("memory_areas", &self.memory_map_tag())
487-
// so far, I didn't found a nice way to connect the iterator with ".field()" because
488-
// the iterator isn't Debug
489-
.field("module_tags", &self.module_tags());
490-
// usually this is REALLY big (thousands of tags) => skip it here
488+
.field("start_address", &self.start_address())
489+
.field("end_address", &self.end_address())
490+
.field("total_size", &self.total_size())
491+
// now tags in alphabetical order
492+
.field("basic_memory_info", &(self.basic_memory_info_tag()))
493+
.field("boot_loader_name", &self.boot_loader_name_tag())
494+
// .field("bootdev", &self.bootdev_tag())
495+
.field("command_line", &self.command_line_tag())
496+
.field("efi_bs_not_exited", &self.efi_bs_not_exited_tag())
497+
.field("efi_memory_map", &self.efi_memory_map_tag())
498+
.field("efi_sdt32", &self.efi_sdt32_tag())
499+
.field("efi_sdt64", &self.efi_sdt64_tag())
500+
.field("efi_ih32", &self.efi_ih32_tag())
501+
.field("efi_ih64", &self.efi_ih64_tag());
491502

492-
let elf_sections_tag_entries_count = self.elf_sections().map(|x| x.count()).unwrap_or(0);
493-
494-
if elf_sections_tag_entries_count > ELF_SECTIONS_LIMIT {
495-
debug.field("elf_sections_tags (count)", &elf_sections_tag_entries_count);
496-
} else {
497-
debug.field(
498-
"elf_sections_tags",
499-
&self.elf_sections().unwrap_or_default(),
500-
);
503+
// usually this is REALLY big (thousands of tags) => skip it here
504+
{
505+
let elf_sections_tag_entries_count =
506+
self.elf_sections().map(|x| x.count()).unwrap_or(0);
507+
508+
if elf_sections_tag_entries_count > ELF_SECTIONS_LIMIT {
509+
debug.field("elf_sections (count)", &elf_sections_tag_entries_count);
510+
} else {
511+
debug.field("elf_sections", &self.elf_sections().unwrap_or_default());
512+
}
501513
}
502514

503515
debug
504-
.field("efi_32_ih", &self.efi_32_ih_tag())
505-
.field("efi_64_ih", &self.efi_64_ih_tag())
506-
.field("efi_sdt_32_tag", &self.efi_sdt_32_tag())
507-
.field("efi_sdt_64_tag", &self.efi_sdt_64_tag())
508-
.field("efi_memory_map_tag", &self.efi_memory_map_tag())
516+
.field("framebuffer", &self.framebuffer_tag())
517+
.field("load_base_addr", &self.load_base_addr_tag())
518+
.field("memory_map", &self.memory_map_tag())
519+
.field("modules", &self.module_tags())
520+
// .field("network", &self.network_tag())
521+
.field("rsdp_v1", &self.rsdp_v1_tag())
522+
.field("rsdp_v2", &self.rsdp_v2_tag())
523+
.field("smbios_tag", &self.smbios_tag())
524+
.field("vbe_info_tag", &self.vbe_info_tag())
509525
.finish()
510526
}
511527
}

multiboot2/src/memory_map.rs

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -73,7 +73,7 @@ impl TagTrait for MemoryMapTag {
7373
}
7474

7575
/// A memory area entry descriptor.
76-
#[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord, Hash)]
76+
#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
7777
#[repr(C)]
7878
pub struct MemoryArea {
7979
base_addr: u64,
@@ -114,6 +114,16 @@ impl MemoryArea {
114114
}
115115
}
116116

117+
impl Debug for MemoryArea {
118+
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
119+
f.debug_struct("MemoryArea")
120+
.field("base_addr", &self.base_addr)
121+
.field("length", &self.length)
122+
.field("typ", &self.typ)
123+
.finish()
124+
}
125+
}
126+
117127
#[cfg(feature = "builder")]
118128
impl AsBytes for MemoryArea {}
119129

multiboot2/src/module.rs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -80,11 +80,11 @@ impl Debug for ModuleTag {
8080
fn fmt(&self, f: &mut Formatter<'_>) -> core::fmt::Result {
8181
f.debug_struct("ModuleTag")
8282
.field("type", &{ self.typ })
83-
.field("size (tag)", &{ self.size })
84-
.field("size (module)", &self.module_size())
83+
.field("size", &{ self.size })
8584
// Trick to print as hex.
86-
.field("mod_start", &(self.mod_start as *const usize))
87-
.field("mod_end", &(self.mod_end as *const usize))
85+
.field("mod_start", &self.mod_start)
86+
.field("mod_end", &self.mod_end)
87+
.field("mod_size", &self.module_size())
8888
.field("cmdline", &self.cmdline())
8989
.finish()
9090
}

0 commit comments

Comments
 (0)