little correctif
This commit is contained in:
parent
0526b88859
commit
5c7daabdd0
10 changed files with 35 additions and 77 deletions
|
|
@ -1 +1 @@
|
||||||
Subproject commit 4425c197f10d5bcada47eabb8b2f93a8e2422937
|
Subproject commit 73530c41902a6991ca54ad6f12d05519d4870403
|
||||||
|
|
@ -12,12 +12,9 @@ start:
|
||||||
call check_multiboot
|
call check_multiboot
|
||||||
|
|
||||||
call set_up_page_tables
|
call set_up_page_tables
|
||||||
call enable_pse
|
|
||||||
; call enable_paging
|
|
||||||
|
|
||||||
; load the new gdt
|
; load the new gdt
|
||||||
lgdt [GDTR.ptr]
|
lgdt [GDTR.ptr]
|
||||||
|
|
||||||
jmp GDTR.gdt_cs:x86_start
|
jmp GDTR.gdt_cs:x86_start
|
||||||
|
|
||||||
check_multiboot:
|
check_multiboot:
|
||||||
|
|
@ -34,42 +31,13 @@ set_up_page_tables:
|
||||||
or eax, 0b11 ; present + writable
|
or eax, 0b11 ; present + writable
|
||||||
mov [p2_table + 1023 * 4], eax
|
mov [p2_table + 1023 * 4], eax
|
||||||
|
|
||||||
; map each P2 entry to a huge 4MiB page
|
; map ecx-th P2 entry to a huge page that starts at address 2MiB*ecx
|
||||||
mov ecx, 0 ; counter variable
|
mov eax, 0b10000011 ; huge + present + writable
|
||||||
|
mov [p2_table], eax ; map ecx-th entry
|
||||||
|
|
||||||
.map_p2_table:
|
mov eax, p2_table
|
||||||
; map ecx-th P2 entry to a huge page that starts at address 2MiB*ecx
|
mov cr3, eax
|
||||||
mov eax, 0x400000 ; 4MiB
|
ret
|
||||||
mul ecx ; start address of ecx-th page
|
|
||||||
or eax, 0b10000011 ; huge + present + writable
|
|
||||||
mov [p2_table + ecx * 4], eax ; map ecx-th entry
|
|
||||||
|
|
||||||
inc ecx ; increase counter
|
|
||||||
cmp ecx, 20 ; if counter == 1023, the whole P2 table is mapped
|
|
||||||
jne .map_p2_table ; else map the next entry
|
|
||||||
|
|
||||||
mov eax, p2_table
|
|
||||||
mov cr3, eax
|
|
||||||
ret
|
|
||||||
|
|
||||||
; PSE (Page Size Extension) allows huge pages to exist
|
|
||||||
enable_pse:
|
|
||||||
; enable PSE in the cr4 register
|
|
||||||
mov eax, cr4
|
|
||||||
or eax, 1 << 4
|
|
||||||
mov cr4, eax
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
enable_paging:
|
|
||||||
; load P2 to cr3 register (cpu uses this to access the P2 table)
|
|
||||||
|
|
||||||
; enable paging in the cr0 register
|
|
||||||
mov eax, cr0
|
|
||||||
or eax, 1 << 31
|
|
||||||
mov cr0, eax
|
|
||||||
|
|
||||||
ret
|
|
||||||
|
|
||||||
error:
|
error:
|
||||||
mov dword [0xb8000], 0x4f524f45
|
mov dword [0xb8000], 0x4f524f45
|
||||||
|
|
@ -84,9 +52,9 @@ HALT:
|
||||||
section .bss
|
section .bss
|
||||||
align 4096
|
align 4096
|
||||||
p2_table:
|
p2_table:
|
||||||
resb 4096
|
resb 4096
|
||||||
stack_bottom:
|
stack_bottom:
|
||||||
resb 4096 * 8
|
resb 4096 * 8
|
||||||
stack_top:
|
stack_top:
|
||||||
|
|
||||||
section .gdt
|
section .gdt
|
||||||
|
|
|
||||||
|
|
@ -38,9 +38,10 @@ pub fn outl(port: u16, value: u32) {
|
||||||
unsafe {asm!("outl %eax, %dx" :: "{dx}"(port), "{eax}"(value) :: "volatile")};
|
unsafe {asm!("outl %eax, %dx" :: "{dx}"(port), "{eax}"(value) :: "volatile")};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Halt system
|
||||||
pub fn halt() -> ! {
|
pub fn halt() -> ! {
|
||||||
unsafe {asm!("cli")};//TODO sure here ?
|
unsafe {asm!("cli" : : : : "volatile")};
|
||||||
loop {
|
loop {
|
||||||
unsafe {asm!("hlt")}; //TODO volatile ?????
|
unsafe {asm!("hlt" : : : : "volatile")};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,24 +40,12 @@ fn init_kernel(multiboot_info_addr: usize) -> Result <(), &'static str> {
|
||||||
else {
|
else {
|
||||||
acpi::init()?;
|
acpi::init()?;
|
||||||
}
|
}
|
||||||
enable_paging();
|
|
||||||
|
|
||||||
enable_write_protect_bit();
|
|
||||||
memory::init(&boot_info);
|
memory::init(&boot_info);
|
||||||
vga::init();
|
vga::init();
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn enable_paging() {
|
|
||||||
use x86::registers::control::{Cr0, Cr0Flags};
|
|
||||||
unsafe { Cr0::write(Cr0::read() | Cr0Flags::PAGING) };
|
|
||||||
}
|
|
||||||
|
|
||||||
fn enable_write_protect_bit() {
|
|
||||||
use x86::registers::control::{Cr0, Cr0Flags};
|
|
||||||
unsafe { Cr0::write(Cr0::read() | Cr0Flags::WRITE_PROTECT) };
|
|
||||||
}
|
|
||||||
|
|
||||||
#[no_mangle]
|
#[no_mangle]
|
||||||
pub extern fn kmain(multiboot_info_addr: usize) -> ! {
|
pub extern fn kmain(multiboot_info_addr: usize) -> ! {
|
||||||
if let Err(msg) = init_kernel(multiboot_info_addr) {
|
if let Err(msg) = init_kernel(multiboot_info_addr) {
|
||||||
|
|
|
||||||
|
|
@ -18,6 +18,10 @@ pub trait FrameAllocator {
|
||||||
|
|
||||||
/// memory initialisation should only be called once
|
/// memory initialisation should only be called once
|
||||||
pub fn init(boot_info: &multiboot2::BootInformation) {
|
pub fn init(boot_info: &multiboot2::BootInformation) {
|
||||||
|
use x86::registers::control::{Cr0, Cr4, Cr0Flags, Cr4Flags};
|
||||||
|
Cr4::add(Cr4Flags::PSE);
|
||||||
|
Cr0::add(Cr0Flags::PAGING | Cr0Flags::WRITE_PROTECT);
|
||||||
|
|
||||||
let elf_sections_tag = boot_info.elf_sections_tag().unwrap();
|
let elf_sections_tag = boot_info.elf_sections_tag().unwrap();
|
||||||
let memory_map_tag = boot_info.memory_map_tag().unwrap();
|
let memory_map_tag = boot_info.memory_map_tag().unwrap();
|
||||||
|
|
||||||
|
|
@ -33,7 +37,7 @@ pub fn init(boot_info: &multiboot2::BootInformation) {
|
||||||
|
|
||||||
let mut frame_allocator = self::AreaFrameAllocator::new(
|
let mut frame_allocator = self::AreaFrameAllocator::new(
|
||||||
kernel_start as usize, kernel_end as usize,
|
kernel_start as usize, kernel_end as usize,
|
||||||
boot_info.start_address(), boot_info.start_address(),
|
boot_info.start_address(), boot_info.end_address(),
|
||||||
memory_map_tag.memory_areas());
|
memory_map_tag.memory_areas());
|
||||||
|
|
||||||
let mut active_table = paging::remap_the_kernel(&mut frame_allocator,
|
let mut active_table = paging::remap_the_kernel(&mut frame_allocator,
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,6 @@ impl Mapper {
|
||||||
let offset = virtual_address.as_u32() % PAGE_SIZE as u32;
|
let offset = virtual_address.as_u32() % PAGE_SIZE as u32;
|
||||||
self.translate_page(Page::containing_address(virtual_address))
|
self.translate_page(Page::containing_address(virtual_address))
|
||||||
.map(|frame| frame.start_address() + offset)
|
.map(|frame| frame.start_address() + offset)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// virtual page to physical frame translation
|
/// virtual page to physical frame translation
|
||||||
|
|
@ -50,13 +49,13 @@ impl Mapper {
|
||||||
if p2_entry.flags().contains(PageTableFlags::HUGE_PAGE) {
|
if p2_entry.flags().contains(PageTableFlags::HUGE_PAGE) {
|
||||||
// TODO 4MiB alignment check
|
// TODO 4MiB alignment check
|
||||||
return Some(start_frame + u32::from(page.p1_index()));
|
return Some(start_frame + u32::from(page.p1_index()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
|
|
||||||
p1.and_then(|p1| p1[page.p1_index()].pointed_frame())
|
p1.and_then(|p1| p1[page.p1_index()].pointed_frame())
|
||||||
.or_else(huge_page)
|
.or_else(huge_page)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// map a virtual page to a physical frame in the page tables
|
/// map a virtual page to a physical frame in the page tables
|
||||||
|
|
|
||||||
|
|
@ -8,9 +8,9 @@ pub trait RecTable
|
||||||
fn next_table(&self, index: usize) -> Option<&PageTable>;
|
fn next_table(&self, index: usize) -> Option<&PageTable>;
|
||||||
fn next_table_mut(&mut self, index: usize) -> Option<&mut PageTable>;
|
fn next_table_mut(&mut self, index: usize) -> Option<&mut PageTable>;
|
||||||
fn next_table_create<A: FrameAllocator>(&mut self,
|
fn next_table_create<A: FrameAllocator>(&mut self,
|
||||||
index: usize,
|
index: usize,
|
||||||
allocator: &mut A)
|
allocator: &mut A)
|
||||||
-> &mut PageTable;
|
-> &mut PageTable;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl RecTable for PageTable
|
impl RecTable for PageTable
|
||||||
|
|
@ -36,8 +36,8 @@ impl RecTable for PageTable
|
||||||
}
|
}
|
||||||
|
|
||||||
fn next_table_create<A>(&mut self,
|
fn next_table_create<A>(&mut self,
|
||||||
index: usize,
|
index: usize,
|
||||||
allocator: &mut A) -> &mut PageTable
|
allocator: &mut A) -> &mut PageTable
|
||||||
where A: FrameAllocator
|
where A: FrameAllocator
|
||||||
{
|
{
|
||||||
if self.next_table(index).is_none() {
|
if self.next_table(index).is_none() {
|
||||||
|
|
|
||||||
|
|
@ -18,17 +18,17 @@ impl TemporaryPage {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Maps the temporary page to the given frame in the active table.
|
/// Maps the temporary page to the given frame in the active table.
|
||||||
/// Returns the start address of the temporary page.
|
/// Returns the start address of the temporary page.
|
||||||
pub fn map(&mut self, frame: PhysFrame, active_table: &mut ActivePageTable)
|
pub fn map(&mut self, frame: PhysFrame, active_table: &mut ActivePageTable)
|
||||||
-> VirtAddr
|
-> VirtAddr
|
||||||
{
|
{
|
||||||
assert!(active_table.translate_page(self.page).is_none(),
|
assert!(active_table.translate_page(self.page).is_none(),
|
||||||
"temporary page is already mapped");
|
"temporary page is already mapped");
|
||||||
active_table.map_to(self.page, frame, PageTableFlags::WRITABLE, &mut self.allocator);
|
active_table.map_to(self.page, frame, PageTableFlags::WRITABLE, &mut self.allocator);
|
||||||
// this kind of check should be done in a test routine
|
// this kind of check should be done in a test routine
|
||||||
assert!(active_table.translate_page(self.page).is_some(),
|
assert!(active_table.translate_page(self.page).is_some(),
|
||||||
"temporary page was not mapped");
|
"temporary page was not mapped");
|
||||||
self.page.start_address()
|
self.page.start_address()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -37,14 +37,14 @@ impl TemporaryPage {
|
||||||
active_table.unmap(self.page, &mut self.allocator)
|
active_table.unmap(self.page, &mut self.allocator)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Maps the temporary page to the given page table frame in the active
|
/// Maps the temporary page to the given page table frame in the active
|
||||||
/// table. Returns a reference to the now mapped table.
|
/// table. Returns a reference to the now mapped table.
|
||||||
pub fn map_table_frame(&mut self,
|
pub fn map_table_frame(&mut self,
|
||||||
frame: PhysFrame,
|
frame: PhysFrame,
|
||||||
active_table: &mut ActivePageTable)
|
active_table: &mut ActivePageTable)
|
||||||
-> &mut PageTable {
|
-> &mut PageTable {
|
||||||
unsafe { &mut *(self.map(frame, active_table).as_u32() as *mut PageTable) }
|
unsafe { &mut *(self.map(frame, active_table).as_u32() as *mut PageTable) }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct TinyAllocator([Option<PhysFrame>; 1]);
|
struct TinyAllocator([Option<PhysFrame>; 1]);
|
||||||
|
|
|
||||||
|
|
@ -214,7 +214,5 @@ pub fn init() {
|
||||||
format_args!("{: ^80}", r#" | : ;| : .' "#),
|
format_args!("{: ^80}", r#" | : ;| : .' "#),
|
||||||
format_args!("{: ^80}", r#" ' ,/ ; | .' "#),
|
format_args!("{: ^80}", r#" ' ,/ ; | .' "#),
|
||||||
format_args!("{: ^80}", r#" '--' `---' "#));
|
format_args!("{: ^80}", r#" '--' `---' "#));
|
||||||
set_color!();
|
|
||||||
unsafe { VGA.prompt(); }
|
unsafe { VGA.prompt(); }
|
||||||
unsafe { VGA.flush(); }
|
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1 +1 @@
|
||||||
Subproject commit eae470839b1ff232dbc4af5389e9a0b4fffe4b30
|
Subproject commit 7b8227e36afe68ed2d518a2c7cede0466878ca9d
|
||||||
Loading…
Reference in a new issue