diff --git a/src/arch/x86_64/multiboot.rs b/src/arch/x86_64/multiboot.rs index 3446ffc..c620f21 100644 --- a/src/arch/x86_64/multiboot.rs +++ b/src/arch/x86_64/multiboot.rs @@ -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::(mb_info, mb_info, 1, PageTableFlags::empty()); } - unsafe { paging::map::(mb_info, mb_info, 1, PageTableFlags::empty()) }; let mut mem = Mem; // Load the Multiboot information and identity-map the modules information. @@ -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::( - 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::( first_module_mapping_end, first_module_mapping_end, @@ -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) } } diff --git a/src/arch/x86_64/paging.rs b/src/arch/x86_64/paging.rs index 50fec12..56dd4eb 100644 --- a/src/arch/x86_64/paging.rs +++ b/src/arch/x86_64/paging.rs @@ -50,18 +50,14 @@ where } #[cfg(all(target_arch = "x86_64", not(feature = "fc")))] -pub fn map_range( - virtual_start: usize, - phys_start: usize, - phys_end: usize, - mut flags: PageTableFlags, -) where +pub fn map_range(virtual_start: u64, phys_start: u64, phys_end: u64, mut flags: PageTableFlags) +where S: PageSize + Debug, RecursivePageTable<'static>: Mapper, { - let first_page = Page::::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::::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,