diff --git a/Cargo.toml b/Cargo.toml index 57c18cd..7e40575 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -17,7 +17,7 @@ bit_field = "0.7.0" rlibc = "1.0" volatile = "0.1.0" spin = "0.4.5" -multiboot2 = "0.1.0" +multiboot2 = "0.5" bitflags = "1.0" x86_64 = "0.1.2" once = "0.3.3" diff --git a/src/memory/area_frame_allocator.rs b/src/memory/area_frame_allocator.rs index 9759b5c..68ebee2 100644 --- a/src/memory/area_frame_allocator.rs +++ b/src/memory/area_frame_allocator.rs @@ -23,7 +23,7 @@ impl FrameAllocator for AreaFrameAllocator { // the last frame of the current area let current_area_last_frame = { - let address = area.base_addr + area.length - 1; + let address = area.end_address() - 1; Frame::of_addr(address as usize) }; @@ -77,12 +77,12 @@ impl AreaFrameAllocator { fn choose_next_area(&mut self) { self.current_area = self.areas.clone().filter(|area| { - let address = area.base_addr + area.length - 1; + let address = area.end_address() - 1; Frame::of_addr(address as usize) >= self.next_free_frame - }).min_by_key(|area| area.base_addr); + }).min_by_key(|area| area.start_address()); if let Some(area) = self.current_area { - let start_frame = Frame::of_addr(area.base_addr as usize); + let start_frame = Frame::of_addr(area.start_address()); if self.next_free_frame < start_frame { self.next_free_frame = start_frame; } diff --git a/src/memory/mod.rs b/src/memory/mod.rs index 574c737..507fb46 100644 --- a/src/memory/mod.rs +++ b/src/memory/mod.rs @@ -26,7 +26,7 @@ pub fn alloc_frame() -> Frame { .allocate_frame().expect("no more frame") } -pub fn init(boot_info: &BootInformation) -> MemoryController { +pub fn init(boot_info: BootInformation) -> MemoryController { assert_has_not_been_called!("memory::init must be called only once"); let memory_map_tag = boot_info.memory_map_tag().expect( @@ -35,9 +35,9 @@ pub fn init(boot_info: &BootInformation) -> MemoryController { "Elf sections tag required"); let kernel_start = PhysAddr(elf_sections_tag.sections() - .filter(|s| s.is_allocated()).map(|s| s.start_address()).min().unwrap() as u64); + .filter(|s| s.is_allocated()).map(|s| s.start_address()).min().unwrap()); let kernel_end = PhysAddr::from_kernel_virtual(elf_sections_tag.sections() - .filter(|s| s.is_allocated()).map(|s| s.end_address()).max().unwrap()); + .filter(|s| s.is_allocated()).map(|s| s.end_address()).max().unwrap() as usize); let boot_info_start = PhysAddr(boot_info.start_address() as u64); let boot_info_end = PhysAddr(boot_info.end_address() as u64); @@ -66,7 +66,7 @@ pub fn init(boot_info: &BootInformation) -> MemoryController { } } -pub fn remap_the_kernel(boot_info: &BootInformation) -> (ActivePageTable, Stack) +pub fn remap_the_kernel(boot_info: BootInformation) -> (ActivePageTable, Stack) { let mut active_table = unsafe { ActivePageTable::new() }; let mut memory_set = MemorySet::from(boot_info.elf_sections_tag().unwrap()); @@ -115,8 +115,8 @@ pub fn remap_the_kernel(boot_info: &BootInformation) -> (ActivePageTable, Stack) use multiboot2::{ElfSectionsTag, ElfSection, ElfSectionFlags}; -impl From<&'static ElfSectionsTag> for MemorySet { - fn from(sections: &'static ElfSectionsTag) -> Self { +impl From for MemorySet { + fn from(sections: ElfSectionsTag) -> Self { assert_has_not_been_called!(); // WARNING: must ensure it's large enough static mut SPACE: [u8; 0x1000] = [0; 0x1000]; @@ -132,26 +132,29 @@ impl From<&'static ElfSectionsTag> for MemorySet { } } -impl<'a> From<&'a ElfSection> for MemoryArea { - fn from(section: &'a ElfSection) -> Self { +impl From for MemoryArea { + fn from(section: ElfSection) -> Self { use self::address::FromToVirtualAddress; - assert_eq!(section.start_address() % PAGE_SIZE, 0, "sections need to be page aligned"); - if section.start_address() < KERNEL_OFFSET { + let start_addr = section.start_address() as usize; + let end_addr = section.end_address() as usize; + assert_eq!(start_addr % PAGE_SIZE, 0, "sections need to be page aligned"); + let name = unsafe { &*(section.name() as *const str) }; + if start_addr < KERNEL_OFFSET { MemoryArea { - start_addr: section.start_address() + KERNEL_OFFSET, - end_addr: section.end_address() + KERNEL_OFFSET, + start_addr: start_addr + KERNEL_OFFSET, + end_addr: end_addr + KERNEL_OFFSET, phys_start_addr: Some(PhysAddr(section.start_address() as u64)), flags: EntryFlags::from(section.flags()).bits() as u32, - name: "", + name, mapped: false, } } else { MemoryArea { - start_addr: section.start_address(), - end_addr: section.end_address(), - phys_start_addr: Some(PhysAddr::from_kernel_virtual(section.start_address())), + start_addr, + end_addr, + phys_start_addr: Some(PhysAddr::from_kernel_virtual(start_addr)), flags: EntryFlags::from(section.flags()).bits() as u32, - name: "", + name, mapped: false, } } @@ -160,19 +163,16 @@ impl<'a> From<&'a ElfSection> for MemoryArea { impl From for EntryFlags { fn from(elf_flags: ElfSectionFlags) -> Self { - use multiboot2::{ELF_SECTION_ALLOCATED, ELF_SECTION_WRITABLE, - ELF_SECTION_EXECUTABLE}; - let mut flags = EntryFlags::empty(); - if elf_flags.contains(ELF_SECTION_ALLOCATED) { + if elf_flags.contains(ElfSectionFlags::ALLOCATED) { // section is loaded to memory flags = flags | EntryFlags::PRESENT; } - if elf_flags.contains(ELF_SECTION_WRITABLE) { + if elf_flags.contains(ElfSectionFlags::WRITABLE) { flags = flags | EntryFlags::WRITABLE; } - if !elf_flags.contains(ELF_SECTION_EXECUTABLE) { + if !elf_flags.contains(ElfSectionFlags::EXECUTABLE) { flags = flags | EntryFlags::NO_EXECUTE; } flags