i must have done something right becuase now 0xffff_f000 points to p2 as expected, hurray

This commit is contained in:
Jack Halford 2018-03-11 18:41:34 +01:00
parent bbe2b8b1e6
commit f0456aa7fd
10 changed files with 60 additions and 25 deletions

View file

@ -10,7 +10,7 @@ endif
project := bluesnow project := bluesnow
arch ?= x86 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 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 -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 QEMU := qemu-system-x86_64 -gdb tcp::$(PORTG) -enable-kvm -monitor telnet:127.0.0.1:$(PORT),server,nowait

View file

@ -12,8 +12,8 @@ start:
call check_multiboot call check_multiboot
call set_up_page_tables call set_up_page_tables
; call enable_pse call enable_pse
; call enable_paging call enable_paging
; load the new gdt ; load the new gdt
lgdt [GDTR.ptr] lgdt [GDTR.ptr]
@ -39,9 +39,9 @@ set_up_page_tables:
.map_p2_table: .map_p2_table:
; map ecx-th P2 entry to a huge page that starts at address 2MiB*ecx ; 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 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 mov [p2_table + ecx * 4], eax ; map ecx-th entry
inc ecx ; increase counter inc ecx ; increase counter
@ -54,7 +54,7 @@ set_up_page_tables:
enable_pse: enable_pse:
; enable PSE in the cr4 register ; enable PSE in the cr4 register
mov eax, cr4 mov eax, cr4
or eax, 1 << 2 or eax, 1 << 4
mov cr4, eax mov cr4, eax
ret ret
@ -148,4 +148,3 @@ GDTR:
.ptr: .ptr:
DW .gdt_bottom - .gdt_top - 1 ; length of the structure minus 1 DW .gdt_bottom - .gdt_top - 1 ; length of the structure minus 1
DD .gdt_top ; pointer to top of gdt DD .gdt_top ; pointer to top of gdt

View file

@ -104,8 +104,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();
} }

View file

@ -30,6 +30,7 @@ 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 {}
acpi::init().unwrap(); acpi::init().unwrap();
loop { keyboard::kbd_callback(); } loop { keyboard::kbd_callback(); }
} }

View file

@ -1,6 +1,7 @@
use memory::Frame; use memory::Frame;
pub struct Entry(u32); pub struct Entry(u32);
use multiboot2::ElfSection;
impl Entry { impl Entry {
pub fn is_unused(&self) -> bool { pub fn is_unused(&self) -> bool {
@ -45,3 +46,21 @@ bitflags! {
// const NO_EXECUTE = 1 << 63; // 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
}
}

View file

@ -1,6 +1,6 @@
use super::{VirtualAddress, PhysicalAddress, Page, ENTRY_COUNT}; use super::{VirtualAddress, PhysicalAddress, Page, ENTRY_COUNT};
use super::entry::*; use super::entry::*;
use super::table::{self, Table, Level2, Level1}; 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;

View file

@ -79,14 +79,20 @@ impl ActivePageTable {
f: F) f: F)
where F: FnOnce(&mut Mapper) 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 //TODO tlb flush all
// execute f in the nex context // execute f in the new context
f(self); f(self);
// TODO restore recursive mapping to original p2 table // 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 { pub fn switch(&mut self, new_table: InactivePageTable) -> InactivePageTable {
@ -127,6 +133,7 @@ impl InactivePageTable {
} }
pub fn remap_the_kernel<A>(allocator: &mut A, boot_info: &BootInformation) pub fn remap_the_kernel<A>(allocator: &mut A, boot_info: &BootInformation)
-> ActivePageTable
where A: FrameAllocator where A: FrameAllocator
{ {
let mut temporary_page = TemporaryPage::new(Page { number: 0xcafe }, let mut temporary_page = TemporaryPage::new(Page { number: 0xcafe },
@ -139,6 +146,11 @@ pub fn remap_the_kernel<A>(allocator: &mut A, boot_info: &BootInformation)
}; };
active_table.with(&mut new_table, &mut temporary_page, |mapper| { 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() let elf_sections_tag = boot_info.elf_sections_tag()
.expect("Memory map tag required"); .expect("Memory map tag required");
@ -155,8 +167,7 @@ pub fn remap_the_kernel<A>(allocator: &mut A, boot_info: &BootInformation)
println!("mapping section at addr: {:#x}, size: {:#x}", println!("mapping section at addr: {:#x}, size: {:#x}",
section.start_address(), section.size()); section.start_address(), section.size());
let flags = EntryFlags::WRITABLE; //TODO use real section flags let flags = EntryFlags::from_elf_section_flags(&section);
let start_frame = Frame::containing_address(section.start_address() as usize); let start_frame = Frame::containing_address(section.start_address() as usize);
let end_frame = Frame::containing_address(section.end_address() as usize - 1); let end_frame = Frame::containing_address(section.end_address() as usize - 1);
for frame in Frame::range_inclusive(start_frame, end_frame) { for frame in Frame::range_inclusive(start_frame, end_frame) {
@ -164,9 +175,6 @@ pub fn remap_the_kernel<A>(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_start = Frame::containing_address(boot_info.start_address());
let multiboot_end = Frame::containing_address(boot_info.end_address() - 1); let multiboot_end = Frame::containing_address(boot_info.end_address() - 1);
for frame in Frame::range_inclusive(multiboot_start, multiboot_end) { for frame in Frame::range_inclusive(multiboot_start, multiboot_end) {
@ -175,7 +183,14 @@ pub fn remap_the_kernel<A>(allocator: &mut A, boot_info: &BootInformation)
}); });
let old_table = active_table.switch(new_table); 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<A>(allocator: &mut A) pub fn test_paging<A>(allocator: &mut A)

View file

@ -55,8 +55,7 @@ impl<L> Table<L> where L: HierarchicalLevel
"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");
self[index].set(frame, EntryFlags::PRESENT | EntryFlags::WRITABLE); self[index].set(frame, EntryFlags::PRESENT | EntryFlags::WRITABLE);
panic!("wtf"); self.next_table_mut(index).expect("next_table_mut gave None").zero()
self.next_table_mut(index).expect("real wtf now").zero()
} }
self.next_table_mut(index).expect("no next table 2") self.next_table_mut(index).expect("no next table 2")
} }

View file

@ -165,11 +165,10 @@ 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);
let cr0 = x86::cr0() & !(1 << 31); // unsafe { x86::cr0_write(cr0); }
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)); } // unsafe { x86::cr0_write(cr0 | (1 << 31)); }
self.flush_cursor(); self.flush_cursor();
} }

View file

@ -1,6 +1,9 @@
{ {
"arch": "x86", "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", "data-layout": "e-m:e-p:32:32-f64:32:64-f80:32-n8:16:32-S128",
"llvm-target": "i686-unknown-none", "llvm-target": "i686-unknown-none",
"linker-flavor": "gcc", "linker-flavor": "gcc",
"no-compiler-rt": true, "no-compiler-rt": true,