Skip to content

Commit 91f37d2

Browse files
committed
main: Split boot off device into own function
Also remove the behaviour of resetting on failure, instead return true on boot success or false otherwise. When we start to look at iterating over multiple devices returning false will cause the firmwarware to try another device. Signed-off-by: Rob Bradford <robert.bradford@intel.com>
1 parent 78e158e commit 91f37d2

File tree

1 file changed

+54
-57
lines changed

1 file changed

+54
-57
lines changed

src/main.rs

Lines changed: 54 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,6 @@ mod common;
2525

2626
use core::panic::PanicInfo;
2727

28-
use cpuio::Port;
29-
3028
mod block;
3129
mod bzimage;
3230
mod efi;
@@ -46,19 +44,6 @@ fn panic(_info: &PanicInfo) -> ! {
4644
loop {}
4745
}
4846

49-
#[cfg(not(test))]
50-
/// Reset the VM via the keyboard controller
51-
fn i8042_reset() -> ! {
52-
loop {
53-
let mut good: u8 = 0x02;
54-
let mut i8042_command: Port<u8> = unsafe { Port::new(0x64) };
55-
while good & 0x02 > 0 {
56-
good = i8042_command.read();
57-
}
58-
i8042_command.write(0xFE);
59-
}
60-
}
61-
6247
#[cfg(not(test))]
6348
/// Enable SSE2 for XMM registers (needed for EFI calling)
6449
fn enable_sse2() {
@@ -95,37 +80,11 @@ const VIRTIO_PCI_VENDOR_ID: u16 = 0x1af4;
9580
const VIRTIO_PCI_BLOCK_DEVICE_ID: u16 = 0x1042;
9681

9782
#[cfg(not(test))]
98-
#[allow(unused_attributes)]
99-
#[no_mangle]
100-
pub extern "C" fn _start() -> ! {
101-
unsafe {
102-
asm!("movq $$0x180000, %rsp");
103-
}
104-
105-
log!("Starting..\n");
106-
107-
enable_sse2();
108-
setup_pagetables();
109-
110-
pci::print_bus();
111-
112-
let mut pci_transport;
113-
let mut mmio_transport;
114-
115-
let mut device = if let Some(pci_device) =
116-
pci::search_bus(VIRTIO_PCI_VENDOR_ID, VIRTIO_PCI_BLOCK_DEVICE_ID)
117-
{
118-
pci_transport = pci::VirtioPciTransport::new(pci_device);
119-
block::VirtioBlockDevice::new(&mut pci_transport)
120-
} else {
121-
mmio_transport = mmio::VirtioMMIOTransport::new(0xd000_0000u64);
122-
block::VirtioBlockDevice::new(&mut mmio_transport)
123-
};
124-
83+
fn boot_from_device(device: &mut block::VirtioBlockDevice) -> bool {
12584
match device.init() {
12685
Err(_) => {
12786
log!("Error configuring block device\n");
128-
i8042_reset();
87+
return false;
12988
}
13089
Ok(_) => log!(
13190
"Virtio block device configured. Capacity: {} sectors\n",
@@ -135,18 +94,18 @@ pub extern "C" fn _start() -> ! {
13594

13695
let mut f;
13796

138-
match part::find_efi_partition(&device) {
97+
match part::find_efi_partition(device) {
13998
Ok((start, end)) => {
14099
log!("Found EFI partition\n");
141-
f = fat::Filesystem::new(&device, start, end);
100+
f = fat::Filesystem::new(device, start, end);
142101
if f.init().is_err() {
143102
log!("Failed to create filesystem\n");
144-
i8042_reset();
103+
return false;
145104
}
146105
}
147106
Err(_) => {
148107
log!("Failed to find EFI partition\n");
149-
i8042_reset();
108+
return false;
150109
}
151110
}
152111

@@ -159,26 +118,31 @@ pub extern "C" fn _start() -> ! {
159118
jump_address = addr;
160119
}
161120
Err(_) => {
162-
log!("Error loading default entry\n");
121+
log!("Error loading default entry. Using EFI boot.\n");
163122
match f.open("/EFI/BOOT/BOOTX64 EFI") {
164123
Ok(mut file) => {
165124
log!("Found bootloader (BOOTX64.EFI)\n");
166125
let mut l = pe::Loader::new(&mut file);
167126
match l.load(0x20_0000) {
168127
Ok((a, size)) => {
169128
log!("Executable loaded\n");
170-
efi::efi_exec(a, 0x20_0000, size, &f, &device);
171-
i8042_reset();
129+
efi::efi_exec(a, 0x20_0000, size, &f, device);
130+
return true;
131+
}
132+
Err(e) => {
133+
match e {
134+
pe::Error::FileError => log!("File error\n"),
135+
pe::Error::InvalidExecutable => log!("Invalid executable\n"),
136+
}
137+
return false;
172138
}
173-
Err(e) => match e {
174-
pe::Error::FileError => log!("File error\n"),
175-
pe::Error::InvalidExecutable => log!("Invalid executable\n"),
176-
},
177139
}
178140
}
179-
Err(_) => log!("Failed to find bootloader\n"),
141+
Err(_) => {
142+
log!("Failed to find bootloader\n");
143+
return false;
144+
}
180145
}
181-
i8042_reset();
182146
}
183147
}
184148

@@ -190,6 +154,39 @@ pub extern "C" fn _start() -> ! {
190154
let ptr = jump_address as *const ();
191155
let code: extern "C" fn(u64, u64) = unsafe { core::mem::transmute(ptr) };
192156
(code)(0 /* dummy value */, bzimage::ZERO_PAGE_START as u64);
157+
true
158+
}
193159

194-
i8042_reset()
160+
#[cfg(not(test))]
161+
#[allow(unused_attributes)]
162+
#[no_mangle]
163+
pub extern "C" fn _start() -> ! {
164+
unsafe {
165+
asm!("movq $$0x180000, %rsp");
166+
}
167+
168+
log!("Starting..\n");
169+
170+
enable_sse2();
171+
setup_pagetables();
172+
173+
pci::print_bus();
174+
175+
let mut pci_transport;
176+
let mut mmio_transport;
177+
178+
let mut device = if let Some(pci_device) =
179+
pci::search_bus(VIRTIO_PCI_VENDOR_ID, VIRTIO_PCI_BLOCK_DEVICE_ID)
180+
{
181+
pci_transport = pci::VirtioPciTransport::new(pci_device);
182+
block::VirtioBlockDevice::new(&mut pci_transport)
183+
} else {
184+
mmio_transport = mmio::VirtioMMIOTransport::new(0xd000_0000u64);
185+
block::VirtioBlockDevice::new(&mut mmio_transport)
186+
};
187+
188+
boot_from_device(&mut device);
189+
190+
#[allow(clippy::empty_loop)]
191+
loop {}
195192
}

0 commit comments

Comments
 (0)