Skip to content

Commit e426948

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 e426948

File tree

2 files changed

+53
-6
lines changed

2 files changed

+53
-6
lines changed

src/efi/mod.rs

+13-5
Original file line numberDiff line numberDiff line change
@@ -1107,8 +1107,8 @@ pub fn efi_exec(
11071107
loaded_address: u64,
11081108
loaded_size: u64,
11091109
info: &dyn bootinfo::Info,
1110-
fs: &crate::fat::Filesystem,
1111-
block: *const crate::block::VirtioBlockDevice,
1110+
fs: Option<&crate::fat::Filesystem>,
1111+
block: Option<*const crate::block::VirtioBlockDevice>,
11121112
) {
11131113
let vendor_data = 0u32;
11141114

@@ -1178,14 +1178,22 @@ pub fn efi_exec(
11781178

11791179
populate_allocator(info, loaded_address, loaded_size);
11801180

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

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

11851193
let image = new_image_handle(
11861194
crate::efi::EFI_BOOT_PATH,
11871195
0 as Handle,
1188-
&wrapped_fs as *const _ as Handle,
1196+
wrapped_fs,
11891197
loaded_address,
11901198
loaded_size,
11911199
address,

src/main.rs

+40-1
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)