summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVegard Storheil Eriksen <zyp@jvnv.net>2010-02-02 07:28:10 +0100
committerVegard Storheil Eriksen <zyp@jvnv.net>2010-02-02 07:28:10 +0100
commit8abb673efbc4cccda9ed564eeebe4660a879647e (patch)
tree9709fd49dbc70838b77d290a338a1d230ea27f27
parent273967f16dad471478bbca2a14a5282faae95679 (diff)
Reinitialize paging.
-rw-r--r--kernel/SConscript1
-rw-r--r--kernel/entry.c19
-rw-r--r--kernel/idt.c2
-rw-r--r--kernel/main.c7
-rw-r--r--kernel/paging.c26
-rw-r--r--kernel/paging.h30
6 files changed, 75 insertions, 10 deletions
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