tlb added, acpi still faults with the new memory
This commit is contained in:
parent
f0456aa7fd
commit
ec1e7c8a5b
10 changed files with 60 additions and 30 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(); }
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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
10
kernel-rs/src/x86/tlb.rs
Normal 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); }
|
||||
}
|
||||
Loading…
Reference in a new issue