151 lines
3.4 KiB
C
151 lines
3.4 KiB
C
|
|
#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"
|
|
|
|
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()
|
|
{
|
|
kprintf("k_init()\n");
|
|
k_enter_critical();
|
|
mm_init();
|
|
vmm_init();
|
|
if (real_mode_module)
|
|
{
|
|
kprintf("Real mode module present\n");
|
|
}
|
|
u32_t alloc_size = 1;
|
|
void *addresses[32];
|
|
memsetd(addresses, 0, 32);
|
|
void *address;
|
|
int i;
|
|
for (i = -5; i < 5; i++)
|
|
{
|
|
kprintf("Counting down... %d\t0x%x\t%u\n", i, i, i);
|
|
}
|
|
for (i = 0; i < 32; i++)
|
|
{
|
|
kprintf("\e[31mAllocating %u (0x%x) bytes\e[0m,\tmm_freepages = %u...\n", alloc_size, alloc_size, mm_freepages);
|
|
address = kmalloc(alloc_size);
|
|
if (!address)
|
|
break;
|
|
addresses[i] = address;
|
|
alloc_size <<= 1;
|
|
}
|
|
for (i = 0; i < 32; i++)
|
|
{
|
|
if (!addresses[i])
|
|
break;
|
|
kprintf("\e[32mFreeing 0x%x\e[0m,\tmm_freepages = %u...\n", addresses[i], mm_freepages);
|
|
kfree(addresses[i]);
|
|
}
|
|
|
|
// dev_init();
|
|
kprintf("End of k_init()\n");
|
|
criticalCounter--;
|
|
}
|
|
|
|
void isr(u32_t num)
|
|
{
|
|
criticalCounter++;
|
|
kprintf("Interrupt #%d!\n", num);
|
|
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();
|
|
}
|
|
|