xref: /haiku/src/system/boot/platform/bios_ia32/start.cpp (revision 323b65468e5836bb27a5e373b14027d902349437)
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