-
Notifications
You must be signed in to change notification settings - Fork 57
Expand file tree
/
Copy pathmod.rs
More file actions
119 lines (108 loc) · 3.45 KB
/
mod.rs
File metadata and controls
119 lines (108 loc) · 3.45 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
mod chainloader;
mod grub;
use alloc::format;
use alloc::vec::Vec;
use multiboot2::{BootInformation, ElfSectionExt};
pub fn run(mbi: &BootInformation) -> anyhow::Result<()> {
println!("MBI: {mbi:#x?}");
println!();
let bootloader = mbi
.boot_loader_name_tag()
.ok_or("No bootloader tag")
.map_err(anyhow::Error::msg)?
.name()
.map_err(anyhow::Error::msg)?;
if bootloader.to_lowercase().contains("grub") {
log::info!("loaded by grub");
grub::run(mbi)?;
} else {
log::info!("loaded by chainloader");
chainloader::run(mbi)?;
}
Ok(())
}
pub(self) fn print_memory_map(mbi: &BootInformation) -> anyhow::Result<()> {
let memmap = mbi
.memory_map_tag()
.ok_or("Should have memory map")
.map_err(anyhow::Error::msg)?;
println!("Memory Map:");
memmap.memory_areas().iter().for_each(|e| {
println!(
" 0x{:010x} - 0x{:010x} ({:.3} MiB {:?})",
e.start_address(),
e.end_address(),
e.size() as f32 / 1024.0 / 1024.0,
e.typ()
);
});
println!();
Ok(())
}
pub(self) fn print_elf_info(mbi: &BootInformation) -> anyhow::Result<()> {
let sections_iter = mbi
.elf_sections_tag()
.ok_or("Should have elf sections")
.map(|tag| tag.sections())
.map_err(anyhow::Error::msg)?;
let string_table = mbi
.elf_sections_tag()
.ok_or("Should have elf sections")
.map(|tag| tag.string_table())
.map_err(anyhow::Error::msg)?
.ok_or("String table section should be present")
.map_err(anyhow::Error::msg)?;
println!("ELF sections:");
for s in sections_iter {
let typ = format!("{:?}", s.sh_type);
let flags = format!("{:?}", s.flags());
let name = s
.name_from_string_table(string_table)
.map_err(anyhow::Error::msg)?
.to_str()
.map_err(anyhow::Error::msg)?;
println!(
" {:<13} {:<17} {:<22} 0x{:010x} 0x{:010x} {:>5.2} MiB align={}",
name,
typ,
flags,
s.sh_addr,
s.sh_addr + s.sh_size,
s.sh_size as f32 / 1024.0,
s.sh_addralign,
);
}
println!();
Ok(())
}
pub(self) fn print_module_info(mbi: &BootInformation) -> anyhow::Result<()> {
let modules = mbi.module_tags().collect::<Vec<_>>();
if modules.len() != 1 {
Err(anyhow::Error::msg("Should have exactly one boot module"))?
}
let module = modules.first().unwrap();
let module_cmdline = module.cmdline().map_err(anyhow::Error::msg)?;
println!("Modules:");
println!(
" 0x{:010x} - 0x{:010x} ({} B, cmdline='{}')",
module.start_address(),
module.end_address(),
module.module_size(),
module_cmdline
);
println!(" grub cfg passed as boot module:");
let grup_cfg_ptr = module.start_address() as *const u32 as *const u8;
let grub_cfg =
unsafe { core::slice::from_raw_parts(grup_cfg_ptr, module.module_size() as usize) };
// In the GRUB bootflow case, we pass the config as module with it. This is
// not done for the chainloaded case.
if let Ok(str) = core::str::from_utf8(grub_cfg) {
println!("=== file begin ===");
for line in str.lines() {
println!(" > {line}");
}
println!("=== file end ===");
println!();
}
Ok(())
}