diff --git a/src/boot.rs b/src/boot.rs index 8745afa..2c9c169 100644 --- a/src/boot.rs +++ b/src/boot.rs @@ -33,7 +33,7 @@ trampoline_code: cli mov rsp,rdi push rcx - sal rdx, #32 + sal rdx, 32 push rdx push r8 mov cr3,rsi @@ -54,14 +54,14 @@ trampoline_size: fn trampoline_code( stack: *const u8, pagetable: *const PageTable, - modinfo_base: *const u8, - free_ptr: *const u8, + modinfo_offset: usize, + free_offset: usize, entry: *const u8, ); } type TrampolineFunction = - extern "sysv64" fn(*const u8, *const PageTable, *const u8, *const u8, *const u8); + extern "sysv64" fn(*const u8, *const PageTable, usize, usize, *const u8); #[repr(C, align(4096))] struct MiscBuf { @@ -76,11 +76,15 @@ trampoline_size: pub fn boot_kernel( system_table: SystemTable, kernel: Kernel, - kernel_base: *const u8, + kernel_start: *const u8, modinfo_base: *const u8, free_ptr: *const u8, staging: &mut [u8], ) { + // FreeBSD x86_64 makes stuff relative to KERNBASE, + // 2MiB before the first mapping (KERNSTART) + let kernel_base = unsafe { kernel_start.byte_offset(-(1 << 21)) }; + let misc_alloc = allocate_code( system_table.boot_services(), core::mem::size_of::(), @@ -126,6 +130,18 @@ trampoline_size: ); unsafe { + let entry_addr = kernel.entry_addr(kernel_start); + log::debug!( + "Calling trampoline at {:#x} for kernel at {:#x}", + misc_buf.trampoline.as_ptr() as usize, + entry_addr as usize + ); + log::debug!( + "modinfo_base={:#x}, free_ptr={:#x}", + modinfo_base as usize, + free_ptr as usize + ); + // Serialize some final metadata. Calls exit boot services. add_efi_metadata(system_table, staging); @@ -134,9 +150,9 @@ trampoline_size: trampoline_func( &misc_buf.stack[PAGE_SIZE - 8] as *const u8, &misc_buf.pt4 as *const PageTable, - modinfo_base, - free_ptr, - kernel.entry_addr(kernel_base), + modinfo_base.byte_offset_from(kernel_base) as usize, + free_ptr.byte_offset_from(kernel_base) as usize, + entry_addr, ); } } @@ -178,7 +194,7 @@ trampoline_size: item.serialize_unaligned(staging) } - fn parse_efi_framebuffer_params<'a>( + fn parse_efi_framebuffer_params( boot_services: &BootServices, ) -> Result { let gop_handle = boot_services.get_handle_for_protocol::()?; diff --git a/src/main.rs b/src/main.rs index 53a39dd..8ef398d 100644 --- a/src/main.rs +++ b/src/main.rs @@ -12,7 +12,7 @@ use abi::{Environment, Howto, ModuleInfoItem, ModuleInfoType, ModuleInfoValue, S use alloc::{collections::btree_map::BTreeMap, string::ToString}; use log::info; use object::{Kernel, Module}; -use uefi::{fs::FileSystem, prelude::*, proto::loaded_image::LoadedImage}; +use uefi::{fs::FileSystem, prelude::*, proto::loaded_image::LoadedImage, table::boot::PAGE_SIZE}; #[entry] fn main(image_handle: Handle, mut system_table: SystemTable) -> Status { @@ -45,7 +45,6 @@ fn main(image_handle: Handle, mut system_table: SystemTable) -> Status { let kernel = Kernel::from_elf_bytes(&kernel_data); let mut kernel_metadata = kernel.metadata(); - info!("Kernel metadata is {:x?}", kernel_metadata); let environment = Environment(BTreeMap::from([( "kernel".to_string(), @@ -68,7 +67,11 @@ fn main(image_handle: Handle, mut system_table: SystemTable) -> Status { kernel_metadata.push(abi::ModuleInfoItem { tag: ModuleInfoType::Environment, - value: ModuleInfoValue::Pointer(environ_base), + value: ModuleInfoValue::Size( + (environ_base as usize) + .wrapping_sub(kernel_base as usize) + .wrapping_add(1 << 21), + ), }); kernel_metadata.push(abi::ModuleInfoItem { @@ -76,12 +79,18 @@ fn main(image_handle: Handle, mut system_table: SystemTable) -> Status { value: ModuleInfoValue::Howto(Howto::VERBOSE | Howto::SERIAL), }); - let free_ptr = unsafe { next.as_ptr().byte_add(metadata_size) }; + let free_ptr = unsafe { + let base = next.as_ptr().byte_add(metadata_size); + let offset = base.align_offset(PAGE_SIZE); + base.byte_add(offset) + }; kernel_metadata.push(ModuleInfoItem { tag: ModuleInfoType::FreeAddress, value: ModuleInfoValue::Pointer(free_ptr), }); + info!("Kernel metadata is {:x?}", kernel_metadata); + let modinfo_base = next.as_ptr(); for item in kernel_metadata.iter() { next = item.serialize_unaligned(next);