diff --git a/src/memory/mod.rs b/src/memory/mod.rs
index daa34780..f8094bde 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 257a58a4..e7349496 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);
+ }
+ }
+ });
+}