1 /* 2 * Copyright 2003-2010, Axel Dörfler, axeld@pinc-software.de. 3 * Distributed under the terms of the MIT License. 4 */ 5 6 7 #include <string.h> 8 9 #include <KernelExport.h> 10 11 #include <arch/cpu.h> 12 #include <boot/platform.h> 13 #include <boot/heap.h> 14 #include <boot/stage2.h> 15 16 #include "acpi.h" 17 #include "apm.h" 18 #include "bios.h" 19 #include "console.h" 20 #include "cpu.h" 21 #include "debug.h" 22 #include "hpet.h" 23 #include "interrupts.h" 24 #include "keyboard.h" 25 #include "mmu.h" 26 #include "multiboot.h" 27 #include "serial.h" 28 #include "smp.h" 29 30 31 #define HEAP_SIZE (128 * 1024) 32 33 // GCC defined globals 34 extern void (*__ctor_list)(void); 35 extern void (*__ctor_end)(void); 36 extern uint8 __bss_start; 37 extern uint8 _end; 38 39 extern "C" int main(stage2_args *args); 40 extern "C" void _start(void); 41 42 43 uint32 sBootOptions; 44 45 46 static void 47 clear_bss(void) 48 { 49 memset(&__bss_start, 0, &_end - &__bss_start); 50 } 51 52 53 static void 54 call_ctors(void) 55 { 56 void (**f)(void); 57 58 for (f = &__ctor_list; f < &__ctor_end; f++) { 59 (**f)(); 60 } 61 } 62 63 64 extern "C" uint32 65 platform_boot_options(void) 66 { 67 #if 0 68 if (!gKernelArgs.fb.enabled) 69 sBootOptions |= check_for_boot_keys(); 70 #endif 71 return sBootOptions; 72 } 73 74 75 extern "C" void 76 platform_start_kernel(void) 77 { 78 static struct kernel_args *args = &gKernelArgs; 79 // something goes wrong when we pass &gKernelArgs directly 80 // to the assembler inline below - might be a bug in GCC 81 // or I don't see something important... 82 addr_t stackTop 83 = gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size; 84 85 smp_init_other_cpus(); 86 debug_cleanup(); 87 mmu_init_for_kernel(); 88 89 // We're about to enter the kernel -- disable console output. 90 stdout = NULL; 91 92 smp_boot_other_cpus(); 93 94 dprintf("kernel entry at %lx\n", 95 gKernelArgs.kernel_image.elf_header.e_entry); 96 97 asm("movl %0, %%eax; " // move stack out of way 98 "movl %%eax, %%esp; " 99 : : "m" (stackTop)); 100 asm("pushl $0x0; " // we're the BSP cpu (0) 101 "pushl %0; " // kernel args 102 "pushl $0x0;" // dummy retval for call to main 103 "pushl %1; " // this is the start address 104 "ret; " // jump. 105 : : "g" (args), "g" (gKernelArgs.kernel_image.elf_header.e_entry)); 106 107 panic("kernel returned!\n"); 108 } 109 110 111 extern "C" void 112 platform_exit(void) 113 { 114 // reset the system using the keyboard controller 115 out8(0xfe, 0x64); 116 } 117 118 119 extern "C" void 120 _start(void) 121 { 122 stage2_args args; 123 124 asm("cld"); // Ain't nothing but a GCC thang. 125 asm("fninit"); // initialize floating point unit 126 127 clear_bss(); 128 call_ctors(); 129 // call C++ constructors before doing anything else 130 131 args.heap_size = HEAP_SIZE; 132 args.arguments = NULL; 133 134 serial_init(); 135 serial_enable(); 136 interrupts_init(); 137 console_init(); 138 cpu_init(); 139 mmu_init(); 140 debug_init_post_mmu(); 141 parse_multiboot_commandline(&args); 142 143 // reading the keyboard doesn't seem to work in graphics mode 144 // (maybe a bochs problem) 145 sBootOptions = check_for_boot_keys(); 146 // if (sBootOptions & BOOT_OPTION_DEBUG_OUTPUT) 147 // serial_enable(); 148 149 apm_init(); 150 acpi_init(); 151 smp_init(); 152 hpet_init(); 153 dump_multiboot_info(); 154 main(&args); 155 } 156 157