From 5ff8596233e5946013d15b29c3779e4531fcc779 Mon Sep 17 00:00:00 2001 From: Julien CLEMENT Date: Wed, 8 Dec 2021 16:20:38 +0100 Subject: [PATCH] feat(paging): map kernel using elf section flags Signed-off-by: Julien CLEMENT --- src/lib.rs | 17 ++++++++++++++--- src/memory/paging/mod.rs | 28 +++++++++++++++++++++++----- 2 files changed, 37 insertions(+), 8 deletions(-) diff --git a/src/lib.rs b/src/lib.rs index 2e47eca..5e9eacd 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -12,6 +12,8 @@ extern crate multiboot2; use core::panic::PanicInfo; use vga::{Color, ColorCode}; +use memory::paging::{Size4KiB, FrameAllocator}; +use multiboot2::BootInformation; #[panic_handler] fn panic_handler(info: &PanicInfo) -> ! { @@ -26,14 +28,24 @@ pub fn hlt_loop() -> ! { } } -pub fn init() { +pub fn init(frame_allocator: &mut A, boot_info: &BootInformation) + where A: FrameAllocator +{ vga::change_color(ColorCode::new(Color::LightCyan, Color::Black)); println!("Starting init"); + enable_nxe_bit(); + memory::kernel_remap(frame_allocator, boot_info); gdt::init_gdt(); interrupts::init_idt(); vga::change_color(ColorCode::new(Color::LightGreen, Color::Black)); } +fn enable_nxe_bit() { + println!("Enabling nxe bit"); + use x86_64::registers::control::{Efer, EferFlags}; + unsafe { Efer::update(|efer| *efer |= EferFlags::NO_EXECUTE_ENABLE) } +} + fn get_frame_allocator(multiboot_info_addr: usize) -> memory::AreaFrameAllocator { let boot_info = unsafe { multiboot2::load(multiboot_info_addr) }; let memory_map_tag = boot_info.memory_map_tag().expect("Memory map tag required"); @@ -62,9 +74,8 @@ pub extern "C" fn julios_main(multiboot_info_addr: usize) -> ! { let mut frame_allocator = get_frame_allocator(multiboot_info_addr); - memory::kernel_remap(&mut frame_allocator, boot_info); - init(); + init(&mut frame_allocator, &boot_info); println!("***JuliOS V0.1.0***"); serial_println!("Hello serial"); memory::paging::test_paging(&mut frame_allocator); diff --git a/src/memory/paging/mod.rs b/src/memory/paging/mod.rs index 2b5d9d5..835fc12 100644 --- a/src/memory/paging/mod.rs +++ b/src/memory/paging/mod.rs @@ -1,4 +1,4 @@ -use multiboot2::BootInformation; +use multiboot2::{BootInformation, ElfSection}; pub use x86_64::structures::paging::{FrameAllocator, Size4KiB, PageTable, RecursivePageTable, Page, PageTableFlags as Flags, Mapper, PhysFrame as Frame}; use crate::println; use x86_64::{VirtAddr, PhysAddr}; @@ -10,9 +10,29 @@ mod temporary_page; pub const P4: *mut PageTable = 0o177777_777_777_777_777_0000 as *mut _; +fn get_flags_from_elf_section(section: &ElfSection) -> Flags { + use multiboot2::{ELF_SECTION_ALLOCATED, ELF_SECTION_WRITABLE, + ELF_SECTION_EXECUTABLE}; + + let mut flags = Flags::empty(); + + if section.flags().contains(ELF_SECTION_ALLOCATED) { + flags = flags | Flags::PRESENT; + } + if section.flags().contains(ELF_SECTION_WRITABLE) { + flags = flags | Flags::WRITABLE; + } + if !section.flags().contains(ELF_SECTION_EXECUTABLE) { + flags = flags | Flags::NO_EXECUTE; + } + + flags +} + pub fn kernel_remap(allocator: &mut A, boot_info: &BootInformation) where A: FrameAllocator { + println!("Remapping kernel"); let mut temporary_page = TemporaryPage::new(Page::containing_address(VirtAddr::new(0xcafebabe)), allocator); let mut active_table = get_active_page_table(); let mut new_table = { @@ -33,7 +53,7 @@ pub fn kernel_remap(allocator: &mut A, boot_info: &BootInformation) "sections need to be page aligned"); - let flags = Flags::WRITABLE | Flags::PRESENT; + let flags = get_flags_from_elf_section(section); let start_frame = Frame::::containing_address(PhysAddr::new(section.start_address() as u64)); let end_frame = Frame::containing_address(PhysAddr::new(section.end_address() as u64 - 1)); @@ -129,7 +149,5 @@ pub fn test_paging(allocator: &mut A) let page_ptr: *mut u8 = page.start_address().as_mut_ptr(); let frame_ptr: *mut u8 = frame.start_address().as_u64() as *mut u8; - unsafe { - println!("Page: {:#?}, Frame: {:#?}", page_ptr, frame_ptr); - } + println!("Page: {:#?}, Frame: {:#?}", page_ptr, frame_ptr); }