diff --git a/kernel-rs/Makefile b/kernel-rs/Makefile
index e43fe467..a26b3e36 100644
--- a/kernel-rs/Makefile
+++ b/kernel-rs/Makefile
@@ -10,7 +10,7 @@ endif
project := bluesnow
arch ?= x86
-NASM := /usr/bin/nasm -f elf
+NASM := /usr/bin/nasm -f elf -g
LD := /usr/bin/ld -m elf_i386 -L ./ -n --gc-sections
# QEMU := qemu-system-x86_64 -device isa-debug-exit,iobase=0xf4,iosize=0x04 -gdb tcp::$(PORTG) -enable-kvm -monitor telnet:127.0.0.1:$(PORT),server,nowait
QEMU := qemu-system-x86_64 -gdb tcp::$(PORTG) -enable-kvm -monitor telnet:127.0.0.1:$(PORT),server,nowait
diff --git a/kernel-rs/src/arch/x86/boot.asm b/kernel-rs/src/arch/x86/boot.asm
index c6cb7cb3..72a2fbe3 100644
--- a/kernel-rs/src/arch/x86/boot.asm
+++ b/kernel-rs/src/arch/x86/boot.asm
@@ -12,8 +12,8 @@ start:
call check_multiboot
call set_up_page_tables
- ; call enable_pse
- ; call enable_paging
+ call enable_pse
+ call enable_paging
; load the new gdt
lgdt [GDTR.ptr]
@@ -39,9 +39,9 @@ set_up_page_tables:
.map_p2_table:
; map ecx-th P2 entry to a huge page that starts at address 2MiB*ecx
- mov eax, 0x200000 ; 2MiB
+ mov eax, 0x400000 ; 4MiB
mul ecx ; start address of ecx-th page
- or eax, 0b10000011 ; present + writable + huge
+ or eax, 0b10000011 ; huge + present + writable
mov [p2_table + ecx * 4], eax ; map ecx-th entry
inc ecx ; increase counter
@@ -54,7 +54,7 @@ set_up_page_tables:
enable_pse:
; enable PSE in the cr4 register
mov eax, cr4
- or eax, 1 << 2
+ or eax, 1 << 4
mov cr4, eax
ret
@@ -148,4 +148,3 @@ GDTR:
.ptr:
DW .gdt_bottom - .gdt_top - 1 ; length of the structure minus 1
DD .gdt_top ; pointer to top of gdt
-
diff --git a/kernel-rs/src/context.rs b/kernel-rs/src/context.rs
index 25e0e30b..38e5dd0a 100644
--- a/kernel-rs/src/context.rs
+++ b/kernel-rs/src/context.rs
@@ -104,8 +104,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();
+ // memory::remap_the_kernel(frame_allocator(), boot_info());
+ // self::init_screen();
}
diff --git a/kernel-rs/src/lib.rs b/kernel-rs/src/lib.rs
index 786bd74e..172fab12 100644
--- a/kernel-rs/src/lib.rs
+++ b/kernel-rs/src/lib.rs
@@ -30,6 +30,7 @@ pub mod x86;
#[no_mangle]
pub extern fn kmain(multiboot_info_addr: usize) -> ! {
context::init(multiboot_info_addr);
+ loop {}
acpi::init().unwrap();
loop { keyboard::kbd_callback(); }
}
diff --git a/kernel-rs/src/memory/paging/entry.rs b/kernel-rs/src/memory/paging/entry.rs
index 0f2803c7..26edb9c1 100644
--- a/kernel-rs/src/memory/paging/entry.rs
+++ b/kernel-rs/src/memory/paging/entry.rs
@@ -1,6 +1,7 @@
use memory::Frame;
pub struct Entry(u32);
+use multiboot2::ElfSection;
impl Entry {
pub fn is_unused(&self) -> bool {
@@ -45,3 +46,21 @@ bitflags! {
// const NO_EXECUTE = 1 << 63;
}
}
+
+impl EntryFlags {
+ pub fn from_elf_section_flags(section: &ElfSection) -> EntryFlags {
+ use multiboot2::ElfSectionFlags;
+
+ let mut flags = EntryFlags::empty();
+ if section.flags().contains(ElfSectionFlags::ALLOCATED) {
+ flags = flags | EntryFlags::PRESENT;
+ }
+ if section.flags().contains(ElfSectionFlags::WRITABLE) {
+ flags = flags | EntryFlags::WRITABLE;
+ }
+ // if !section.flags().contains(ElfSectionFlags::EXECUTABLE) {
+ // flags = flags | EntryFlags::NO_EXECUTE;
+ // }
+ flags
+ }
+}
diff --git a/kernel-rs/src/memory/paging/mapper.rs b/kernel-rs/src/memory/paging/mapper.rs
index b17d4ee7..e3d2074f 100644
--- a/kernel-rs/src/memory/paging/mapper.rs
+++ b/kernel-rs/src/memory/paging/mapper.rs
@@ -1,6 +1,6 @@
use super::{VirtualAddress, PhysicalAddress, Page, ENTRY_COUNT};
use super::entry::*;
-use super::table::{self, Table, Level2, Level1};
+use super::table::{self, Table, Level2};
use memory::{PAGE_SIZE, Frame, FrameAllocator};
use core::ptr::Unique;
diff --git a/kernel-rs/src/memory/paging/mod.rs b/kernel-rs/src/memory/paging/mod.rs
index 49981a40..5e7277c4 100644
--- a/kernel-rs/src/memory/paging/mod.rs
+++ b/kernel-rs/src/memory/paging/mod.rs
@@ -79,14 +79,20 @@ impl ActivePageTable {
f: F)
where F: FnOnce(&mut Mapper)
{
- self.p2_mut()[ENTRY_COUNT -1].set(table.p2_frame.clone(), EntryFlags::PRESENT | EntryFlags::WRITABLE);
+ let backup = Frame::containing_address(x86::cr3());
+ // map temp page to current p2
+ let p2_table = temporary_page.map_table_frame(backup.clone(), self);
+
+ // overwrite recrusive map
+ self.p2_mut()[1023].set(table.p2_frame.clone(), EntryFlags::PRESENT | EntryFlags::WRITABLE);
//TODO tlb flush all
- // execute f in the nex context
+ // execute f in the new context
f(self);
// TODO restore recursive mapping to original p2 table
+ p2_table[1023].set(backup, EntryFlags::PRESENT | EntryFlags::WRITABLE);
}
pub fn switch(&mut self, new_table: InactivePageTable) -> InactivePageTable {
@@ -127,6 +133,7 @@ impl InactivePageTable {
}
pub fn remap_the_kernel(allocator: &mut A, boot_info: &BootInformation)
+ -> ActivePageTable
where A: FrameAllocator
{
let mut temporary_page = TemporaryPage::new(Page { number: 0xcafe },
@@ -139,6 +146,11 @@ pub fn remap_the_kernel(allocator: &mut A, boot_info: &BootInformation)
};
active_table.with(&mut new_table, &mut temporary_page, |mapper| {
+
+ // identity map the VGA text buffer
+ let vga_buffer_frame = Frame::containing_address(0xb8000);
+ mapper.identity_map(vga_buffer_frame, EntryFlags::WRITABLE, allocator);
+
let elf_sections_tag = boot_info.elf_sections_tag()
.expect("Memory map tag required");
@@ -155,8 +167,7 @@ pub fn remap_the_kernel(allocator: &mut A, boot_info: &BootInformation)
println!("mapping section at addr: {:#x}, size: {:#x}",
section.start_address(), section.size());
- let flags = EntryFlags::WRITABLE; //TODO use real section flags
-
+ let flags = EntryFlags::from_elf_section_flags(§ion);
let start_frame = Frame::containing_address(section.start_address() as usize);
let end_frame = Frame::containing_address(section.end_address() as usize - 1);
for frame in Frame::range_inclusive(start_frame, end_frame) {
@@ -164,9 +175,6 @@ pub fn remap_the_kernel(allocator: &mut A, boot_info: &BootInformation)
}
}
- let vga_buffer_frame = Frame::containing_address(0xb8000);
- mapper.identity_map(vga_buffer_frame, EntryFlags::WRITABLE, allocator);
-
let multiboot_start = Frame::containing_address(boot_info.start_address());
let multiboot_end = Frame::containing_address(boot_info.end_address() - 1);
for frame in Frame::range_inclusive(multiboot_start, multiboot_end) {
@@ -175,7 +183,14 @@ pub fn remap_the_kernel(allocator: &mut A, boot_info: &BootInformation)
});
let old_table = active_table.switch(new_table);
- println!("new table!");
+
+ 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());
+
+ active_table
}
pub fn test_paging(allocator: &mut A)
diff --git a/kernel-rs/src/memory/paging/table.rs b/kernel-rs/src/memory/paging/table.rs
index 57988f06..da35e011 100644
--- a/kernel-rs/src/memory/paging/table.rs
+++ b/kernel-rs/src/memory/paging/table.rs
@@ -55,8 +55,7 @@ impl Table where L: HierarchicalLevel
"mapping code does not support huge pages");
let frame = allocator.allocate_frame().expect("no frames available");
self[index].set(frame, EntryFlags::PRESENT | EntryFlags::WRITABLE);
- panic!("wtf");
- self.next_table_mut(index).expect("real wtf now").zero()
+ self.next_table_mut(index).expect("next_table_mut gave None").zero()
}
self.next_table_mut(index).expect("no next table 2")
}
diff --git a/kernel-rs/src/vga/mod.rs b/kernel-rs/src/vga/mod.rs
index 2ab62cbd..605a84f1 100644
--- a/kernel-rs/src/vga/mod.rs
+++ b/kernel-rs/src/vga/mod.rs
@@ -165,11 +165,10 @@ 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); }
+ // 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)); }
+ // unsafe { x86::cr0_write(cr0 | (1 << 31)); }
self.flush_cursor();
}
diff --git a/kernel-rs/x86-bluesnow.json b/kernel-rs/x86-bluesnow.json
index 6e895d2b..22f12e60 100644
--- a/kernel-rs/x86-bluesnow.json
+++ b/kernel-rs/x86-bluesnow.json
@@ -1,6 +1,9 @@
{
"arch": "x86",
+
+ "_comment": "http://llvm.org/docs/LangRef.html#data-layout",
"data-layout": "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128",
+
"llvm-target": "i686-unknown-none",
"linker-flavor": "gcc",
"no-compiler-rt": true,