From ec1e7c8a5bf7f21d14f4a892f220b2e00208ad02 Mon Sep 17 00:00:00 2001 From: Jack Halford Date: Mon, 12 Mar 2018 14:53:26 +0100 Subject: [PATCH] tlb added, acpi still faults with the new memory --- kernel-rs/src/arch/x86/boot.asm | 8 +++----- kernel-rs/src/arch/x86/linker.ld | 25 ++++++++++++++++++++++--- kernel-rs/src/context.rs | 7 ++----- kernel-rs/src/lib.rs | 4 ++-- kernel-rs/src/memory/paging/mapper.rs | 8 +++++--- kernel-rs/src/memory/paging/mod.rs | 21 +++++++++++++-------- kernel-rs/src/memory/paging/table.rs | 1 + kernel-rs/src/vga/mod.rs | 4 ---- kernel-rs/src/x86/mod.rs | 2 ++ kernel-rs/src/x86/tlb.rs | 10 ++++++++++ 10 files changed, 60 insertions(+), 30 deletions(-) create mode 100644 kernel-rs/src/x86/tlb.rs diff --git a/kernel-rs/src/arch/x86/boot.asm b/kernel-rs/src/arch/x86/boot.asm index 72a2fbe3..8615c283 100644 --- a/kernel-rs/src/arch/x86/boot.asm +++ b/kernel-rs/src/arch/x86/boot.asm @@ -34,7 +34,7 @@ set_up_page_tables: or eax, 0b11 ; present + writable mov [p2_table + 1023 * 4], eax - ; map each P2 entry to a huge 2MiB page + ; map each P2 entry to a huge 4MiB page mov ecx, 0 ; counter variable .map_p2_table: @@ -45,7 +45,7 @@ set_up_page_tables: mov [p2_table + ecx * 4], eax ; map ecx-th entry inc ecx ; increase counter - cmp ecx, 1023 ; if counter == 1023, the whole P2 table is mapped + cmp ecx, 20 ; if counter == 1023, the whole P2 table is mapped jne .map_p2_table ; else map the next entry ret @@ -85,10 +85,8 @@ section .bss align 4096 p2_table: resb 4096 -p1_table: - resb 4096 stack_bottom: - resb 4096 * 4 + resb 4096 * 8 stack_top: section .gdt diff --git a/kernel-rs/src/arch/x86/linker.ld b/kernel-rs/src/arch/x86/linker.ld index 27f2ae00..d02b7510 100644 --- a/kernel-rs/src/arch/x86/linker.ld +++ b/kernel-rs/src/arch/x86/linker.ld @@ -3,8 +3,8 @@ OUTPUT_FORMAT(elf32-i386) SECTIONS { /* GDT for the win */ - . = 0x800; - .gdt : {KEEP(*(.gdt))} + /* . = 0x800; */ + /* .gdt : {KEEP(*(.gdt))} */ /* VGA, cannot use section for this */ VGA_PTR = 0xb8000; @@ -45,6 +45,25 @@ SECTIONS { .bss : { - *(.bss .bss.*)} + *(.bss .bss.*) . = ALIGN(4K); } + + .gdt : + { + *(.gdt) + . = ALIGN(4K); + } + + .got : + { + *(.got) + . = ALIGN(4K); + } + + .got.plt : + { + *(.got.plt) + . = ALIGN(4K); + } +} diff --git a/kernel-rs/src/context.rs b/kernel-rs/src/context.rs index 38e5dd0a..fd258849 100644 --- a/kernel-rs/src/context.rs +++ b/kernel-rs/src/context.rs @@ -43,9 +43,6 @@ impl Context vga2, } } - - - } pub fn init_screen() { @@ -104,8 +101,8 @@ fn context() -> &'static mut Context { } pub fn init(multiboot_info_addr: usize) { - // unsafe { CONTEXT = Some(Context::new(multiboot_info_addr)) }; + unsafe { CONTEXT = Some(Context::new(multiboot_info_addr)) }; // memory::remap_the_kernel(frame_allocator(), boot_info()); - // self::init_screen(); + self::init_screen(); } diff --git a/kernel-rs/src/lib.rs b/kernel-rs/src/lib.rs index 172fab12..6ea1a015 100644 --- a/kernel-rs/src/lib.rs +++ b/kernel-rs/src/lib.rs @@ -30,8 +30,8 @@ pub mod x86; #[no_mangle] pub extern fn kmain(multiboot_info_addr: usize) -> ! { context::init(multiboot_info_addr); - loop {} - acpi::init().unwrap(); + // println!("init done!"); + // acpi::init().unwrap(); loop { keyboard::kbd_callback(); } } diff --git a/kernel-rs/src/memory/paging/mapper.rs b/kernel-rs/src/memory/paging/mapper.rs index e3d2074f..93d5be86 100644 --- a/kernel-rs/src/memory/paging/mapper.rs +++ b/kernel-rs/src/memory/paging/mapper.rs @@ -3,6 +3,7 @@ use super::entry::*; use super::table::{self, Table, Level2}; use memory::{PAGE_SIZE, Frame, FrameAllocator}; use core::ptr::Unique; +use x86; pub struct Mapper { p2: Unique>, @@ -39,7 +40,7 @@ impl Mapper { let p2_entry = &self.p2()[page.p2_index()]; if let Some(start_frame) = p2_entry.pointed_frame() { if p2_entry.flags().contains(EntryFlags::HUGE_PAGE) { - // 2MiB alignment check + // 4KiB alignment check assert!(start_frame.number % ENTRY_COUNT == 0); return Some(Frame { number: start_frame.number + page.p1_index() @@ -89,7 +90,8 @@ impl Mapper { .expect("mapping code does not support huge pages"); let frame = p1[page.p1_index()].pointed_frame().unwrap(); p1[page.p1_index()].set_unused(); - // TODO flush the tlb - allocator.deallocate_frame(frame); + x86::tlb::flush(page.start_address()); + // TODO + // allocator.deallocate_frame(frame); } } diff --git a/kernel-rs/src/memory/paging/mod.rs b/kernel-rs/src/memory/paging/mod.rs index 5e7277c4..45a43f81 100644 --- a/kernel-rs/src/memory/paging/mod.rs +++ b/kernel-rs/src/memory/paging/mod.rs @@ -84,9 +84,9 @@ impl ActivePageTable { // map temp page to current p2 let p2_table = temporary_page.map_table_frame(backup.clone(), self); - // overwrite recrusive map + // overwrite recursive map self.p2_mut()[1023].set(table.p2_frame.clone(), EntryFlags::PRESENT | EntryFlags::WRITABLE); - //TODO tlb flush all + x86::tlb::flush_all(); // execute f in the new context f(self); @@ -98,12 +98,15 @@ impl ActivePageTable { pub fn switch(&mut self, new_table: InactivePageTable) -> InactivePageTable { let p2_frame = Frame::containing_address(x86::cr3() as usize); + + println!("old p2_frame at {}", p2_frame.number); let old_table = InactivePageTable { p2_frame, }; unsafe { let frame = Frame::containing_address(new_table.p2_frame.start_address()); + println!("new p2_frame at {:#x}", new_table.p2_frame.start_address()); x86::cr3_write(frame.start_address()); } @@ -124,8 +127,9 @@ impl InactivePageTable { let table = temporary_page.map_table_frame(frame.clone(), active_table); table.zero(); + // set up recursive mapping for the table - table[ENTRY_COUNT - 1].set(frame.clone(), EntryFlags::PRESENT | EntryFlags:: WRITABLE) + table[1023].set(frame.clone(), EntryFlags::PRESENT | EntryFlags:: WRITABLE) } temporary_page.unmap(active_table); InactivePageTable { p2_frame: frame } @@ -138,7 +142,6 @@ pub fn remap_the_kernel(allocator: &mut A, boot_info: &BootInformation) { let mut temporary_page = TemporaryPage::new(Page { number: 0xcafe }, allocator); - let mut active_table = unsafe { ActivePageTable::new() }; let mut new_table = { let frame = allocator.allocate_frame().expect("no more frames"); @@ -158,7 +161,6 @@ pub fn remap_the_kernel(allocator: &mut A, boot_info: &BootInformation) use self::entry::EntryFlags; if !section.is_allocated() { - //section is not loaded to memory continue; } assert!(section.start_address() % PAGE_SIZE as u64 == 0, @@ -187,8 +189,11 @@ pub fn remap_the_kernel(allocator: &mut A, boot_info: &BootInformation) let old_p2_page = Page::containing_address( old_table.p2_frame.start_address() ); + active_table.unmap(old_p2_page, allocator); + println!("guard page at {:#x}", old_p2_page.start_address()); + println!("cr3 = {:#x}", x86::cr3()); active_table } @@ -201,9 +206,9 @@ pub fn test_paging(allocator: &mut A) let addr = 0xffff_f000; let page = Page::containing_address(addr); let frame = allocator.allocate_frame().expect("no more frames"); - // println!("None = {:?}, map to {:?}", - // page_table.translate(addr), - // frame); + println!("None = {:?}, map to {:?}", + page_table.translate(addr), + frame); println!("check 0"); flush!(); page_table.map_to(page, frame, EntryFlags::empty(), allocator); diff --git a/kernel-rs/src/memory/paging/table.rs b/kernel-rs/src/memory/paging/table.rs index da35e011..2a9e9a86 100644 --- a/kernel-rs/src/memory/paging/table.rs +++ b/kernel-rs/src/memory/paging/table.rs @@ -51,6 +51,7 @@ impl Table where L: HierarchicalLevel where A: FrameAllocator { if self.next_table(index).is_none() { + println!("index={} flags={:#b}", index, self[index].flags()); assert!(!self[index].flags().contains(EntryFlags::HUGE_PAGE), "mapping code does not support huge pages"); let frame = allocator.allocate_frame().expect("no frames available"); diff --git a/kernel-rs/src/vga/mod.rs b/kernel-rs/src/vga/mod.rs index 605a84f1..0a09fe1b 100644 --- a/kernel-rs/src/vga/mod.rs +++ b/kernel-rs/src/vga/mod.rs @@ -5,7 +5,6 @@ pub use self::color::{Color, ColorCode}; use context; use cpuio; use console; -use x86; #[derive(Debug, Clone, Copy)] #[repr(C)] @@ -165,10 +164,7 @@ impl Writer { pub fn flush(&mut self) { let slice = unsafe { core::slice::from_raw_parts_mut(0xb8000 as *mut u8, 4000) }; - // let cr0 = x86::cr0() & !(1 << 31); - // unsafe { x86::cr0_write(cr0); } slice.as_mut().clone_from_slice(&self.buffer); - // unsafe { x86::cr0_write(cr0 | (1 << 31)); } self.flush_cursor(); } diff --git a/kernel-rs/src/x86/mod.rs b/kernel-rs/src/x86/mod.rs index 3659eb88..7d9cf902 100644 --- a/kernel-rs/src/x86/mod.rs +++ b/kernel-rs/src/x86/mod.rs @@ -1,5 +1,7 @@ //! x86 (32 bit) only +pub mod tlb; + pub unsafe fn cr0_write(val: usize) { asm!("mov $0, %cr0" :: "r"(val) : "memory"); } diff --git a/kernel-rs/src/x86/tlb.rs b/kernel-rs/src/x86/tlb.rs new file mode 100644 index 00000000..1890ebaa --- /dev/null +++ b/kernel-rs/src/x86/tlb.rs @@ -0,0 +1,10 @@ +use super::*; + +pub fn flush(addr: usize) { + unsafe { asm!("invlpg ($0)" :: "r"(addr) : "memory")} +} + +pub fn flush_all() { + let cr3 = cr3(); + unsafe { cr3_write(cr3); } +}