Skip to content

Commit

Permalink
find_kernel: fix ELF module boundaries
Browse files Browse the repository at this point in the history
The end address for all the modules seemed to be confused with the end address for the first module.
  • Loading branch information
cagatay-y committed Oct 1, 2024
1 parent 420b9e8 commit f649c1f
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 33 deletions.
50 changes: 26 additions & 24 deletions src/arch/x86_64/multiboot.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,13 @@ impl DeviceTree {

pub fn find_kernel() -> &'static [u8] {
paging::clean_up();

// Identity-map the Multiboot information.
unsafe {
assert!(mb_info > 0, "Could not find Multiboot information");
info!("Found Multiboot information at {:#x}", mb_info);
paging::map::<Size4KiB>(mb_info, mb_info, 1, PageTableFlags::empty());
}
unsafe { paging::map::<Size4KiB>(mb_info, mb_info, 1, PageTableFlags::empty()) };

let mut mem = Mem;
// Load the Multiboot information and identity-map the modules information.
Expand All @@ -109,37 +110,38 @@ pub fn find_kernel() -> &'static [u8] {
let mut module_iter = multiboot
.modules()
.expect("Could not find a memory map in the Multiboot information");
let start_address;
let mut end_address;

if let Some(first_module) = module_iter.next() {
start_address = first_module.start as usize;
info!("Found an ELF module at {:#x}", start_address);
end_address = first_module.end as usize;
} else {
panic!("Could not find a single module in the Multiboot information")
}

let first_module = module_iter
.next()
.expect("Could not find a single module in the Multiboot information");
info!(
"Found an ELF module at [{:#x} - {:#x}]",
first_module.start, first_module.end
);
let elf_start = first_module.start as usize;
let elf_len = (first_module.end - first_module.start) as usize;
info!("Module length: {:#x}", elf_len);

// Find the maximum end address from the remaining modules
let mut end_address = first_module.end;
for m in module_iter {
end_address = usize::max(end_address, m.end as usize);
end_address = cmp::max(end_address, m.end);
}

info!("Found module: [{:#x} - {:#x}]", start_address, end_address);
let elf_start = start_address;
let elf_len = end_address - start_address;
info!("Module length: {:#x}", elf_len);

// Identity-map the ELF header of the first module.
let first_module_mapping_end = start_address.align_up(Size2MiB::SIZE as usize);
// Identity-map the ELF header of the first module and until the 2 MiB
// mapping starts. We cannot start the 2 MiB mapping right from
// `first_module.end` because when it is aligned down, the
// resulting mapping range may overlap with the 4 KiB mapping.
let first_module_mapping_end = first_module.end.align_up(Size2MiB::SIZE);
paging::map_range::<Size4KiB>(
start_address,
start_address,
first_module.start,
first_module.start,
first_module_mapping_end,
PageTableFlags::empty(),
);

// map also the rest of the module
let modules_mapping_end = end_address.align_up(Size2MiB::SIZE as usize);
// map also the rest of the modules
let modules_mapping_end = end_address.align_up(Size2MiB::SIZE);
paging::map_range::<Size2MiB>(
first_module_mapping_end,
first_module_mapping_end,
Expand All @@ -148,7 +150,7 @@ pub fn find_kernel() -> &'static [u8] {
);

// Memory after the highest end address is unused and available for the physical memory manager.
PhysAlloc::init(modules_mapping_end);
PhysAlloc::init(modules_mapping_end as usize);

unsafe { slice::from_raw_parts(sptr::from_exposed_addr(elf_start), elf_len) }
}
Expand Down
14 changes: 5 additions & 9 deletions src/arch/x86_64/paging.rs
Original file line number Diff line number Diff line change
Expand Up @@ -50,18 +50,14 @@ where
}

#[cfg(all(target_arch = "x86_64", not(feature = "fc")))]
pub fn map_range<S>(
virtual_start: usize,
phys_start: usize,
phys_end: usize,
mut flags: PageTableFlags,
) where
pub fn map_range<S>(virtual_start: u64, phys_start: u64, phys_end: u64, mut flags: PageTableFlags)
where
S: PageSize + Debug,
RecursivePageTable<'static>: Mapper<S>,
{
let first_page = Page::<S>::containing_address(x86_64::VirtAddr::new(virtual_start as u64));
let first_frame = PhysFrame::containing_address(x86_64::PhysAddr::new(phys_start as u64));
let last_frame = PhysFrame::containing_address(x86_64::PhysAddr::new(phys_end as u64));
let first_page = Page::<S>::containing_address(x86_64::VirtAddr::new(virtual_start));
let first_frame = PhysFrame::containing_address(x86_64::PhysAddr::new(phys_start));
let last_frame = PhysFrame::containing_address(x86_64::PhysAddr::new(phys_end));
warn!(
"Mapping {size} pages starting from {from_start:p} to frames {to_start:p}..{to_end:p}",
size = S::DEBUG_STR,
Expand Down

0 comments on commit f649c1f

Please sign in to comment.