Browse Source

Remap the kernel! (finally)

master
3moon 8 years ago
parent
commit
c83ab3c3a2
3 changed files with 50 additions and 3 deletions
  1. +1
    -1
      src/arch/x86_64/memory/mod.rs
  2. +46
    -0
      src/arch/x86_64/memory/paging/mod.rs
  3. +3
    -2
      src/lib.rs

+ 1
- 1
src/arch/x86_64/memory/mod.rs View File

@ -7,7 +7,7 @@ mod paging;
pub use self::area_frame_allocator::AreaFrameAllocator;
pub use self::paging::test_paging;
pub use self::paging::remap_kernel;
/// The physical size of each frame.
pub const PAGE_SIZE: usize = 4096;


+ 46
- 0
src/arch/x86_64/memory/paging/mod.rs View File

@ -3,12 +3,15 @@
//! Extremely ripped off from Phil Oppermann's tutorials, because I don't feel like writing
//! a paging system off the top of my head today.
use core::ops::{Deref, DerefMut};
use multiboot2::BootInformation;
use super::PAGE_SIZE;
use super::{Frame, FrameAllocator};
mod entry;
mod table;
mod mapper;
mod temporary_page;
use self::entry::*;
use self::table::{Table, Level4};
@ -148,6 +151,49 @@ impl Page {
}
}
/// Remap the kernel
pub fn remap_kernel<A>(allocator: &mut A, boot_info: &BootInformation)
where A: FrameAllocator {
let mut scratch_page = TemporaryPage::new(Page { index: 0xabadcafe },
allocator);
let mut active_table = unsafe {ActivePageTable::new()};
let mut new_table = {
let frame = allocator.alloc_frame()
.expect("Attempted to allocate a frame for a new page table, but no frames are available!");
InactivePageTable::new(frame, &mut active_table, &mut scratch_page)
};
active_table.with(&mut new_table, &mut scratch_page, |mapper| {
let elf_sections_tag = boot_info.elf_sections_tag()
.expect("ELF sections tag required!");
for section in elf_sections_tag.sections() {
if !section.is_allocated() {
// section is not loaded to memory
continue;
}
assert!(section.start_address() % PAGE_SIZE == 0, "ELF sections must be page-aligned!");
debug!("Mapping section at addr: {:#x}, size: {:#x}",
section.addr, section.size);
let flags = WRITABLE;
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);
}
}
let vga_buffer_frame = Frame::containing_address(0xb8000);
mapper.identity_map(vga_buffer_frame, WRITABLE, allocator);
});
let old_table = active_table.switch(new_table);
info!("Successfully switched to new page table.");
}
/// Temporary function to test paging
pub fn test_paging<A>(allocator: &mut A) where A: FrameAllocator {
let mut page_table = unsafe {ActivePageTable::new()};


+ 3
- 2
src/lib.rs View File

@ -63,8 +63,9 @@ pub extern fn kernel_main(multiboot_info_pointer: usize) {
kernel_start as usize, kernel_end as usize, multiboot_start,
multiboot_end, memory_map_tag.memory_areas());
memory::test_paging(&mut frame_allocator);
println!("-- memory paging test finished --");
memory::remap_kernel(&mut frame_allocator, boot_info);
println!("-- remap_kernel finished! --");
loop {}
}


Loading…
Cancel
Save