summaryrefslogtreecommitdiff
path: root/kernel/entry.c
diff options
context:
space:
mode:
authorVegard Storheil Eriksen <zyp@jvnv.net>2009-12-23 22:26:43 +0100
committerVegard Storheil Eriksen <zyp@jvnv.net>2009-12-23 22:31:02 +0100
commit864fb03a3305b65fedbe434ebb87510ac13fe865 (patch)
tree6b0b2b0dccf6fd1835a4e86ba808fbad2cba89cb /kernel/entry.c
Initial commit.
Diffstat (limited to 'kernel/entry.c')
-rw-r--r--kernel/entry.c92
1 files changed, 92 insertions, 0 deletions
diff --git a/kernel/entry.c b/kernel/entry.c
new file mode 100644
index 0000000..d040cfb
--- /dev/null
+++ b/kernel/entry.c
@@ -0,0 +1,92 @@
+#include "types.h"
+
+extern void addr_phys;
+extern void addr_virt;
+extern void addr_virt_end;
+extern void addr_load_virt;
+extern void addr_load_virt_end;
+
+extern void entry_stack;
+
+extern uint32_t entry_pagedir[];
+extern uint32_t entry_pagetable_low[];
+extern uint32_t entry_pagetable_high[];
+
+extern void main();
+
+asm(
+ ".globl entry\n"
+ "entry:\n"
+ "mov $entry_stack_top,%esp\n"
+ "push %eax\n"
+ "call entry_main\n"
+);
+
+void entry_serial_out(char* str);
+
+void entry_main(uint32_t mb_magic, void* mb_info) {
+ entry_serial_out("entry_main()\n");
+ if(mb_magic != 0x2badb002) {
+ entry_serial_out("Multiboot magic word is wrong!\n");
+ goto stop;
+ }
+ entry_serial_out("Multiboot ok\n");
+
+ // TODO: Copy multiboot information.
+
+ // Create initial page tables.
+ for(unsigned int i = 0; i < 1024; i++) {
+ // Clear page directory.
+ entry_pagedir[i] = 0;
+
+ // Identity mapping of the current code.
+ entry_pagetable_low[i] = ((uint32_t)&addr_phys & 0xffc00000) | (i << 12) | 0x003;
+
+ // Map kernelspace.
+ if((i << 12) < ((uint32_t)&addr_virt_end & 0x003ff000 )) {
+ entry_pagetable_high[i] = ((uint32_t)&addr_load_virt + (i << 12)) | 0x003;
+ } else {
+ entry_pagetable_high[i] = 0;
+ }
+ }
+
+ entry_pagedir[(uint32_t)&addr_phys >> 22] = (uint32_t)&entry_pagetable_low | 0x003;
+ entry_pagedir[(uint32_t)&addr_virt >> 22] = (uint32_t)&entry_pagetable_high | 0x003;
+
+ // 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;
+
+ // Enable paging.
+ asm volatile(
+ "mov %0, %%cr3\n"
+ "mov %%cr0, %0\n"
+ "or $0x80000000, %0\n"
+ "mov %0, %%cr0\n"
+ : : "r" (&entry_pagedir) : "%0"
+ );
+
+ // TODO: Check that segments are loaded and mapped right.
+
+ // Call main() in virtual memory.
+ main();
+
+ stop:
+ entry_serial_out("Halting.\n");
+ asm volatile(
+ "cli\n"
+ "hlt\n"
+ );
+ while(1);
+}
+
+#define outb(port, value) asm volatile("out %b0,%w1" : : "a" (value), "d" (port));
+
+void entry_serial_out(char* str) {
+ while(*str) {
+ if(*str == '\n') {
+ outb(0x3f8, '\r');
+ }
+ outb(0x3f8, *str++);
+ }
+}