@@ -28,6 +28,8 @@ use x86_64::instructions::hlt;
2828
2929#[ cfg( target_arch = "aarch64" ) ]
3030use crate :: arch:: aarch64:: layout:: code_range;
31+ #[ cfg( target_arch = "aarch64" ) ]
32+ use crate :: fdt:: KernelInfo ;
3133
3234#[ macro_use]
3335mod 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]
165199pub 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