FreeBSD starts loading, lots of unclean code
This commit is contained in:
parent
d53eb73e76
commit
9f68ee84b6
34
src/boot.rs
34
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<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>()?;
|
||||
|
|
17
src/main.rs
17
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<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);
|
||||
|
|
Loading…
Reference in a new issue