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
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<Boot>,
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::<MiscBuf>(),
@ -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<EFIFramebufferParams, uefi::Error> {
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 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<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 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<Boot>) -> 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<Boot>) -> 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);