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