Added .gitignore
[comos.git] / kernel / kmain.c
blob9805d8e667267db1a34b6808a30f43d44e8c9238
1 #include "align.h"
2 #include "console.h"
3 #include "gdt.h"
4 #include "cpuid.h"
5 #include "interrupt.h"
6 #include "keyboard.h"
7 #include "timer.h"
8 #include "multiboot.h"
9 #include "mp_tables.h"
10 #include "mm/mm.h"
11 #include "mm/paging.h"
12 #include "mm/region.h"
13 #include "general.h"
14 #include "serial.h"
15 #include "assert.h"
16 #include "critical.h"
17 #include "shell.h"
18 #include "task.h"
19 #include "chardev.h"
20 #include "loadelf.h"
21 #include "smbios.h"
22 #include "rtc.h"
23 #include "cpu.h"
24 #include "syscall.h"
26 static void read_mmap_info(struct mb_info *mbi)
28 struct mb_mmap *region; // current memory region
29 struct mb_mmap *end; // end of memory region array
30 region = (struct mb_mmap *) mbi->mmap_addr;
31 end = (struct mb_mmap *) (mbi->mmap_addr + mbi->mmap_length);
32 console_printf(get_vterm(0), "Memory map from bootloader, at address %.8X:\n", mbi->mmap_addr);
33 console_puts(get_vterm(0), "Range Type\n");
34 while (region < end){
35 if (region->type == 1){
36 // This is a free memory region
37 console_set_fcolour(get_vterm(0), COLOR_BRIGHT_WHITE);
38 } else {
39 console_reset_colour(get_vterm(0));
41 console_printf(get_vterm(0), "%.8X - %.8X %d\n",
42 (unsigned long) region->base_addr,
43 (unsigned long) (region->base_addr + region->length - 1),
44 region->type);
45 if (region->type == 1){
46 pmem_init_mark_free(region->base_addr, region->base_addr + region->length);
48 // locate next region
49 region = (struct mb_mmap *) (((char *) region) + region->size + 4);
51 console_reset_colour(get_vterm(0));
54 static void read_multiboot_info(struct mb_info *mbi)
56 if (mbi->flags & MBI_BOOT_LOADER_NAME){
57 // Bootloader has given us a name. Why not print it?
58 console_printf(get_vterm(0), "Thank you, %s.\n", mbi->boot_loader_name);
60 if (mbi->flags & MBI_MMAP_XXX){
61 // read the memory map
62 read_mmap_info(mbi);
63 } else if (mbi->flags & MBI_MEM_XXX){
64 // Use the more basic memory information
65 console_printf(get_vterm(0), "Upper memory (mbi->mem_upper): %d kiB\n", mbi->mem_upper);
66 pmem_init_mark_free(KERNEL_PHYS_BASE, KERNEL_PHYS_BASE + mbi->mem_upper * 1024);
67 } else {
68 panic("The bootloader gave us no memory information!");
72 // ignore spurious irq 7
73 void spurious_int_7(int vector, struct interrupt_stack *is)
75 //trace("suprious_int_7() called! \n");
76 asm("pause;");
79 void read_mb_modules(struct mb_info *mbi)
81 // XXX: we're assuming the first 4 MiB is identity-mapped!
82 struct mb_module *mod;
83 int count, i;
84 if (mbi->flags & MBI_MODS_XXX){
85 // find address of first module structure from the multiboot info
86 mod = (struct mb_module *) mbi->mods_addr;
87 count = mbi->mods_count;
88 for (i=0; i<count; ++i){
89 // print info about each module
90 trace("Module: %s at 0x%.8X (%d kiB)\n", (char *) mod->string, mod->mod_start,
91 uldivru(mod->mod_end - mod->mod_start, 1024));
92 if (i < 1){
93 // load only the first module, for now
94 load_elf_module((void *)((KERNEL_VIRT_BASE - KERNEL_PHYS_BASE) + mod->mod_start), // start_addr
95 mod->mod_start, // phys_addr
96 mod->mod_end - mod->mod_start); // length
98 ++mod;
100 if (count == 0){
101 trace("No multiboot modules found.\n");
103 } else {
104 trace("No multiboot module information.\n");
105 trace("Either the bootloader doesn't support modules,\n");
106 trace("or no modules were loaded.\n");
110 void kmain(uint32_t freemem_base, struct mb_info *mbi, unsigned int magic)
112 MULTITASKING = false;
113 chardev_init();
114 console_init();
116 // try initializing COM1 for 9600 baud output
117 if (serial_init(&com1, 1, 9600) == 0){
118 // also send console output to COM1
119 console_serial_enable(get_vterm(0), &com1);
122 console_set_fcolour(get_vterm(0), COLOR_BRIGHT_WHITE);
123 console_puts(get_vterm(0), "CommunityOS booting up...\n");
124 console_reset_colour(get_vterm(0));
125 if (magic != MB_BOOT_MAGIC){
126 console_set_fcolour(get_vterm(0), COLOR_BRIGHT_RED);
127 console_printf(get_vterm(0), "Bootloader gave us an invalid magic number: 0x%.8X\n", magic);
128 console_reset_colour(get_vterm(0));
130 pmem_init_set_freemem_base(freemem_base);
131 read_multiboot_info(mbi);
132 console_printf(get_vterm(0), "Free memory: %d MiB\n", uldivru(pmem_get_size(), 1024 * 1024));
133 mem_init();
134 console_puts(get_vterm(0), "Loading GDT and task register...\n");
135 gdt_init();
136 console_puts(get_vterm(0), "Loading IDT...\n");
137 interrupt_init();
138 syscall_init();
139 //console_puts(get_vterm(0), "Triggering interrupt 0x80 to test the IDT...\n");
140 //asm volatile ("int $0x80" ::: "cc");
141 console_puts(get_vterm(0), "Installing page fault handler...\n");
142 set_pagefault_handler();
143 paging_init();
144 console_puts(get_vterm(0), "Configuring PIT...\n");
145 timer_init();
146 console_puts(get_vterm(0), "Getting CPUID information...\n");
147 parse_cpuid();
149 apic_init();
150 enable_local_apic();
151 init_sse();
152 init_fpu();
154 uint64_t counter;
155 counter = read_cpu_timestamp();
156 parse_mp_tables();
157 counter = (read_cpu_timestamp() - counter);
158 console_printf(get_vterm(0), "parse_mp_tables took 0x%llX ticks\n", counter);
160 counter = read_cpu_timestamp();
161 parse_smbios();
162 counter = (read_cpu_timestamp() - counter);
163 console_printf(get_vterm(0), "parse_smbios took 0x%llX ticks\n", counter);
165 sti();
166 console_puts(get_vterm(0), "Initializing Real-Time Clock...\n");
167 init_rtc();
169 console_puts(get_vterm(0), "Initializing keyboard driver...\n");
170 keyboard_init();
172 //console_set_fcolour(get_vterm(0), COLOR_BRIGHT_GREEN);
173 //console_puts(get_vterm(0), "Bootup complete!\n"); no it's not!
174 //console_reset_colour(get_vterm(0));
175 interrupt_set_handler(irq_to_int(7), spurious_int_7);
177 // Now, in order for the console code to continue working,
178 // it needs 0xB8000 mapped somewhere sensible.
179 // NOTE: the whole screen at 0xB8000 fits one page
180 // (80 * 25 * 2 = 4000)
181 intptr_t vram_vaddr;
182 if (alloc_kvpages(1, 1, &vram_vaddr) < 1){
183 panic("Cannot allocate (alloc_kvpages) virtual page for vram");
185 map_mem(0xB8000, vram_vaddr, 1, PTE_PRESENT | PTE_WRITABLE);
186 // Tell the console driver where the new VRAM virtual-address is
187 console_change_vram((uint16_t *) vram_vaddr);
190 #if 0
192 struct addr_space *aspace;
193 struct vm_region *vm_r;
194 aspace = addr_space_new();
195 vm_r = vm_region_new_physical(aspace, 0x10000000, 1);
196 addr_space_switch(aspace);
197 asm volatile ("movl 0x10000800,%%eax" ::: "eax");
199 #endif
202 init_multitasking();
203 read_mb_modules(mbi);
205 //create_task((uint32_t)kmain_task, "Kernel Task", PRIO_HIGH);
206 //create_task((uint32_t)kshell_task, "Kernel Shell", PRIO_NORMAL);
208 sti();
210 // enter an idle loop, so we can see the effects of interrupts
211 for (;;){
212 hlt();
216 void kmain_task(void)
218 critical_state_t crs = critical_enter();
219 console_printf(get_vterm(0), "task_mgr: kmain_task() has been called \n");
220 console_printf(get_vterm(1), "Hey, this is virtual terminal 1\n");
223 // test the device interface
224 struct chardev *tty2 = chardev_get(4, 2);
225 if (tty2){
226 chardev_write(tty2, "Waay it's tty2!\n", 16);
227 } else {
228 trace("chardev_get(4, 2) failed\n");
232 change_task_priority(active_id, PRIO_VERYLOW);
233 critical_exit(crs);
235 for (;;){
236 hlt();