Moved PAGE_SIZE to kernel/archinf.h
[marionette.git] / kernel / kmain.c
blobcc9d35ad07310ef6e1925981f8fc213ffb02bbe2
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 #include "stddef.h"
29 #include "stdint.h"
30 #include "extlib.h"
31 #include "stdlib.h"
32 #include "console.h"
33 #include "serial.h"
34 #include "multiboot.h"
35 #include "gdt.h"
36 #include "interrupt.h"
37 #include "timer.h"
38 #include "mm/allocation.h"
39 #include "mm/paging.h"
40 #include "mm/region.h"
41 #include "thread.h"
42 #include "loadelf.h"
43 #include "syscall.h"
44 #include "exit.h"
45 #include "panic.h"
46 #include "trace.h"
48 static void read_mmap_info(struct mb_info *mbi)
50 struct mb_mmap *region; // current memory region
51 struct mb_mmap *end; // end of memory region array
52 region = (struct mb_mmap *) mbi->mmap_addr;
53 end = (struct mb_mmap *) (mbi->mmap_addr + mbi->mmap_length);
54 TRACE("Memory map from bootloader, at address %.8X:", mbi->mmap_addr);
55 while (region < end){
56 TRACE(" Region(%.8X .. %.8X (type %d)",
57 (unsigned long) region->base_addr,
58 (unsigned long) (region->base_addr + region->length - 1),
59 region->type);
60 if (region->type == 1){
61 pmem_init_mark_free(region->base_addr, region->base_addr + region->length);
63 // locate next region
64 region = (struct mb_mmap *) (((char *) region) + region->size + 4);
68 static void read_multiboot_info(struct mb_info *mbi)
70 if (mbi->flags & MBI_BOOT_LOADER_NAME){
71 // Bootloader has given us a name. Why not print it?
73 if (mbi->flags & MBI_MMAP_XXX){
74 // read the memory map
75 read_mmap_info(mbi);
76 } else if (mbi->flags & MBI_MEM_XXX){
77 // Use the more basic memory information
78 console_printf(&tty1, "Upper memory (mbi->mem_upper): %d kiB\n", mbi->mem_upper);
79 pmem_init_mark_free(KERNEL_PHYS_BASE, KERNEL_PHYS_BASE + mbi->mem_upper * 1024);
80 } else {
81 panic("The bootloader gave us no memory information!");
85 #if 0
86 static void read_multiboot_modules(struct mb_info *mbi)
88 // XXX: we're assuming the first 4 MiB is identity-mapped!
89 struct mb_module *mod;
90 int count, i;
91 if (mbi->flags & MBI_MODS_XXX){
92 // find address of first module structure from the multiboot info
93 mod = (struct mb_module *) mbi->mods_addr;
94 count = mbi->mods_count;
95 for (i=0; i<count; ++i,++mod){
96 // print info about each module
97 TRACE("Module: %s at 0x%.8X (%d kiB)\n", (char *) mod->string, mod->mod_start,
98 uldivru(mod->mod_end - mod->mod_start, 1024));
99 // load the elf module
100 load_elf_module((void *) mod->mod_start, mod->mod_start, mod->mod_end - mod->mod_start);
102 if (count == 0){
103 TRACE("No multiboot modules found.\n");
105 } else {
106 TRACE("No multiboot module information.\n");
107 TRACE("Either the bootloader doesn't support modules,\n");
108 TRACE("or no modules were loaded.\n");
112 extern char stack[];
114 void foo_func(void)
116 for (;;);
119 void bar_func(void)
121 for (;;);
123 #endif
125 void kmain(uint32_t freemem_base, struct mb_info *mbi, unsigned int magic)
127 static struct pagedir init_pagedir;
129 console_init(&tty1); // init the text console
130 serial_init(&com1, 1, 9600); // try to init ttyS0 (first serial port)
131 if (magic != MB_BOOT_MAGIC){
132 console_colour_fg(&tty1, COLOUR_BRIGHT_RED);
133 console_printf(&tty1, "Bootloader gave us an invalid magic number: 0x%.8X\n", magic);
134 console_colour_default(&tty1);
136 pmem_init_set_freemem_base(freemem_base);
137 read_multiboot_info(mbi);
138 console_printf(&tty1, "Free memory: %d MiB\n", uldivru(pmem_get_size(), 1024 * 1024));
139 mm_allocation_init();
140 create_init_pagedir(&init_pagedir);
142 map_mem(&init_pagedir, 0xF0000000, 0x00000000, 4096, PTE_PRESENT | PTE_WRITABLE);
143 TRACE("map_mem returned! Check the mapping!");
145 static struct pagedir second_pagedir;
146 pagedir_create(&second_pagedir);
147 map_mem(&second_pagedir, 0x00000000, 0x40000000, 4096, PTE_PRESENT | PTE_WRITABLE);
148 pagedir_switch(&second_pagedir);
149 TRACE("Well I seem to be still alive!");
151 asm volatile ("cli ; hlt");
153 // allocate a page for the IDT, GDT and TSS
154 #if 0
156 intptr_t page_paddr, page_vaddr;
157 void *page;
158 size_t n_pages_phys, n_pages_virt;
159 n_pages_phys = ppalloc(1, 1, &page_paddr);
160 if (n_pages_phys == 0){
161 panic("cannot allocate physical page for IDT/GDT/TSS");
163 n_pages_virt = vpalloc(&kvpa, 1, 1, &page_vaddr);
164 if (n_pages_virt == 0){
165 panic("cannot allocate virtual page for IDT/GDT/TSS");
167 map_mem(page_paddr, page_vaddr, 1, PTE_PRESENT | PTE_USER);
168 page = (void *) page_vaddr;
169 gdt_init(&page);
170 interrupt_init(&page);
172 syscall_init();
174 // test interrupt handling
175 asm volatile ("int $0x81");
176 #endif
178 #if 0
179 set_pagefault_handler();
180 paging_init();
182 // Map VRAM to a suitable place
183 map_mem(0xB8000, 0xFFBFF000, 1, PTE_PRESENT | PTE_WRITABLE);
184 tty1.vram = (void *) 0xFFBFF000; // TODO: don't probe into other modules' structures
186 timer_sys_start();
187 thread_sys_init();
188 read_multiboot_modules(mbi);
189 thread_sys_start();
190 asm volatile ("sti");
192 // enter an idle loop, so we can see the effects of interrupts
193 for (;;){
194 asm volatile ("hlt");
196 #endif