// 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; // semaphore for if interrupts are disabled u32_t timer; 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(HOS_TIMER_FREQ); 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(" \e[31mWe \e[1mcan \e[32mfinally \e[33;45msee\e[0;7m text\e[0m!\n"); u16_t *vidMem = (u16_t *)(CONSOLE_MEMORY + 160); u16_t i; for (i = 0; i < 256; i++) { *vidMem++ = (i << 8) | '*'; if (((u32_t)vidMem % 32) == 0) vidMem += 64; } if (real_mode_module) { kprintf("Real mode module present\n"); } criticalCounter--; } void isr(u32_t num) { criticalCounter++; switch (num) { case 0x20: // timer (*(u16_t *)CONSOLE_MEMORY)++; timer++; pic_eoi(); break; case 0x21: // keyboard isr_keyboard(); pic_eoi(); break; default: kprintf("Unhandled interrupt #%d, CR2 = 0x%x!\n", num, read_cr2()); halt(); } criticalCounter--; } void k_enter_critical() // functions for implementing "atomic actions" { disable_ints(); criticalCounter++; } void k_leave_critical() { criticalCounter--; if (!criticalCounter) enable_ints(); }