Skip to content

Commit

Permalink
find_kernel: initialize the allocator based on the start address for …
Browse files Browse the repository at this point in the history
…unrelocatable kernels
  • Loading branch information
cagatay-y committed Oct 3, 2024
1 parent c857397 commit c51b5bc
Showing 1 changed file with 16 additions and 10 deletions.
26 changes: 16 additions & 10 deletions src/arch/x86_64/multiboot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use align_address::Align;
use hermit_entry::boot_info::{
BootInfo, DeviceTreeAddress, HardwareInfo, PlatformInfo, SerialPortBase,
};
use hermit_entry::elf::LoadedKernel;
use hermit_entry::elf::{KernelObject, LoadedKernel};
use log::info;
use multiboot::information::{MemoryManagement, MemoryType, Multiboot, PAddr};
use sptr::Strict;
Expand Down Expand Up @@ -92,8 +92,6 @@ impl DeviceTree {
}

pub fn find_kernel() -> &'static [u8] {
use core::cmp;

paging::clean_up();
// Identity-map the Multiboot information.
unsafe {
Expand Down Expand Up @@ -139,12 +137,6 @@ pub fn find_kernel() -> &'static [u8] {
let elf_len = end_address - start_address;
info!("Module length: {:#x}", elf_len);

let free_memory_address = end_address.align_up(Size2MiB::SIZE as usize);
// TODO: Workaround for https://github.com/hermitcore/loader/issues/96
let free_memory_address = cmp::max(free_memory_address, 0x800000);
// Memory after the highest end address is unused and available for the physical memory manager.
PhysAlloc::init(free_memory_address);

// Identity-map the ELF header of the first module.
assert!(
found_module,
Expand All @@ -165,7 +157,21 @@ pub fn find_kernel() -> &'static [u8] {
paging::map::<Size2MiB>(address, address, counter, PageTableFlags::empty());
}

unsafe { slice::from_raw_parts(sptr::from_exposed_addr(elf_start), elf_len) }
let elf_slice = unsafe { slice::from_raw_parts(sptr::from_exposed_addr(elf_start), elf_len) };

// This is mostly a workaround, as it does not really ensure that the memory allocated to load the kernel
// will include the required start address. If the structure of the surrounding code at the time of writing
// of this section changes, an allocation that will overlap with the kernel load section can be made or the
// allocation granularity of the kernel load section can get smaller in a way that will not cover the whole need.
let kernel = KernelObject::parse(elf_slice).unwrap();
let free_memory_address = kernel.start_addr().map_or(
end_address.align_up(Size2MiB::SIZE as usize),
|start_addr| start_addr.align_down(Size2MiB::SIZE).try_into().unwrap(),
);
// Memory after the highest end address is unused and available for the physical memory manager.
PhysAlloc::init(free_memory_address);

elf_slice
}

pub unsafe fn boot_kernel(kernel_info: LoadedKernel) -> ! {
Expand Down

0 comments on commit c51b5bc

Please sign in to comment.