|
|
|
@ -22,13 +22,13 @@ pub fn init(boot_info: &BootInformation) -> MemoryController {
|
|
|
|
|
let elf_sections_tag = boot_info.elf_sections_tag().expect(
|
|
|
|
|
"Elf sections tag required");
|
|
|
|
|
|
|
|
|
|
let kernel_start = PhysicalAddress(elf_sections_tag.sections()
|
|
|
|
|
let kernel_start = PhysAddr(elf_sections_tag.sections()
|
|
|
|
|
.filter(|s| s.is_allocated()).map(|s| s.start_address()).min().unwrap() as u64);
|
|
|
|
|
let kernel_end = PhysicalAddress::from_kernel_virtual(elf_sections_tag.sections()
|
|
|
|
|
let kernel_end = PhysAddr::from_kernel_virtual(elf_sections_tag.sections()
|
|
|
|
|
.filter(|s| s.is_allocated()).map(|s| s.end_address()).max().unwrap());
|
|
|
|
|
|
|
|
|
|
let boot_info_start = PhysicalAddress(boot_info.start_address() as u64);
|
|
|
|
|
let boot_info_end = PhysicalAddress(boot_info.end_address() as u64);
|
|
|
|
|
let boot_info_start = PhysAddr(boot_info.start_address() as u64);
|
|
|
|
|
let boot_info_end = PhysAddr(boot_info.end_address() as u64);
|
|
|
|
|
|
|
|
|
|
println!("kernel start: {:#x}, kernel end: {:#x}",
|
|
|
|
|
kernel_start,
|
|
|
|
@ -51,8 +51,8 @@ pub fn init(boot_info: &BootInformation) -> MemoryController {
|
|
|
|
|
use self::paging::Page;
|
|
|
|
|
use consts::{KERNEL_HEAP_OFFSET, KERNEL_HEAP_SIZE};
|
|
|
|
|
|
|
|
|
|
let heap_start_page = Page::containing_address(KERNEL_HEAP_OFFSET);
|
|
|
|
|
let heap_end_page = Page::containing_address(KERNEL_HEAP_OFFSET + KERNEL_HEAP_SIZE-1);
|
|
|
|
|
let heap_start_page = Page::of_addr(KERNEL_HEAP_OFFSET);
|
|
|
|
|
let heap_end_page = Page::of_addr(KERNEL_HEAP_OFFSET + KERNEL_HEAP_SIZE-1);
|
|
|
|
|
|
|
|
|
|
for page in Page::range_inclusive(heap_start_page, heap_end_page) {
|
|
|
|
|
active_table.map(page, EntryFlags::WRITABLE, &mut frame_allocator);
|
|
|
|
@ -67,9 +67,9 @@ pub fn init(boot_info: &BootInformation) -> MemoryController {
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
MemoryController {
|
|
|
|
|
active_table: active_table,
|
|
|
|
|
frame_allocator: frame_allocator,
|
|
|
|
|
stack_allocator: stack_allocator,
|
|
|
|
|
active_table,
|
|
|
|
|
frame_allocator,
|
|
|
|
|
stack_allocator,
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
@ -77,7 +77,7 @@ pub fn remap_the_kernel<A>(allocator: &mut A, boot_info: &BootInformation)
|
|
|
|
|
-> ActivePageTable
|
|
|
|
|
where A: FrameAllocator
|
|
|
|
|
{
|
|
|
|
|
let mut temporary_page = TemporaryPage::new(Page::containing_address(0xcafebabe), allocator);
|
|
|
|
|
let mut temporary_page = TemporaryPage::new(Page::of_addr(0xcafebabe), allocator);
|
|
|
|
|
|
|
|
|
|
let mut active_table = unsafe { ActivePageTable::new() };
|
|
|
|
|
let mut new_table = {
|
|
|
|
@ -94,8 +94,7 @@ pub fn remap_the_kernel<A>(allocator: &mut A, boot_info: &BootInformation)
|
|
|
|
|
// section is not loaded to memory
|
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
assert!(section.start_address() % PAGE_SIZE == 0,
|
|
|
|
|
"sections need to be page aligned");
|
|
|
|
|
assert_eq!(section.start_address() % PAGE_SIZE, 0, "sections need to be page aligned");
|
|
|
|
|
|
|
|
|
|
println!("mapping section at addr: {:#x}, size: {:#x}",
|
|
|
|
|
section.addr, section.size);
|
|
|
|
@ -103,7 +102,7 @@ pub fn remap_the_kernel<A>(allocator: &mut A, boot_info: &BootInformation)
|
|
|
|
|
let flags = EntryFlags::from_elf_section_flags(section);
|
|
|
|
|
|
|
|
|
|
fn to_physical_frame(addr: usize) -> Frame {
|
|
|
|
|
Frame::containing_address(
|
|
|
|
|
Frame::of_addr(
|
|
|
|
|
if addr < KERNEL_OFFSET { addr }
|
|
|
|
|
else { addr - KERNEL_OFFSET })
|
|
|
|
|
}
|
|
|
|
@ -112,18 +111,18 @@ pub fn remap_the_kernel<A>(allocator: &mut A, boot_info: &BootInformation)
|
|
|
|
|
let end_frame = to_physical_frame(section.end_address() - 1);
|
|
|
|
|
|
|
|
|
|
for frame in Frame::range_inclusive(start_frame, end_frame) {
|
|
|
|
|
let page = Page::containing_address(frame.start_address().to_kernel_virtual());
|
|
|
|
|
let page = Page::of_addr(frame.start_address().to_kernel_virtual());
|
|
|
|
|
mapper.map_to(page, frame, flags, allocator);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
// identity map the VGA text buffer
|
|
|
|
|
let vga_buffer_frame = Frame::containing_address(0xb8000);
|
|
|
|
|
let vga_buffer_frame = Frame::of_addr(0xb8000);
|
|
|
|
|
mapper.identity_map(vga_buffer_frame, EntryFlags::WRITABLE, allocator);
|
|
|
|
|
|
|
|
|
|
// identity map the multiboot info structure
|
|
|
|
|
let multiboot_start = Frame::containing_address(boot_info.start_address());
|
|
|
|
|
let multiboot_end = Frame::containing_address(boot_info.end_address() - 1);
|
|
|
|
|
let multiboot_start = Frame::of_addr(boot_info.start_address());
|
|
|
|
|
let multiboot_end = Frame::of_addr(boot_info.end_address() - 1);
|
|
|
|
|
for frame in Frame::range_inclusive(multiboot_start, multiboot_end) {
|
|
|
|
|
mapper.identity_map(frame, EntryFlags::PRESENT, allocator);
|
|
|
|
|
}
|
|
|
|
@ -134,8 +133,8 @@ pub fn remap_the_kernel<A>(allocator: &mut A, boot_info: &BootInformation)
|
|
|
|
|
|
|
|
|
|
// turn the stack bottom into a guard page
|
|
|
|
|
extern { fn stack_bottom(); }
|
|
|
|
|
let stack_bottom = PhysicalAddress(stack_bottom as u64).to_kernel_virtual();
|
|
|
|
|
let stack_bottom_page = Page::containing_address(stack_bottom);
|
|
|
|
|
let stack_bottom = PhysAddr(stack_bottom as u64).to_kernel_virtual();
|
|
|
|
|
let stack_bottom_page = Page::of_addr(stack_bottom);
|
|
|
|
|
active_table.unmap(stack_bottom_page, allocator);
|
|
|
|
|
println!("guard page at {:#x}", stack_bottom_page.start_address());
|
|
|
|
|
|
|
|
|
@ -157,13 +156,13 @@ impl MemoryController {
|
|
|
|
|
size_in_pages)
|
|
|
|
|
}
|
|
|
|
|
pub fn map_page_identity(&mut self, addr: usize) {
|
|
|
|
|
let frame = Frame::containing_address(addr);
|
|
|
|
|
let frame = Frame::of_addr(addr);
|
|
|
|
|
let flags = EntryFlags::WRITABLE;
|
|
|
|
|
self.active_table.identity_map(frame, flags, &mut self.frame_allocator);
|
|
|
|
|
}
|
|
|
|
|
pub fn map_page_p2v(&mut self, addr: PhysicalAddress) {
|
|
|
|
|
let page = Page::containing_address(addr.to_kernel_virtual());
|
|
|
|
|
let frame = Frame::containing_address(addr.get());
|
|
|
|
|
pub fn map_page_p2v(&mut self, addr: PhysAddr) {
|
|
|
|
|
let page = Page::of_addr(addr.to_kernel_virtual());
|
|
|
|
|
let frame = Frame::of_addr(addr.get());
|
|
|
|
|
let flags = EntryFlags::WRITABLE;
|
|
|
|
|
self.active_table.map_to(page, frame, flags, &mut self.frame_allocator);
|
|
|
|
|
}
|
|
|
|
|