/* * multiboot i386 (pc) kernel entry point */ int kmain(struct multiboot *mboot, uint32_t mboot_mag, uintptr_t esp) { initial_esp = esp; extern char * cmdline; uint32_t mboot_mods_count = 0; mboot_mod_t * mboot_mods = NULL; mboot_ptr = mboot; ENABLE_EARLY_BOOT_LOG(0); assert(mboot_mag == MULTIBOOT_EAX_MAGIC && "Didn't boot with multiboot, not sure how we got here."); debug_print(NOTICE, "Processing Multiboot information."); /* Initialize core modules */ gdt_install(); /* Global descriptor table */ idt_install(); /* IDT */ isrs_install(); /* Interrupt service requests */ irq_install(); /* Hardware interrupt requests */ if (mboot_ptr->flags & (1 << 3)) { debug_print(NOTICE, "There %s %d module%s starting at 0x%x.", mboot_ptr->mods_count == 1 ? "is" : "are", mboot_ptr->mods_count, mboot_ptr->mods_count == 1 ? "" : "s", mboot_ptr->mods_addr); debug_print(NOTICE, "Current kernel heap start point would be 0x%x.", &end); if (mboot_ptr->mods_count > 0) { uintptr_t last_mod = (uintptr_t)&end; uint32_t i; mboot_mods = (mboot_mod_t *)mboot_ptr->mods_addr; mboot_mods_count = mboot_ptr->mods_count; for (i = 0; i < mboot_ptr->mods_count; ++i ) { mboot_mod_t * mod = &mboot_mods[i]; uint32_t module_start = mod->mod_start; uint32_t module_end = mod->mod_end; if ((uintptr_t)mod + sizeof(mboot_mod_t) > last_mod) { /* Just in case some silly person put this *behind* the modules... */ last_mod = (uintptr_t)mod + sizeof(mboot_mod_t); } debug_print(NOTICE, "Module %d is at 0x%x:0x%x", i, module_start, module_end); if (last_mod < module_end) { last_mod = module_end; } } debug_print(NOTICE, "Moving kernel heap start to 0x%x", last_mod); kmalloc_startat(last_mod); } } paging_install(mboot_ptr->mem_upper + mboot_ptr->mem_lower); if (mboot_ptr->flags & (1 << 6)) { debug_print(NOTICE, "Parsing memory map."); mboot_memmap_t * mmap = (void *)mboot_ptr->mmap_addr; while ((uintptr_t)mmap < mboot_ptr->mmap_addr + mboot_ptr->mmap_length) { if (mmap->type == 2) { for (unsigned long long int i = 0; i < mmap->length; i += 0x1000) { if (mmap->base_addr + i > 0xFFFFFFFF) break; /* xxx */ debug_print(INFO, "Marking 0x%x", (uint32_t)(mmap->base_addr + i)); paging_mark_system((mmap->base_addr + i) & 0xFFFFF000); } } mmap = (mboot_memmap_t *) ((uintptr_t)mmap + mmap->size + sizeof(uintptr_t)); } } paging_finalize(); { char cmdline_[1024]; size_t len = strlen((char *)mboot_ptr->cmdline); memmove(cmdline_, (char *)mboot_ptr->cmdline, len + 1); /* Relocate the command line */ cmdline = (char *)kmalloc(len + 1); memcpy(cmdline, cmdline_, len + 1); } /* Memory management */ heap_install(); /* Kernel heap */ if (cmdline) { args_parse(cmdline); } vfs_install(); tasking_install(); /* Multi-tasking */ timer_install(); /* PIC driver */ fpu_install(); /* FPU/SSE magic */ syscalls_install(); /* Install the system calls */ shm_install(); /* Install shared memory */ modules_install(); /* Modules! */ DISABLE_EARLY_BOOT_LOG(); /* Load modules from bootloader */ debug_print(NOTICE, "%d modules to load", mboot_mods_count); for (unsigned int i = 0; i < mboot_ptr->mods_count; ++i ) { mboot_mod_t * mod = &mboot_mods[i]; uint32_t module_start = mod->mod_start; uint32_t module_end = mod->mod_end; size_t module_size = module_end - module_start; if (!module_quickcheck((void *)module_start)) { debug_print(NOTICE, "Loading ramdisk: 0x%x:0x%x", module_start, module_end); ramdisk_mount(module_start, module_size); } else { debug_print(NOTICE, "Loading a module: 0x%x:0x%x", module_start, module_end); module_data_t * mod_info = (module_data_t *)module_load_direct((void *)(module_start), module_size); if (mod_info) { debug_print(NOTICE, "Loaded: %s", mod_info->mod_info->name); } } } /* Map /dev to a device mapper */ map_vfs_directory("/dev"); if (args_present("root")) { vfs_mount_type("ext2", args_value("root"), "/"); } if (args_present("start")) { char * c = args_value("start"); if (!c) { debug_print(WARNING, "Expected an argument to kernel option `start`. Ignoring."); } else { debug_print(NOTICE, "Got start argument: %s", c); boot_arg = strdup(c); } } if (!fs_root) { debug_print(CRITICAL, "No root filesystem is mounted. Skipping init."); map_vfs_directory("/"); switch_task(0); } /* Prepare to run /bin/init */ char * argv[] = { "/bin/init", boot_arg, NULL }; int argc = 0; while (argv[argc]) { argc++; } system(argv[0], argc, argv); /* Run init */ return 0; }
void main(uint32_t magic, struct multiboot_info *mbi, uintptr_t esp, uintptr_t stack_end) { stack_start = esp; stack_size = stack_end - stack_start; vga_driver = vga_init(); com_driver = serial_init(); logging_init(vga_driver, com_driver); assert(magic == MULTIBOOT_MAGIC); assert(mbi->flags & MULTIBOOT_LOADER); kprintf(INFO, "\033\012Toutatis kernel booting from %s\033\017\n", (char *)(mbi->boot_loader_name + (uint32_t)&kernel_voffset)); arch_init(); initrd_init(mbi); assert(mbi->flags & MULTIBOOT_MEMINFO); paging_init((mbi->mem_lower + mbi->mem_upper) * 1024); paging_mark_reserved((uint32_t)mbi - (uint32_t)&kernel_voffset); assert(mbi->flags & MULTIBOOT_MMAP); for (mmap_entry_t *mmap = (mmap_entry_t *)(mbi->mmap_addr + (uint32_t)&kernel_voffset); (uint32_t)mmap < mbi->mmap_addr + (uint32_t)&kernel_voffset + mbi->mmap_length; mmap = (mmap_entry_t *)((uint32_t)mmap + mmap->size + sizeof(mmap->size))) { if (mmap->type == 2) { for (uint64_t i = 0; i < mmap->length; i += FRAME_SIZE) { paging_mark_reserved((mmap->addr + i) & 0xfffff000); } } } paging_finalize(); void *p1 = kmalloc(8); void *p2 = kmalloc(8); *((char *)p1) = 'a'; kprintf(INFO, "p1 @ 0x%x\n", (uint32_t)p1); kprintf(INFO, "p2 @ 0x%x\n", (uint32_t)p2); kfree(p2); kfree(p1); void *p3 = kmalloc(16); kprintf(INFO, "p3 @ 0x%x\n", (uint32_t)p3); uintptr_t phys; void *p4 = kmalloc_ap(0x1a0000, &phys); memset(p4, 0, 0x1a0000); *((char *)p4) = 'z'; kprintf(INFO, "p4 @ 0x%x phys = %x\n", (uint32_t)p4, phys); void *p5 = kmalloc(0x02); kprintf(INFO, "p5 @ 0x%x\n", (uint32_t)p5); kfree(p5); kfree(p4); kfree(p3); print_mmap(mbi); syscall_init(); scheduling_init(); keyboard_init(); process_t *proc1 = create_process("Process 1", 1); process_t *proc2 = create_process("Process 2", 1); process_t *proc3 = create_process("Process 3", 1); process_t *procs[] = { proc1, proc2, proc3 }; unsigned int k = 0; unsigned int off = 0; for (k = 0; k < 10; ++k) { if (!create_thread(procs[k % 3], func2, (void *)(off + 80*2), 1, 0, 0)) { kprintf(INFO, "Oups\n"); stop(); } if (!create_thread(procs[k % 3], func1, (void *)k, 1, 1, 0)) { kprintf(INFO, "Oups\n"); stop(); } off += 2; } //create_thread(proc1, func3, (void *)0, 1, 1, 1); k = 0; unsigned int i = 0; off = 0; for (;;) { uint16_t *video = (uint16_t *)(0xc00b8000 + 80); *video = (uint16_t)alph[i++ % sizeof(alph)] | 0x0f00; if (k % 1 == 0) { //set_pos(0, 23); //vga_print_dec(k); //kprintf(INFO, "mem used: %6x num threads:%3d \n", mem_used(kheap), get_num_threads()); } /* if (!create_thread(proc1, func2, (void *)(off + 80*2), 1, 0, 0)) { kprintf(INFO, "Oups\n"); break; } off += 2; off %= (60 * (25-2)); */ char c = keyboard_lastchar(); if (c == 'u') { create_thread(proc1, func1, (void *)5, 1, 1, 0); } else if (c == 'k') { create_thread(proc1, func2, (void *)off, 1, 0, 0); off += 2; } ++k; } serial_terminate(); stop(); }