Added context-switching and a yield() function.
[marionette.git] / kernel / kmain.c
blob24db657f5aea88f43ef5f31972ccf10a6d4e216f
1 /*
2 * Copyright (c) 2008 Joshua Phillips. All rights reserved.
3 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
7 *
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in
12 * the documentation and/or other materials provided with the
13 * distribution.
15 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
16 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
18 * DISCLAIMED. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY
19 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
20 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
21 * GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
22 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER
23 * IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
24 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
25 * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 #define USE_TRACE
29 #include "stddef.h"
30 #include "stdint.h"
31 #include "extlib.h"
32 #include "stdlib.h"
33 #include "console.h"
34 #include "serial.h"
35 #include "multiboot.h"
36 #include "gdt.h"
37 #include "interrupt.h"
38 #include "timer.h"
39 #include "mm/mm.h"
40 #include "mm/paging.h"
41 #include "mm/region.h"
42 #include "thread.h"
44 static void read_mmap_info(struct mb_info *mbi)
46 struct mb_mmap *region; // current memory region
47 struct mb_mmap *end; // end of memory region array
48 region = (struct mb_mmap *) mbi->mmap_addr;
49 end = (struct mb_mmap *) (mbi->mmap_addr + mbi->mmap_length);
50 console_printf(&tty1, "Memory map from bootloader, at address %.8X:\n", mbi->mmap_addr);
51 console_puts(&tty1, "Range Type\n");
52 while (region < end){
53 if (region->type == 1){
54 // This is a free memory region
55 console_colour_fg(&tty1, COLOUR_BRIGHT_WHITE);
56 } else {
57 console_colour_default(&tty1);
59 console_printf(&tty1, "%.8X - %.8X %d\n",
60 (unsigned long) region->base_addr,
61 (unsigned long) (region->base_addr + region->length - 1),
62 region->type);
63 if (region->type == 1){
64 pmem_init_mark_free(region->base_addr, region->base_addr + region->length);
66 // locate next region
67 region = (struct mb_mmap *) (((char *) region) + region->size + 4);
69 console_colour_default(&tty1);
72 static void read_multiboot_info(struct mb_info *mbi)
74 if (mbi->flags & MBI_BOOT_LOADER_NAME){
75 // Bootloader has given us a name. Why not print it?
76 console_printf(&tty1, "Thank you, %s.\n", mbi->boot_loader_name);
78 if (mbi->flags & MBI_MMAP_XXX){
79 // read the memory map
80 read_mmap_info(mbi);
81 } else if (mbi->flags & MBI_MEM_XXX){
82 // Use the more basic memory information
83 console_printf(&tty1, "Upper memory (mbi->mem_upper): %d kiB\n", mbi->mem_upper);
84 pmem_init_mark_free(KERNEL_PHYS_BASE, KERNEL_PHYS_BASE + mbi->mem_upper * 1024);
85 } else {
86 panic("The bootloader gave us no memory information!");
90 extern char stack[];
92 void foo_func(void)
94 console_printf(&tty1, "Hello world II\n");
95 yield();
96 for (;;);
99 void bar_func(void)
101 console_printf(&tty1, "Hello world IIb\n");
102 for (;;);
105 void kmain(uint32_t freemem_base, struct mb_info *mbi, unsigned int magic)
107 console_init(&tty1);
108 if (serial_init(&com1, 1, 9600)){
109 console_serial_enable(&tty1, &com1);
111 console_printf(&tty1, "Hello world!\n");
112 if (magic != MB_BOOT_MAGIC){
113 console_colour_fg(&tty1, COLOUR_BRIGHT_RED);
114 console_printf(&tty1, "Bootloader gave us an invalid magic number: 0x%.8X\n", magic);
115 console_colour_default(&tty1);
117 pmem_init_set_freemem_base(freemem_base);
118 read_multiboot_info(mbi);
119 console_printf(&tty1, "Free memory: %d MiB\n", uldivru(pmem_get_size(), 1024 * 1024));
120 mem_init();
121 gdt_init();
122 interrupt_sys_start();
124 // test interrupt handling
125 asm volatile ("int $0x80");
127 set_pagefault_handler();
128 paging_init();
130 // Map VRAM to a suitable place
131 map_mem(0xB8000, 0xFFBFF000, 1, PTE_PRESENT | PTE_WRITABLE);
132 tty1.vram = (void *) 0xFFBFF000; // TODO: don't probe into other modules' structures
136 struct addr_space *aspace;
137 struct vm_region *vm_r;
138 aspace = addr_space_new();
139 vm_r = vm_region_new_physical(aspace, 0x00001000, 1);
140 vm_region_set_flags(vm_r, VM_R_WRITABLE);
141 addr_space_switch(aspace);
142 asm volatile ("movl %%eax,0x00001000" ::: "eax");
145 timer_sys_start();
146 thread_sys_init();
148 struct thread *foothread, *barthread;
149 foothread = thread_new();
150 thread_set_eip(foothread, (uint32_t) foo_func);
151 // Guessing stack size, blah blah == bad
152 thread_set_esp(foothread, (uint32_t) stack + 0x4000);
153 thread_resume(foothread);
154 barthread = thread_new();
155 thread_set_eip(barthread, (uint32_t) bar_func);
156 thread_set_esp(barthread, (uint32_t) stack + 0x2000);
157 thread_resume(barthread);
159 thread_sys_start();
160 asm volatile ("sti");
162 // enter an idle loop, so we can see the effects of interrupts
163 for (;;){
164 asm volatile ("hlt");