Skip to content

Commit f7bb89f

Browse files
committed
main: Rewrite boot_from_device
We now pass the boot::Info to `loader::load_default_entry` and `efi::efi_exec`. We also reorganize the code in this function to: - Avoid unnecessary nesting - log errors when they occur The code is now much more readable Signed-off-by: Joe Richey <joerichey@google.com>
1 parent d9bd3ef commit f7bb89f

File tree

1 file changed

+49
-64
lines changed

1 file changed

+49
-64
lines changed

src/main.rs

Lines changed: 49 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -76,81 +76,66 @@ fn enable_sse() {
7676
const VIRTIO_PCI_VENDOR_ID: u16 = 0x1af4;
7777
const VIRTIO_PCI_BLOCK_DEVICE_ID: u16 = 0x1042;
7878

79-
fn boot_from_device(device: &mut block::VirtioBlockDevice) -> bool {
80-
match device.init() {
81-
Err(_) => {
82-
log!("Error configuring block device");
83-
return false;
84-
}
85-
Ok(_) => log!(
86-
"Virtio block device configured. Capacity: {} sectors",
87-
device.get_capacity()
88-
),
79+
fn boot_from_device(device: &mut block::VirtioBlockDevice, info: &dyn boot::Info) -> bool {
80+
if let Err(err) = device.init() {
81+
log!("Error configuring block device: {:?}", err);
82+
return false;
8983
}
84+
log!(
85+
"Virtio block device configured. Capacity: {} sectors",
86+
device.get_capacity()
87+
);
9088

91-
let mut f;
92-
93-
match part::find_efi_partition(device) {
94-
Ok((start, end)) => {
95-
log!("Found EFI partition");
96-
f = fat::Filesystem::new(device, start, end);
97-
if f.init().is_err() {
98-
log!("Failed to create filesystem");
99-
return false;
100-
}
101-
}
102-
Err(_) => {
103-
log!("Failed to find EFI partition");
89+
let (start, end) = match part::find_efi_partition(device) {
90+
Ok(p) => p,
91+
Err(err) => {
92+
log!("Failed to find EFI partition: {:?}", err);
10493
return false;
10594
}
106-
}
95+
};
96+
log!("Found EFI partition");
10797

98+
let mut f = fat::Filesystem::new(device, start, end);
99+
if let Err(err) = f.init() {
100+
log!("Failed to create filesystem: {:?}", err);
101+
return false;
102+
}
108103
log!("Filesystem ready");
109104

110-
let jump_address;
105+
match loader::load_default_entry(&f, info) {
106+
Ok(mut kernel) => {
107+
device.reset();
108+
log!("Jumping to kernel");
109+
kernel.boot();
110+
return true;
111+
}
112+
Err(err) => log!("Error loading default entry: {:?}", err),
113+
}
111114

112-
match loader::load_default_entry(&f) {
113-
Ok(addr) => {
114-
jump_address = addr;
115+
log!("Using EFI boot.");
116+
let mut file = match f.open("/EFI/BOOT/BOOTX64 EFI") {
117+
Ok(file) => file,
118+
Err(err) => {
119+
log!("Failed to load default EFI binary: {:?}", err);
120+
return false;
115121
}
116-
Err(_) => {
117-
log!("Error loading default entry. Using EFI boot.");
118-
match f.open("/EFI/BOOT/BOOTX64 EFI") {
119-
Ok(mut file) => {
120-
log!("Found bootloader (BOOTX64.EFI)");
121-
let mut l = pe::Loader::new(&mut file);
122-
match l.load(0x20_0000) {
123-
Ok((a, size)) => {
124-
log!("Executable loaded");
125-
efi::efi_exec(a, 0x20_0000, size, &f, device);
126-
return true;
127-
}
128-
Err(e) => {
129-
match e {
130-
pe::Error::FileError => log!("File error"),
131-
pe::Error::InvalidExecutable => log!("Invalid executable"),
132-
}
133-
return false;
134-
}
135-
}
136-
}
137-
Err(_) => {
138-
log!("Failed to find bootloader");
139-
return false;
140-
}
141-
}
122+
};
123+
log!("Found bootloader (BOOTX64.EFI)");
124+
125+
let mut l = pe::Loader::new(&mut file);
126+
let load_addr = 0x20_0000;
127+
let (entry_addr, size) = match l.load(load_addr) {
128+
Ok(load_info) => load_info,
129+
Err(err) => {
130+
log!("Error loading executable: {:?}", err);
131+
return false;
142132
}
143-
}
133+
};
144134

145135
device.reset();
146-
147-
log!("Jumping to kernel");
148-
149-
// Rely on x86 C calling convention where second argument is put into %rsi register
150-
let ptr = jump_address as *const ();
151-
let code: extern "C" fn(u64, u64) = unsafe { core::mem::transmute(ptr) };
152-
(code)(0 /* dummy value */, bzimage::ZERO_PAGE_START as u64);
153-
true
136+
log!("Executable loaded");
137+
efi::efi_exec(entry_addr, 0x20_0000, size, info, &f, device);
138+
return true;
154139
}
155140

156141
#[no_mangle]
@@ -175,7 +160,7 @@ fn run(info: &dyn boot::Info) -> ! {
175160
let mut pci_transport = pci::VirtioPciTransport::new(pci_device);
176161
block::VirtioBlockDevice::new(&mut pci_transport);
177162
let mut device = block::VirtioBlockDevice::new(&mut pci_transport);
178-
boot_from_device(&mut device)
163+
boot_from_device(&mut device, info)
179164
},
180165
);
181166

0 commit comments

Comments
 (0)