Move kernel offset into one constant

This commit is contained in:
Artemis Tosini 2024-08-07 02:28:18 +00:00
parent 2a4c87c6b1
commit fb7dcf0f40
Signed by: artemist
GPG key ID: EE5227935FE3FF18
4 changed files with 26 additions and 18 deletions

View file

@ -14,6 +14,17 @@ fn align_slice(unaligned: &mut [u8], alignment: usize) -> &mut [u8] {
&mut unaligned[offset..] &mut unaligned[offset..]
} }
// x86_64 FreeBSD kernels leave 2MiB between KERNBASE and first load,
// but expect us to still be relative to KERNBASE
#[cfg(target_arch = "x86_64")]
pub const KERN_START_OFFSET: usize = 1 << 21;
#[cfg(not(target_arch = "x86_64"))]
pub const KERN_START_OFFSET: usize = 0;
pub fn relative_addr(addr: *const u8, kern_base: *const u8) -> usize {
(addr as usize) - (kern_base as usize) + KERN_START_OFFSET
}
/// Serialize object into a buffer for FreeBSD /// Serialize object into a buffer for FreeBSD
pub trait Serialize { pub trait Serialize {
/// Output buffer must be aligned to this size /// Output buffer must be aligned to this size

View file

@ -20,7 +20,10 @@ mod x86_64 {
}; };
use crate::{ use crate::{
abi::{EFIFramebufferParams, ModuleInfoItem, ModuleInfoType, ModuleInfoValue, Serialize}, abi::{
relative_addr, EFIFramebufferParams, ModuleInfoItem, ModuleInfoType, ModuleInfoValue,
Serialize, KERN_START_OFFSET,
},
object::Kernel, object::Kernel,
staging::allocate_code, staging::allocate_code,
}; };
@ -81,10 +84,6 @@ trampoline_size:
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>(),
@ -112,7 +111,7 @@ trampoline_size:
// Map the kernel to 2GiB from the top of RAM with 2MiB pages // Map the kernel to 2GiB from the top of RAM with 2MiB pages
for (idx, pte) in misc_buf.pt2_upper.iter_mut().enumerate() { for (idx, pte) in misc_buf.pt2_upper.iter_mut().enumerate() {
let addr = kernel_base as usize + (idx << 21); let addr = kernel_start as usize + (idx << 21) - KERN_START_OFFSET;
pte.set_addr( pte.set_addr(
PhysAddr::new(addr as u64), PhysAddr::new(addr as u64),
PageTableFlags::PRESENT | PageTableFlags::HUGE_PAGE | PageTableFlags::WRITABLE, PageTableFlags::PRESENT | PageTableFlags::HUGE_PAGE | PageTableFlags::WRITABLE,
@ -150,8 +149,8 @@ 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.byte_offset_from(kernel_base) as usize, relative_addr(modinfo_base, kernel_start),
free_ptr.byte_offset_from(kernel_base) as usize, relative_addr(free_ptr, kernel_start),
entry_addr, entry_addr,
); );
} }

View file

@ -9,7 +9,9 @@ mod staging;
extern crate alloc; extern crate alloc;
use abi::{Environment, Howto, ModuleInfoItem, ModuleInfoType, ModuleInfoValue, Serialize}; use abi::{
relative_addr, Environment, Howto, ModuleInfoItem, ModuleInfoType, ModuleInfoValue, Serialize,
};
use alloc::{collections::btree_map::BTreeMap, string::ToString}; use alloc::{collections::btree_map::BTreeMap, string::ToString};
use hardware::add_acpi_environ; use hardware::add_acpi_environ;
use log::info; use log::info;
@ -67,17 +69,13 @@ fn main(image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
let alloc_size = kernel.alloc_size() + environment.alloc_size() + modinfo_size; let alloc_size = kernel.alloc_size() + environment.alloc_size() + modinfo_size;
let staging = staging::allocate_code(system_table.boot_services(), alloc_size); let staging = staging::allocate_code(system_table.boot_services(), alloc_size);
let (kernel_base, next) = kernel.serialize_unaligned_base(staging); let (kern_base, next) = kernel.serialize_unaligned_base(staging);
let (environ_base, next) = environment.serialize_unaligned_base(next); let (environ_base, next) = environment.serialize_unaligned_base(next);
kernel_modinfo.push(abi::ModuleInfoItem { kernel_modinfo.push(abi::ModuleInfoItem {
tag: ModuleInfoType::Environment, tag: ModuleInfoType::Environment,
value: ModuleInfoValue::Size( value: ModuleInfoValue::Size(relative_addr(environ_base, kern_base)),
(environ_base as usize)
.wrapping_sub(kernel_base as usize)
.wrapping_add(1 << 21),
),
}); });
kernel_modinfo.push(abi::ModuleInfoItem { kernel_modinfo.push(abi::ModuleInfoItem {
@ -105,7 +103,7 @@ fn main(image_handle: Handle, mut system_table: SystemTable<Boot>) -> Status {
boot::boot_kernel( boot::boot_kernel(
system_table, system_table,
kernel, kernel,
kernel_base, kern_base,
modinfo_base, modinfo_base,
free_ptr, free_ptr,
next, next,

View file

@ -1,6 +1,6 @@
extern crate alloc; extern crate alloc;
use crate::abi::{ModuleInfoItem, ModuleInfoType, ModuleInfoValue, Serialize}; use crate::abi::{ModuleInfoItem, ModuleInfoType, ModuleInfoValue, Serialize, KERN_START_OFFSET};
use alloc::vec::Vec; use alloc::vec::Vec;
use goblin::elf::{program_header, section_header, Elf, SectionHeader}; use goblin::elf::{program_header, section_header, Elf, SectionHeader};
use log::{debug, info}; use log::{debug, info};
@ -198,7 +198,7 @@ impl<'a> Module for Kernel<'a> {
]; ];
if self.symbol_headers.is_some() { if self.symbol_headers.is_some() {
let start_symbols = self.size_load_segments() + (1 << 21); let start_symbols = self.size_load_segments() + KERN_START_OFFSET;
let end_symbols = start_symbols + self.size_symbols(); let end_symbols = start_symbols + self.size_symbols();
items.push(ModuleInfoItem { items.push(ModuleInfoItem {