i must have done something right becuase now 0xffff_f000 points to p2 as expected, hurray
This commit is contained in:
parent
bbe2b8b1e6
commit
f0456aa7fd
10 changed files with 60 additions and 25 deletions
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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(); }
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
|
||||
|
|
|
|||
|
|
@ -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<A>(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<A>(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<A>(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<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_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<A>(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<A>(allocator: &mut A)
|
||||
|
|
|
|||
|
|
@ -55,8 +55,7 @@ impl<L> Table<L> 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")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
Loading…
Reference in a new issue