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
|
or eax, 0b11 ; present + writable
|
||||||
mov [p2_table + 1023 * 4], eax
|
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
|
mov ecx, 0 ; counter variable
|
||||||
|
|
||||||
.map_p2_table:
|
.map_p2_table:
|
||||||
|
|
@ -45,7 +45,7 @@ set_up_page_tables:
|
||||||
mov [p2_table + ecx * 4], eax ; map ecx-th entry
|
mov [p2_table + ecx * 4], eax ; map ecx-th entry
|
||||||
|
|
||||||
inc ecx ; increase counter
|
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
|
jne .map_p2_table ; else map the next entry
|
||||||
|
|
||||||
ret
|
ret
|
||||||
|
|
@ -85,10 +85,8 @@ section .bss
|
||||||
align 4096
|
align 4096
|
||||||
p2_table:
|
p2_table:
|
||||||
resb 4096
|
resb 4096
|
||||||
p1_table:
|
|
||||||
resb 4096
|
|
||||||
stack_bottom:
|
stack_bottom:
|
||||||
resb 4096 * 4
|
resb 4096 * 8
|
||||||
stack_top:
|
stack_top:
|
||||||
|
|
||||||
section .gdt
|
section .gdt
|
||||||
|
|
|
||||||
|
|
@ -3,8 +3,8 @@ OUTPUT_FORMAT(elf32-i386)
|
||||||
|
|
||||||
SECTIONS {
|
SECTIONS {
|
||||||
/* GDT for the win */
|
/* GDT for the win */
|
||||||
. = 0x800;
|
/* . = 0x800; */
|
||||||
.gdt : {KEEP(*(.gdt))}
|
/* .gdt : {KEEP(*(.gdt))} */
|
||||||
|
|
||||||
/* VGA, cannot use section for this */
|
/* VGA, cannot use section for this */
|
||||||
VGA_PTR = 0xb8000;
|
VGA_PTR = 0xb8000;
|
||||||
|
|
@ -45,6 +45,25 @@ SECTIONS {
|
||||||
|
|
||||||
.bss :
|
.bss :
|
||||||
{
|
{
|
||||||
*(.bss .bss.*)}
|
*(.bss .bss.*)
|
||||||
. = ALIGN(4K);
|
. = ALIGN(4K);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.gdt :
|
||||||
|
{
|
||||||
|
*(.gdt)
|
||||||
|
. = ALIGN(4K);
|
||||||
|
}
|
||||||
|
|
||||||
|
.got :
|
||||||
|
{
|
||||||
|
*(.got)
|
||||||
|
. = ALIGN(4K);
|
||||||
|
}
|
||||||
|
|
||||||
|
.got.plt :
|
||||||
|
{
|
||||||
|
*(.got.plt)
|
||||||
|
. = ALIGN(4K);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -43,9 +43,6 @@ impl Context
|
||||||
vga2,
|
vga2,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init_screen() {
|
pub fn init_screen() {
|
||||||
|
|
@ -104,8 +101,8 @@ fn context() -> &'static mut Context {
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn init(multiboot_info_addr: usize) {
|
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());
|
// memory::remap_the_kernel(frame_allocator(), boot_info());
|
||||||
// self::init_screen();
|
self::init_screen();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -30,8 +30,8 @@ pub mod x86;
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern fn kmain(multiboot_info_addr: usize) -> ! {
|
pub extern fn kmain(multiboot_info_addr: usize) -> ! {
|
||||||
context::init(multiboot_info_addr);
|
context::init(multiboot_info_addr);
|
||||||
loop {}
|
// println!("init done!");
|
||||||
acpi::init().unwrap();
|
// acpi::init().unwrap();
|
||||||
loop { keyboard::kbd_callback(); }
|
loop { keyboard::kbd_callback(); }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ use super::entry::*;
|
||||||
use super::table::{self, Table, Level2};
|
use super::table::{self, Table, Level2};
|
||||||
use memory::{PAGE_SIZE, Frame, FrameAllocator};
|
use memory::{PAGE_SIZE, Frame, FrameAllocator};
|
||||||
use core::ptr::Unique;
|
use core::ptr::Unique;
|
||||||
|
use x86;
|
||||||
|
|
||||||
pub struct Mapper {
|
pub struct Mapper {
|
||||||
p2: Unique<Table<Level2>>,
|
p2: Unique<Table<Level2>>,
|
||||||
|
|
@ -39,7 +40,7 @@ impl Mapper {
|
||||||
let p2_entry = &self.p2()[page.p2_index()];
|
let p2_entry = &self.p2()[page.p2_index()];
|
||||||
if let Some(start_frame) = p2_entry.pointed_frame() {
|
if let Some(start_frame) = p2_entry.pointed_frame() {
|
||||||
if p2_entry.flags().contains(EntryFlags::HUGE_PAGE) {
|
if p2_entry.flags().contains(EntryFlags::HUGE_PAGE) {
|
||||||
// 2MiB alignment check
|
// 4KiB alignment check
|
||||||
assert!(start_frame.number % ENTRY_COUNT == 0);
|
assert!(start_frame.number % ENTRY_COUNT == 0);
|
||||||
return Some(Frame {
|
return Some(Frame {
|
||||||
number: start_frame.number + page.p1_index()
|
number: start_frame.number + page.p1_index()
|
||||||
|
|
@ -89,7 +90,8 @@ impl Mapper {
|
||||||
.expect("mapping code does not support huge pages");
|
.expect("mapping code does not support huge pages");
|
||||||
let frame = p1[page.p1_index()].pointed_frame().unwrap();
|
let frame = p1[page.p1_index()].pointed_frame().unwrap();
|
||||||
p1[page.p1_index()].set_unused();
|
p1[page.p1_index()].set_unused();
|
||||||
// TODO flush the tlb
|
x86::tlb::flush(page.start_address());
|
||||||
allocator.deallocate_frame(frame);
|
// TODO
|
||||||
|
// allocator.deallocate_frame(frame);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -84,9 +84,9 @@ impl ActivePageTable {
|
||||||
// map temp page to current p2
|
// map temp page to current p2
|
||||||
let p2_table = temporary_page.map_table_frame(backup.clone(), self);
|
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);
|
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
|
// execute f in the new context
|
||||||
f(self);
|
f(self);
|
||||||
|
|
@ -98,12 +98,15 @@ impl ActivePageTable {
|
||||||
pub fn switch(&mut self, new_table: InactivePageTable) -> InactivePageTable {
|
pub fn switch(&mut self, new_table: InactivePageTable) -> InactivePageTable {
|
||||||
|
|
||||||
let p2_frame = Frame::containing_address(x86::cr3() as usize);
|
let p2_frame = Frame::containing_address(x86::cr3() as usize);
|
||||||
|
|
||||||
|
println!("old p2_frame at {}", p2_frame.number);
|
||||||
let old_table = InactivePageTable {
|
let old_table = InactivePageTable {
|
||||||
p2_frame,
|
p2_frame,
|
||||||
};
|
};
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let frame = Frame::containing_address(new_table.p2_frame.start_address());
|
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());
|
x86::cr3_write(frame.start_address());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -124,8 +127,9 @@ impl InactivePageTable {
|
||||||
let table = temporary_page.map_table_frame(frame.clone(),
|
let table = temporary_page.map_table_frame(frame.clone(),
|
||||||
active_table);
|
active_table);
|
||||||
table.zero();
|
table.zero();
|
||||||
|
|
||||||
// set up recursive mapping for the table
|
// 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);
|
temporary_page.unmap(active_table);
|
||||||
InactivePageTable { p2_frame: frame }
|
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 },
|
let mut temporary_page = TemporaryPage::new(Page { number: 0xcafe },
|
||||||
allocator);
|
allocator);
|
||||||
|
|
||||||
let mut active_table = unsafe { ActivePageTable::new() };
|
let mut active_table = unsafe { ActivePageTable::new() };
|
||||||
let mut new_table = {
|
let mut new_table = {
|
||||||
let frame = allocator.allocate_frame().expect("no more frames");
|
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;
|
use self::entry::EntryFlags;
|
||||||
|
|
||||||
if !section.is_allocated() {
|
if !section.is_allocated() {
|
||||||
//section is not loaded to memory
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
assert!(section.start_address() % PAGE_SIZE as u64 == 0,
|
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(
|
let old_p2_page = Page::containing_address(
|
||||||
old_table.p2_frame.start_address()
|
old_table.p2_frame.start_address()
|
||||||
);
|
);
|
||||||
|
|
||||||
active_table.unmap(old_p2_page, allocator);
|
active_table.unmap(old_p2_page, allocator);
|
||||||
|
|
||||||
println!("guard page at {:#x}", old_p2_page.start_address());
|
println!("guard page at {:#x}", old_p2_page.start_address());
|
||||||
|
println!("cr3 = {:#x}", x86::cr3());
|
||||||
|
|
||||||
active_table
|
active_table
|
||||||
}
|
}
|
||||||
|
|
@ -201,9 +206,9 @@ pub fn test_paging<A>(allocator: &mut A)
|
||||||
let addr = 0xffff_f000;
|
let addr = 0xffff_f000;
|
||||||
let page = Page::containing_address(addr);
|
let page = Page::containing_address(addr);
|
||||||
let frame = allocator.allocate_frame().expect("no more frames");
|
let frame = allocator.allocate_frame().expect("no more frames");
|
||||||
// println!("None = {:?}, map to {:?}",
|
println!("None = {:?}, map to {:?}",
|
||||||
// page_table.translate(addr),
|
page_table.translate(addr),
|
||||||
// frame);
|
frame);
|
||||||
println!("check 0");
|
println!("check 0");
|
||||||
flush!();
|
flush!();
|
||||||
page_table.map_to(page, frame, EntryFlags::empty(), allocator);
|
page_table.map_to(page, frame, EntryFlags::empty(), allocator);
|
||||||
|
|
|
||||||
|
|
@ -51,6 +51,7 @@ impl<L> Table<L> where L: HierarchicalLevel
|
||||||
where A: FrameAllocator
|
where A: FrameAllocator
|
||||||
{
|
{
|
||||||
if self.next_table(index).is_none() {
|
if self.next_table(index).is_none() {
|
||||||
|
println!("index={} flags={:#b}", index, self[index].flags());
|
||||||
assert!(!self[index].flags().contains(EntryFlags::HUGE_PAGE),
|
assert!(!self[index].flags().contains(EntryFlags::HUGE_PAGE),
|
||||||
"mapping code does not support huge pages");
|
"mapping code does not support huge pages");
|
||||||
let frame = allocator.allocate_frame().expect("no frames available");
|
let frame = allocator.allocate_frame().expect("no frames available");
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,6 @@ pub use self::color::{Color, ColorCode};
|
||||||
use context;
|
use context;
|
||||||
use cpuio;
|
use cpuio;
|
||||||
use console;
|
use console;
|
||||||
use x86;
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
#[repr(C)]
|
#[repr(C)]
|
||||||
|
|
@ -165,10 +164,7 @@ impl Writer {
|
||||||
|
|
||||||
pub fn flush(&mut self) {
|
pub fn flush(&mut self) {
|
||||||
let slice = unsafe { core::slice::from_raw_parts_mut(0xb8000 as *mut u8, 4000) };
|
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);
|
slice.as_mut().clone_from_slice(&self.buffer);
|
||||||
// unsafe { x86::cr0_write(cr0 | (1 << 31)); }
|
|
||||||
self.flush_cursor();
|
self.flush_cursor();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,7 @@
|
||||||
//! x86 (32 bit) only
|
//! x86 (32 bit) only
|
||||||
|
|
||||||
|
pub mod tlb;
|
||||||
|
|
||||||
pub unsafe fn cr0_write(val: usize) {
|
pub unsafe fn cr0_write(val: usize) {
|
||||||
asm!("mov $0, %cr0" :: "r"(val) : "memory");
|
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