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
|
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>()?;
|
||||||
|
|
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 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);
|
||||||
|
|
Loading…
Reference in a new issue