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,