From 8abb673efbc4cccda9ed564eeebe4660a879647e Mon Sep 17 00:00:00 2001 From: Vegard Storheil Eriksen Date: Tue, 2 Feb 2010 07:28:10 +0100 Subject: Reinitialize paging. --- kernel/SConscript | 1 + kernel/entry.c | 19 +++++++++++-------- kernel/idt.c | 2 +- kernel/main.c | 7 ++++++- kernel/paging.c | 26 ++++++++++++++++++++++++++ kernel/paging.h | 30 ++++++++++++++++++++++++++++++ 6 files changed, 75 insertions(+), 10 deletions(-) create mode 100644 kernel/paging.c create mode 100644 kernel/paging.h diff --git a/kernel/SConscript b/kernel/SConscript index 47af722..3688850 100644 --- a/kernel/SConscript +++ b/kernel/SConscript @@ -34,6 +34,7 @@ kernel = env.Kernel('kernel', [ 'idt.c', 'irq.c', 'main.c', + 'paging.c', 'palloc.c', 'panic.c', 'printf.c', diff --git a/kernel/entry.c b/kernel/entry.c index 6058910..2ec5089 100644 --- a/kernel/entry.c +++ b/kernel/entry.c @@ -1,4 +1,5 @@ #include "kernel.h" +#include "paging.h" extern void main(); @@ -46,25 +47,27 @@ void entry_main(uint32_t mb_magic, multiboot_info_t* mb_info) { entry_pagedir[i] = 0; // Identity mapping of the current code. - //entry_pagetable_low[i] = ((uint32_t)&addr_phys & 0xffc00000) | (i << 12) | 0x003; - entry_pagetable_low[i] = ((uint32_t)&addr_phys & 0xffc00000) | (i << 12) | 0x007; + entry_pagetable_low[i] = ((uint32_t)&addr_phys & 0xffc00000) | (i << 12) | P1_P | P1_W; // Map kernelspace. if((i << 12) < ((uint32_t)&addr_virt_end & 0x003fffff)) { - entry_pagetable_high[i] = ((uint32_t)&addr_load_virt + (i << 12)) | 0x003; + entry_pagetable_high[i] = ((uint32_t)&addr_load_virt + (i << 12)) | P1_P | P1_W | P1_G; } else { entry_pagetable_high[i] = 0; } } - entry_pagetable_high[((uint32_t)&multiboot_info & 0x003ff000) >> 12] = (uint32_t)&entry_multiboot | 0x003; + entry_pagetable_high[((uint32_t)&multiboot_info & 0x003ff000) >> 12] = (uint32_t)&entry_multiboot | P1_P | P1_W | P1_G; - entry_pagedir[(uint32_t)&addr_phys >> 22] = (uint32_t)&entry_pagetable_low | 0x007; - entry_pagedir[(uint32_t)&addr_virt >> 22] = (uint32_t)&entry_pagetable_high | 0x003; + entry_pagedir[(uint32_t)&addr_phys >> 22] = (uint32_t)&entry_pagetable_low | P2_P | P2_W; + entry_pagedir[(uint32_t)&addr_virt >> 22] = (uint32_t)&entry_pagetable_high | P2_P | P2_W | P2_G; + + // Map map_p1. + entry_pagedir[1022] = (uint32_t)&entry_pagedir | P2_P | P2_W | P2_G; // Mapping stack to top without creating another page directory. - entry_pagetable_high[1023] = (uint32_t)&entry_stack | 0x003; - entry_pagedir[1023] = (uint32_t)&entry_pagetable_high | 0x003; + entry_pagetable_low[1023] = (uint32_t)&entry_stack | P1_P | P1_W | P1_G; + entry_pagedir[1023] = (uint32_t)&entry_pagetable_low | P2_P | P2_W | P2_G; // Enable paging. asm volatile( diff --git a/kernel/idt.c b/kernel/idt.c index 66e1fb8..55c1bae 100644 --- a/kernel/idt.c +++ b/kernel/idt.c @@ -76,7 +76,7 @@ isr_panic(31); #include "irq.h" void tick() { - *(uint16_t*)(0xb8890) += 1; + //*(uint16_t*)(0xb8890) += 1; irq_reset(); } diff --git a/kernel/main.c b/kernel/main.c index db22f07..d6de534 100644 --- a/kernel/main.c +++ b/kernel/main.c @@ -1,6 +1,7 @@ #include "kernel.h" #include "printf.h" #include "palloc.h" +#include "paging.h" #include "gdt.h" #include "idt.h" #include "irq.h" @@ -11,6 +12,9 @@ void main() { palloc_init(); printf("Page allocator initiated.\n"); + paging_reinit(); + printf("Paging reinitialized.\n"); + gdt_init(); printf("GDT set.\n"); @@ -27,6 +31,7 @@ void main() { asm volatile("sti"); + /* asm volatile( "push $0x23\n" "push $entry_stack_top\n" @@ -35,7 +40,7 @@ void main() { "push %0\n" "iret\n" :: "r" (multiboot_info.mods_addr[0].mod_start) - ); + ); */ printf("Halting.\n"); diff --git a/kernel/paging.c b/kernel/paging.c new file mode 100644 index 0000000..22da7e8 --- /dev/null +++ b/kernel/paging.c @@ -0,0 +1,26 @@ +#include "paging.h" +#include "kernel.h" + +#define invlpg(page) asm volatile("invlpg (%0)" :: "r" (page)) + +void paging_reinit() { + map_p1.l[(uint32_t)&map_p2 >> 12] = (uint32_t)&entry_pagedir | P1_P | P1_W | P1_G; + + invlpg(&map_p2); + + for(unsigned int i = 0; i < 1024; i++) { + if(map_p2[i] & P2_P && !(map_p2[i] & P2_G)) { + map_p2[i] = 0; + } + + if(map_p1.b[0x300][i] & P1_P && !(map_p1.b[0x300][i] & P1_G)) { + map_p1.b[0x300][i] = 0; + } + + if(map_p1.b[0x3ff][i] & P1_P && !(map_p1.b[0x3ff][i] & P1_G)) { + map_p1.b[0x3ff][i] = 0; + } + } + + // TODO: Set CR4.PGE. +} diff --git a/kernel/paging.h b/kernel/paging.h new file mode 100644 index 0000000..24409d9 --- /dev/null +++ b/kernel/paging.h @@ -0,0 +1,30 @@ +#ifndef PAGING_H +#define PAGING_H + +enum { + P1_P = 0x001, + P1_W = 0x002, + P1_U = 0x004, + P1_PWT = 0x008, + P1_PCD = 0x010, + P1_A = 0x020, + P1_D = 0x040, + P1_PAT = 0x080, + P1_G = 0x100, +}; + +enum { + P2_P = 0x001, + P2_W = 0x002, + P2_U = 0x004, + P2_PWT = 0x008, + P2_PCD = 0x010, + P2_A = 0x020, + P2_D = 0x040, + P2_PS = 0x080, + P2_G = 0x100, +}; + +void paging_reinit(); + +#endif -- cgit v1.2.3