bond/x86/src/c/entry.c
2015-02-21 18:38:23 -08:00

98 lines
4.0 KiB
C

#include "type.h"
#include "kdef.h"
#include "multiboot.h"
#include "mem.h"
#include "print.h"
uint8_t g_gdt[8 * 8];
gdt_ptr_t g_gdt_ptr;
uint8_t g_idt[8 * 256];
idt_ptr_t g_idt_ptr;
extern uint32_t text_pos;
extern void init_x64(multiboot_info_t* multiboot_info);
extern void BOCHS_MAGIC_BREAKPOINT(void);
extern void HLT_CPU(void);
extern char kernel_start[];
extern char kernel_end[];
void NATIVE32 kmain(multiboot_info_t *multiboot_info)
{
//init text_position
text_pos = 0;
//detect architecture
kprintf("*Checking architecture...\n");
if (support_x64() == 1)
{
kprintf("Arch: x86_64.\n\n");
init_x64(multiboot_info);
}
kprintf("Arch: x86.\n\n");
kprintf("Kernel Start: 0x%X. End: 0x%X. Size: 0x%X.\n\n", (uint32_t) kernel_start, (uint32_t) kernel_end, (uint32_t) kernel_end - (uint32_t) kernel_start);
kprintf("*Setting up GDT...");
//dummy descriptor
write_segment_descriptor((void *) (&g_gdt[0]), 0, 0, 0);
//ring 0 code seg, non-conforming
write_segment_descriptor((void *) (&g_gdt[8]), 0, 0xFFFFF, SEG_TYPE_CODE_XR | SEG_CODE_DATA | SEG_32_BITS | SEG_GRANULARITY | SEG_PRESENT | SEG_DPL_0);
//ring 3 code seg
write_segment_descriptor((void *) (&g_gdt[16]), 0, 0xFFFFF, SEG_TYPE_CODE_XR | SEG_CODE_DATA | SEG_32_BITS | SEG_GRANULARITY | SEG_PRESENT | SEG_DPL_3);
//ring 0 data RW
write_segment_descriptor((void *) (&g_gdt[24]), 0, 0xFFFFF, SEG_TYPE_DATA_RW | SEG_CODE_DATA | SEG_32_BITS | SEG_GRANULARITY | SEG_PRESENT | SEG_DPL_0);
//ring 3 data
write_segment_descriptor((void *) (&g_gdt[32]), 0, 0xFFFFF, SEG_TYPE_DATA_RW | SEG_CODE_DATA | SEG_32_BITS | SEG_GRANULARITY | SEG_PRESENT | SEG_DPL_3);
g_gdt_ptr.limit = 8 * 8 - 1;
g_gdt_ptr.base = (uint32_t) g_gdt;
load_gdt(&g_gdt_ptr, SEG_SELECTOR(1, 0), SEG_SELECTOR(3, 0));
kprintf(" - Done.\n\n");
//check memory, definitely < 32 so we assume that
kprintf("*Checking memory information...\n");
if(multiboot_info->flags & (1 << 6))
{
multiboot_memory_map_t const *mem_map = (multiboot_memory_map_t *) multiboot_info->mmap_addr;
uint32_t const mem_map_size = multiboot_info->mmap_length / sizeof(multiboot_memory_map_t);
kprintf("BaseAddr - Length - Type\n");
uint32_t total_available_mem = 0;
uint32_t total_reserved_mem = 0;
for (uint32_t i = 0; i < mem_map_size; i++)
{
kprintf("0x%x - 0x%X - 0x%x\n", ((uint32_t) (mem_map + i)->addr), (uint32_t) ((mem_map + i)->len), (uint32_t) (mem_map + i)->type);
if((mem_map + i)->type == MULTIBOOT_MEMORY_RESERVED)
{
total_reserved_mem += (uint32_t) ((mem_map + i)->len);
}
else if ((mem_map + i)->type == MULTIBOOT_MEMORY_AVAILABLE)
{
total_available_mem += (uint32_t) ((mem_map + i)->len);
}
}
kprintf("Total available memory: %uB, %uKB, %uMB.\n", total_available_mem, total_available_mem / 1024, total_available_mem / 1024 / 1024);
kprintf("Total reserved memory: %uB, %uKB, %uMB.\n\n", total_reserved_mem, total_reserved_mem / 1024, total_reserved_mem / 1024 / 1024);
}
else
{
kprintf("Memory information is currently unavailable.\n\n");
}
//check modules
kprintf("*Checking loaded kernel modules...\n");
if(multiboot_info->flags & (1 << 3))
{
multiboot_module_t const * mods_list = (multiboot_module_t *)multiboot_info->mods_addr;
uint32_t const mods_count = multiboot_info->mods_count;
kprintf("%u module(s) loaded:\n", mods_count);
kprintf("Name - StartAddr - EndAddr\n");
for (uint64_t i = 0; i < mods_count; i++)
{
kprintf("%s - 0x%X - 0x%X\n", (char *) (mods_list + i)->cmdline, (mods_list + i)->mod_start, (mods_list + i)->mod_end);
}
kprintf("\n");
}
else
{
kprintf("Module information is currently unavailable.\n\n");
}
HLT_CPU();
return;
}