tlb added, acpi still faults with the new memory

This commit is contained in:
Jack Halford 2018-03-12 14:53:26 +01:00
parent f0456aa7fd
commit ec1e7c8a5b
10 changed files with 60 additions and 30 deletions

View file

@ -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

View file

@ -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);
}
}

View file

@ -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();
}

View file

@ -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(); }
}

View file

@ -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<Table<Level2>>,
@ -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);
}
}

View file

@ -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<A>(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<A>(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<A>(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<A>(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);

View file

@ -51,6 +51,7 @@ impl<L> Table<L> 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");

View file

@ -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();
}

View file

@ -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");
}

10
kernel-rs/src/x86/tlb.rs Normal file
View file

@ -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); }
}