FreeBSD starts loading, lots of unclean code

This commit is contained in:
Artemis Tosini 2024-08-05 01:53:12 +00:00
parent d53eb73e76
commit 9f68ee84b6
Signed by: artemist
GPG key ID: EE5227935FE3FF18
2 changed files with 38 additions and 13 deletions

View file

@ -33,7 +33,7 @@ trampoline_code:
cli cli
mov rsp,rdi mov rsp,rdi
push rcx push rcx
sal rdx, #32 sal rdx, 32
push rdx push rdx
push r8 push r8
mov cr3,rsi mov cr3,rsi
@ -54,14 +54,14 @@ trampoline_size:
fn trampoline_code( fn trampoline_code(
stack: *const u8, stack: *const u8,
pagetable: *const PageTable, pagetable: *const PageTable,
modinfo_base: *const u8, modinfo_offset: usize,
free_ptr: *const u8, free_offset: usize,
entry: *const u8, entry: *const u8,
); );
} }
type TrampolineFunction = 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))] #[repr(C, align(4096))]
struct MiscBuf { struct MiscBuf {
@ -76,11 +76,15 @@ trampoline_size:
pub fn boot_kernel( pub fn boot_kernel(
system_table: SystemTable<Boot>, system_table: SystemTable<Boot>,
kernel: Kernel, kernel: Kernel,
kernel_base: *const u8, kernel_start: *const u8,
modinfo_base: *const u8, modinfo_base: *const u8,
free_ptr: *const u8, free_ptr: *const u8,
staging: &mut [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( let misc_alloc = allocate_code(
system_table.boot_services(), system_table.boot_services(),
core::mem::size_of::<MiscBuf>(), core::mem::size_of::<MiscBuf>(),
@ -126,6 +130,18 @@ trampoline_size:
); );
unsafe { 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. // Serialize some final metadata. Calls exit boot services.
add_efi_metadata(system_table, staging); add_efi_metadata(system_table, staging);
@ -134,9 +150,9 @@ trampoline_size:
trampoline_func( trampoline_func(
&misc_buf.stack[PAGE_SIZE - 8] as *const u8, &misc_buf.stack[PAGE_SIZE - 8] as *const u8,
&misc_buf.pt4 as *const PageTable, &misc_buf.pt4 as *const PageTable,
modinfo_base, modinfo_base.byte_offset_from(kernel_base) as usize,
free_ptr, free_ptr.byte_offset_from(kernel_base) as usize,
kernel.entry_addr(kernel_base), entry_addr,
); );
} }
} }
@ -178,7 +194,7 @@ trampoline_size:
item.serialize_unaligned(staging) item.serialize_unaligned(staging)
} }
fn parse_efi_framebuffer_params<'a>( fn parse_efi_framebuffer_params(
boot_services: &BootServices, boot_services: &BootServices,
) -> Result<EFIFramebufferParams, uefi::Error> { ) -> Result<EFIFramebufferParams, uefi::Error> {
let gop_handle = boot_services.get_handle_for_protocol::<GraphicsOutput>()?; let gop_handle = boot_services.get_handle_for_protocol::<GraphicsOutput>()?;

View file

@ -12,7 +12,7 @@ use abi::{Environment, Howto, ModuleInfoItem, ModuleInfoType, ModuleInfoValue, S
use alloc::{collections::btree_map::BTreeMap, string::ToString}; use alloc::{collections::btree_map::BTreeMap, string::ToString};
use log::info; use log::info;
use object::{Kernel, Module}; 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] #[entry]
fn main(image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status { fn main(image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
@ -45,7 +45,6 @@ fn main(image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
let kernel = Kernel::from_elf_bytes(&kernel_data); let kernel = Kernel::from_elf_bytes(&kernel_data);
let mut kernel_metadata = kernel.metadata(); let mut kernel_metadata = kernel.metadata();
info!("Kernel metadata is {:x?}", kernel_metadata);
let environment = Environment(BTreeMap::from([( let environment = Environment(BTreeMap::from([(
"kernel".to_string(), "kernel".to_string(),
@ -68,7 +67,11 @@ fn main(image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
kernel_metadata.push(abi::ModuleInfoItem { kernel_metadata.push(abi::ModuleInfoItem {
tag: ModuleInfoType::Environment, 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 { kernel_metadata.push(abi::ModuleInfoItem {
@ -76,12 +79,18 @@ fn main(image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
value: ModuleInfoValue::Howto(Howto::VERBOSE | Howto::SERIAL), 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 { kernel_metadata.push(ModuleInfoItem {
tag: ModuleInfoType::FreeAddress, tag: ModuleInfoType::FreeAddress,
value: ModuleInfoValue::Pointer(free_ptr), value: ModuleInfoValue::Pointer(free_ptr),
}); });
info!("Kernel metadata is {:x?}", kernel_metadata);
let modinfo_base = next.as_ptr(); let modinfo_base = next.as_ptr();
for item in kernel_metadata.iter() { for item in kernel_metadata.iter() {
next = item.serialize_unaligned(next); next = item.serialize_unaligned(next);