#include <string.h>
#include <KernelExport.h>
#include <arch/x86/arch_cpu.h>
#include <boot/arch/x86/arch_cpu.h>
#include <boot/arch/x86/arch_hpet.h>
#include <boot/platform.h>
#include <boot/heap.h>
#include <boot/stage2.h>
#include "acpi.h"
#include "apm.h"
#include "bios.h"
#include "console.h"
#include "cpu.h"
#include "debug.h"
#include "interrupts.h"
#include "keyboard.h"
#include "long.h"
#include "mmu.h"
#include "multiboot.h"
#include "serial.h"
#include "smp.h"
extern void (*__ctor_list)(void);
extern void (*__ctor_end)(void);
extern uint8 __bss_start;
extern uint8 _end;
extern "C" int main(stage2_args *args);
extern "C" void _start(void);
uint32 sBootOptions;
static void
clear_bss(void)
{
memset(&__bss_start, 0, &_end - &__bss_start);
}
static void
call_ctors(void)
{
void (**f)(void);
for (f = &__ctor_list; f < &__ctor_end; f++) {
(**f)();
}
}
extern "C" uint32
platform_boot_options(void)
{
#if 0
if (!gKernelArgs.fb.enabled)
sBootOptions |= check_for_boot_keys();
#endif
return sBootOptions;
}
static void
smp_start_kernel(void)
{
uint32 curr_cpu = smp_get_current_cpu();
preloaded_elf32_image *image = static_cast<preloaded_elf32_image *>(
gKernelArgs.kernel_image.Pointer());
asm("movl %%eax, %%cr0" : : "a" ((1 << 31) | (1 << 16) | (1 << 5) | 1));
asm("cld");
asm("fninit");
set_debug_idt();
struct gdt_idt_descr gdt_descr;
gdt_descr.limit = sizeof(gBootGDT) - 1;
gdt_descr.base = gBootGDT;
asm("lgdt %0;"
: : "m" (gdt_descr));
asm("pushl %0; "
"pushl %1; "
"pushl $0x0;"
"pushl %2; "
"ret; "
: : "g" (curr_cpu), "g" (&gKernelArgs),
"g" (image->elf_header.e_entry));
panic("kernel returned!\n");
}
extern "C" void
platform_start_kernel(void)
{
if (gKernelArgs.kernel_image->elf_class == ELFCLASS64) {
long_start_kernel();
return;
}
static struct kernel_args *args = &gKernelArgs;
addr_t stackTop
= gKernelArgs.cpu_kstack[0].start + gKernelArgs.cpu_kstack[0].size;
preloaded_elf32_image *image = static_cast<preloaded_elf32_image *>(
gKernelArgs.kernel_image.Pointer());
smp_init_other_cpus();
debug_cleanup();
mmu_init_for_kernel();
heap_release();
stdout = NULL;
smp_boot_other_cpus(smp_start_kernel);
dprintf("kernel entry at %x\n", image->elf_header.e_entry);
asm("movl %0, %%eax; "
"movl %%eax, %%esp; "
: : "m" (stackTop));
asm("pushl $0x0; "
"pushl %0; "
"pushl $0x0;"
"pushl %1; "
"ret; "
: : "g" (args), "g" (image->elf_header.e_entry));
panic("kernel returned!\n");
}
extern "C" void
platform_exit(void)
{
out8(0xfe, 0x64);
}
extern "C" void
_start(void)
{
stage2_args args;
asm("cld");
asm("fninit");
clear_bss();
call_ctors();
args.heap_size = 0;
args.arguments = NULL;
serial_init();
serial_enable();
interrupts_init();
console_init();
cpu_init();
mmu_init();
debug_init_post_mmu();
parse_multiboot_commandline(&args);
sBootOptions = check_for_boot_keys();
apm_init();
acpi_init();
smp_init();
hpet_init();
dump_multiboot_info();
main(&args);
}