Skip to content

Commit fa7ac4f

Browse files
committed
AArch64: try boot from kernel before bootloader
Add kernel image loader and try to find kernel image info in FDT, if there is one, load and start kernel directly. Signed-off-by: Jianyong Wu <[email protected]>
1 parent b5af2a3 commit fa7ac4f

File tree

2 files changed

+55
-6
lines changed

2 files changed

+55
-6
lines changed

src/efi/mod.rs

Lines changed: 15 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ use core::{
1010
ptr::null_mut,
1111
};
1212

13+
use crate::efi::file::FileSystemWrapper;
1314
use atomic_refcell::AtomicRefCell;
1415
use linked_list_allocator::LockedHeap;
1516
use r_efi::{
@@ -1107,8 +1108,8 @@ pub fn efi_exec(
11071108
loaded_address: u64,
11081109
loaded_size: u64,
11091110
info: &dyn bootinfo::Info,
1110-
fs: &crate::fat::Filesystem,
1111-
block: *const crate::block::VirtioBlockDevice,
1111+
fs: Option<&crate::fat::Filesystem>,
1112+
block: Option<*const crate::block::VirtioBlockDevice>,
11121113
) {
11131114
let vendor_data = 0u32;
11141115

@@ -1178,14 +1179,23 @@ pub fn efi_exec(
11781179

11791180
populate_allocator(info, loaded_address, loaded_size);
11801181

1181-
let efi_part_id = unsafe { block::populate_block_wrappers(&mut BLOCK_WRAPPERS, block) };
1182+
let efi_part_id = if let Some(b) = block {
1183+
unsafe { block::populate_block_wrappers(&mut BLOCK_WRAPPERS, b) }
1184+
} else {
1185+
None
1186+
};
11821187

1183-
let wrapped_fs = file::FileSystemWrapper::new(fs, efi_part_id);
1188+
let wrapfs: FileSystemWrapper;
1189+
let mut wrapped_fs = core::ptr::null::<u8>() as Handle;
1190+
if let Some(f) = fs {
1191+
wrapfs = file::FileSystemWrapper::new(f, efi_part_id);
1192+
wrapped_fs = &wrapfs as *const _ as Handle;
1193+
};
11841194

11851195
let image = new_image_handle(
11861196
crate::efi::EFI_BOOT_PATH,
11871197
0 as Handle,
1188-
&wrapped_fs as *const _ as Handle,
1198+
wrapped_fs,
11891199
loaded_address,
11901200
loaded_size,
11911201
address,

src/main.rs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,8 @@ use x86_64::instructions::hlt;
2828

2929
#[cfg(target_arch = "aarch64")]
3030
use crate::arch::aarch64::layout::code_range;
31+
#[cfg(target_arch = "aarch64")]
32+
use crate::fdt::KernelInfo;
3133

3234
#[macro_use]
3335
mod serial;
@@ -156,10 +158,42 @@ fn boot_from_device(device: &mut block::VirtioBlockDevice, info: &dyn bootinfo::
156158
}
157159

158160
log!("Executable loaded");
159-
efi::efi_exec(entry_addr, load_addr, size, info, &f, device);
161+
efi::efi_exec(entry_addr, load_addr, size, info, Some(&f), Some(device));
160162
true
161163
}
162164

165+
#[cfg(target_arch = "aarch64")]
166+
fn boot_from_kernel(k: KernelInfo, info: &dyn bootinfo::Info) {
167+
let load_addr = info.kernel_load_addr();
168+
let dsc = load_addr as *mut u8;
169+
let src = k.address as *const u8;
170+
unsafe {
171+
core::ptr::copy(src, dsc, k.size as usize);
172+
}
173+
// Get pe_header_offset
174+
let pe_header_offset = unsafe {
175+
let addr = (dsc.wrapping_add(60_usize)) as *const u32;
176+
*addr
177+
};
178+
let entry_addr = unsafe {
179+
let addr = (dsc.wrapping_add((pe_header_offset + 40).try_into().unwrap())) as *const u32;
180+
*addr
181+
};
182+
let image_size = unsafe {
183+
let addr = (dsc.wrapping_add((pe_header_offset + 80).try_into().unwrap())) as *const u32;
184+
*addr
185+
};
186+
187+
efi::efi_exec(
188+
load_addr + entry_addr as u64,
189+
load_addr,
190+
image_size.into(),
191+
info,
192+
None,
193+
None,
194+
);
195+
}
196+
163197
#[cfg(target_arch = "x86_64")]
164198
#[no_mangle]
165199
pub extern "C" fn rust64_start(#[cfg(not(feature = "coreboot"))] pvh_info: &pvh::StartInfo) -> ! {
@@ -194,6 +228,11 @@ pub extern "C" fn rust64_start(x0: *const u8) -> ! {
194228
None,
195229
);
196230

231+
if let Some(kernel_info) = info.find_kernel_info() {
232+
log!("Boot with direct kernel");
233+
boot_from_kernel(kernel_info, &info);
234+
}
235+
197236
if let Some((base, length)) = info.find_compatible_region(&["pci-host-ecam-generic"]) {
198237
pci::init(base as u64, length as u64);
199238
}

0 commit comments

Comments
 (0)