From 864fb03a3305b65fedbe434ebb87510ac13fe865 Mon Sep 17 00:00:00 2001 From: Vegard Storheil Eriksen Date: Wed, 23 Dec 2009 22:26:43 +0100 Subject: Initial commit. --- kernel/entry.c | 92 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 92 insertions(+) create mode 100644 kernel/entry.c (limited to 'kernel/entry.c') 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++); + } +} -- cgit v1.2.3