hos/kernel/kernel.c

166 lines
3.8 KiB
C

// kernel.h
// Author: Josh Holtrop
// Date: 08/16/04
// This is the main kernel initialization and boot-strapping file
#include "kernel.h"
#include "multiboot.h"
#include "module.h"
#include "lang/asmfuncs.h"
#include "functions.h"
#include "mm/mm.h"
#include "mm/vmm.h"
#include "char/parallel.h"
#include "kout.h"
#include "lang/conv.h"
#include "char/vconsole.h"
#include "fs/devices.h"
#include "console.h"
#include "sys/io.h"
#include "sys/pic.h"
mb_info_t mb_info_block;
mb_mmap_t mb_mmap[MAX_MMAP];
u32_t mmap_entries;
mb_module_t mb_modules[MAX_MODULES];
mb_apm_t mb_apm_table;
byte real_mode_module;
char mb_cmdline[256];
int criticalCounter;
extern u32_t mm_freepages;
/* This function runs in segmented memory - 0xC000_0000 is mapped to 0x0 but 0x0
itself is an invalid linear address. Therefore, the multiboot information addresses
must be manually adjusted by VIRT_OFFSET to become valid linear addresses. */
int k_mbsave(mb_info_t *mbinfo, unsigned int mb_magic)
{
real_mode_module = 0;
if (mb_magic != MULTIBOOT_BOOTLOADER_MAGIC)
{
char *msg = "Bad multiboot magic identifier!";
char *dest = (char *) CONSOLE_MEMORY;
while (*msg)
{
*dest++ = *msg++;
*dest++ = 0x04; //red error message
}
for (;;) ;
}
mb_info_block = *mbinfo;
if (mb_info_block.flags & MB_BOOTLOADER_COMMAND_LINE)
{
mb_info_block.cmdline += VIRT_OFFSET;
memcpy(mb_cmdline, (void *)mb_info_block.cmdline, 256);
mb_cmdline[255] = 0;
}
if (mb_info_block.flags & MB_BOOTLOADER_MODS)
{
mb_info_block.mods_addr += VIRT_OFFSET;
int i;
for (i = 0; i < mb_info_block.mods_count && i < MAX_MODULES; i++)
{
mb_modules[i] = ((mb_module_t *)mb_info_block.mods_addr)[i];
mb_modules[i].mod_start += VIRT_OFFSET;
mb_modules[i].mod_end += VIRT_OFFSET;
hos_module_header_t *mod = (hos_module_header_t *)mb_modules[i].mod_start;
if (mod->mod_type == MOD_REAL_MODE)
real_mode_module = 1;
}
}
if (mb_info_block.flags & MB_BOOTLOADER_MMAP)
{
mb_info_block.mmap_addr += (VIRT_OFFSET - 4); //-4 to get to size field, not base_addr_low field
mb_mmap_t *mmap = (mb_mmap_t *)mb_info_block.mmap_addr;
int i, sz = 0;
for (i = 0; sz < mb_info_block.mmap_length && i < MAX_MMAP; i++)
{
sz += mmap->size + 4;
mb_mmap[i] = *mmap;
mmap = (mb_mmap_t *)(((u32_t) mmap) + mmap->size + 4);
mmap_entries++;
}
}
if (mb_info_block.flags & MB_BOOTLOADER_APM)
{
mb_info_block.apm_table += VIRT_OFFSET;
mb_apm_table = *(mb_apm_t *)mb_info_block.apm_table;
}
return real_mode_module;
}
/* Main kernel initialization routine */
void k_init()
{
criticalCounter++;
pic_remap(0x20, 0x28);
pic_mask1(0); //unmask IRQ's 0-7
pic_mask2(0); //unmask IRQ's 8-15
timer_init(100);
mm_init();
vmm_init();
// test the memory manager
/* char *all;
int size = 1;
u32_t add = 1;
for (;;)
{
all = kmalloc(size);
add = (u32_t)all;
if (!add)
break;
u32_t pte = (add >> 12) & 0x3FF;
u32_t pde = add >> 22;
u32_t mapped = *((u32_t *)(0xFFC00000 | (pde << 12) | (pte << 2)));
kprintf("Got address 0x%x mapped to 0x%x size=%d\n", add, mapped, size);
memset(all, 0, size);
size <<= 1;
}*/
devices_init();
console_init(6);
console_activate(1);
kprintf("We can finally see text!\n");
while (1)
(*(u16_t *)CONSOLE_MEMORY)++;
if (real_mode_module)
{
kprintf("Real mode module present\n");
}
u16_t *vidMem = (u16_t *)CONSOLE_MEMORY;
u16_t i;
for (i = 0; i < 256; i++)
{
*vidMem++ = (i << 8) | '*';
if (((u32_t)vidMem % 32) == 0)
vidMem += 64;
}
criticalCounter--;
}
void isr(u32_t num)
{
criticalCounter++;
kprintf("Interrupt #%d, CR2 = 0x%x!\n", num, read_cr2());
halt();
switch (num)
{
}
criticalCounter--;
}
void k_enter_critical() // functions for implementing "atomic actions"
{
disable_ints();
criticalCounter++;
}
void k_leave_critical()
{
criticalCounter--;
if (!criticalCounter)
enable_ints();
}