From fb7dcf0f401cad2fb124044df8104747c008a2ed Mon Sep 17 00:00:00 2001 From: Artemis Tosini Date: Wed, 7 Aug 2024 02:28:18 +0000 Subject: [PATCH] Move kernel offset into one constant --- src/abi.rs | 11 +++++++++++ src/boot.rs | 15 +++++++-------- src/main.rs | 14 ++++++-------- src/object.rs | 4 ++-- 4 files changed, 26 insertions(+), 18 deletions(-) diff --git a/src/abi.rs b/src/abi.rs index 35cb6f0..1b87c1f 100644 --- a/src/abi.rs +++ b/src/abi.rs @@ -14,6 +14,17 @@ fn align_slice(unaligned: &mut [u8], alignment: usize) -> &mut [u8] { &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 pub trait Serialize { /// Output buffer must be aligned to this size diff --git a/src/boot.rs b/src/boot.rs index 978d0be..b7aa423 100644 --- a/src/boot.rs +++ b/src/boot.rs @@ -20,7 +20,10 @@ mod x86_64 { }; use crate::{ - abi::{EFIFramebufferParams, ModuleInfoItem, ModuleInfoType, ModuleInfoValue, Serialize}, + abi::{ + relative_addr, EFIFramebufferParams, ModuleInfoItem, ModuleInfoType, ModuleInfoValue, + Serialize, KERN_START_OFFSET, + }, object::Kernel, staging::allocate_code, }; @@ -81,10 +84,6 @@ trampoline_size: 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::(), @@ -112,7 +111,7 @@ trampoline_size: // Map the kernel to 2GiB from the top of RAM with 2MiB pages 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( PhysAddr::new(addr as u64), PageTableFlags::PRESENT | PageTableFlags::HUGE_PAGE | PageTableFlags::WRITABLE, @@ -150,8 +149,8 @@ trampoline_size: trampoline_func( &misc_buf.stack[PAGE_SIZE - 8] as *const u8, &misc_buf.pt4 as *const PageTable, - modinfo_base.byte_offset_from(kernel_base) as usize, - free_ptr.byte_offset_from(kernel_base) as usize, + relative_addr(modinfo_base, kernel_start), + relative_addr(free_ptr, kernel_start), entry_addr, ); } diff --git a/src/main.rs b/src/main.rs index cb6b5b1..8d408b2 100644 --- a/src/main.rs +++ b/src/main.rs @@ -9,7 +9,9 @@ mod staging; 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 hardware::add_acpi_environ; use log::info; @@ -67,17 +69,13 @@ fn main(image_handle: Handle, mut system_table: SystemTable) -> Status { let alloc_size = kernel.alloc_size() + environment.alloc_size() + modinfo_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); kernel_modinfo.push(abi::ModuleInfoItem { tag: ModuleInfoType::Environment, - value: ModuleInfoValue::Size( - (environ_base as usize) - .wrapping_sub(kernel_base as usize) - .wrapping_add(1 << 21), - ), + value: ModuleInfoValue::Size(relative_addr(environ_base, kern_base)), }); kernel_modinfo.push(abi::ModuleInfoItem { @@ -105,7 +103,7 @@ fn main(image_handle: Handle, mut system_table: SystemTable) -> Status { boot::boot_kernel( system_table, kernel, - kernel_base, + kern_base, modinfo_base, free_ptr, next, diff --git a/src/object.rs b/src/object.rs index 7aaaf54..9b386d5 100644 --- a/src/object.rs +++ b/src/object.rs @@ -1,6 +1,6 @@ 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 goblin::elf::{program_header, section_header, Elf, SectionHeader}; use log::{debug, info}; @@ -198,7 +198,7 @@ impl<'a> Module for Kernel<'a> { ]; 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(); items.push(ModuleInfoItem {