From e029eabe180e6ee070ded981e56849a96664e30a Mon Sep 17 00:00:00 2001 From: Philipp Oppermann Date: Tue, 18 Apr 2017 12:11:40 +0200 Subject: [PATCH] Add a remap_the_kernel function --- src/memory/mod.rs | 26 +++++++++++++++++++++++++ src/memory/paging/mod.rs | 41 ++++++++++++++++++++++++++++++++++++++++ 2 files changed, 67 insertions(+) diff --git a/src/memory/mod.rs b/src/memory/mod.rs index daa3478..f8094bd 100644 --- a/src/memory/mod.rs +++ b/src/memory/mod.rs @@ -23,8 +23,34 @@ impl Frame { fn clone(&self) -> Frame { Frame { number: self.number } } + + fn range_inclusive(start: Frame, end: Frame) -> FrameIter { + FrameIter { + start: start, + end: end, + } + } +} + +struct FrameIter { + start: Frame, + end: Frame, } +impl Iterator for FrameIter { + type Item = Frame; + + fn next(&mut self) -> Option { + if self.start <= self.end { + let frame = self.start.clone(); + self.start.number += 1; + Some(frame) + } else { + None + } + } + } + pub trait FrameAllocator { fn allocate_frame(&mut self) -> Option; fn deallocate_frame(&mut self, frame: Frame); diff --git a/src/memory/paging/mod.rs b/src/memory/paging/mod.rs index 257a58a..e734949 100644 --- a/src/memory/paging/mod.rs +++ b/src/memory/paging/mod.rs @@ -3,6 +3,7 @@ pub use self::mapper::Mapper; use core::ops::{Deref, DerefMut}; use core::ptr::Unique; use memory::{PAGE_SIZE, Frame, FrameAllocator}; +use multiboot2::BootInformation; use self::table::{Table, Level4}; use self::temporary_page::TemporaryPage; @@ -127,3 +128,43 @@ impl InactivePageTable { InactivePageTable { p4_frame: frame } } } + +pub fn remap_the_kernel(allocator: &mut A, boot_info: &BootInformation) + where A: FrameAllocator +{ + let mut temporary_page = TemporaryPage::new(Page { number: 0xcafebabe }, + allocator); + + let mut active_table = unsafe { ActivePageTable::new() }; + let mut new_table = { + let frame = allocator.allocate_frame().expect("no more frames"); + InactivePageTable::new(frame, &mut active_table, &mut temporary_page) + }; + + active_table.with(&mut new_table, &mut temporary_page, |mapper| { + let elf_sections_tag = boot_info.elf_sections_tag() + .expect("Memory map tag required"); + + for section in elf_sections_tag.sections() { + use self::entry::WRITABLE; + + if !section.is_allocated() { + // section is not loaded to memory + continue; + } + assert!(section.start_address() % PAGE_SIZE == 0, + "sections need to be page aligned"); + + println!("mapping section at addr: {:#x}, size: {:#x}", + section.addr, section.size); + + let flags = WRITABLE; // TODO use real section flags + + let start_frame = Frame::containing_address(section.start_address()); + let end_frame = Frame::containing_address(section.end_address() - 1); + for frame in Frame::range_inclusive(start_frame, end_frame) { + mapper.identity_map(frame, flags, allocator); + } + } + }); +}