#include #include #include #include "multiboot.h" #include "kernel.h" #include "interrupt.h" #include "timer.h" #include "mem.h" #include "process.h" #include "tty.h" #include "kbd.h" #include "pci/pci.h" #include #include #include int global_errno; extern uint64_t _asm_physmap; /* Check if the compiler thinks if we are targeting the wrong operating system. */ #if defined(__linux__) #error "compiling for linux, not target os" #endif #define STACK_SIZE 65536 __attribute__((aligned(16))) size_t stack[STACK_SIZE / sizeof(size_t)]; static void check_mbmagic(uint64_t magic) { if (magic != MULTIBOOT_BOOTLOADER_MAGIC) { printk("Invalid magic number: 0x%x\n", (unsigned) magic); allstop(); } } void kernel_main(struct multiboot_info *mbinfo, uint64_t mbmagic) { /* we do this first so we can print debug messages */ terminal_initialize(); terminal.writestring("ZOS 64 bit booting...\n"); check_mbmagic(mbmagic); printk("kernel_vma = 0x%llx\n", (uint64_t)_kernel_vma); printk("kernel_end = 0x%llx\n", (uint64_t)_kernel_end); printk("kernel_phys_end = 0x%llx\n", (uint64_t)_kernel_phys_end); printk("kernel_size = %llu KB\n", (uint64_t)_kernel_size/1024); printk("_asm_physmap = %llx\n", _asm_physmap); #define MBADDR(x) (PHY2VIRTP((paddr_t)(x))) /* get modules */ if (mbinfo->mods_count > 0) { void *mod; struct multiboot_mod_list *modlist; char *start; int n; mod = MBADDR(mbinfo->mods_addr); modlist = mod; for (n=0;nmods_count;n++) { char line[80]; printk("Module: %s\n", MBADDR(modlist[n].cmdline)); start = MBADDR(modlist[n].mod_start); memcpy(line, start,80); line[79] = 0; printk("%s\n", line); } } mem_init(mbinfo); printk("mem.kend = 0x%llx\n", (uint64_t)memory.kend); vmem_test(); pci_init(); init_smp(); init_interrupts(); init_timer(200); /* arg is timer tick interrupt Hz */ /* klog isn't really useful before here */ init_syscalls(); init_tasking(); /* from here on out, we may be interrupted */ init_keyboard(); while (1) { schedule(); /* since we're the current task when we call schedule, * we won't get back on the runqueue. The 0 task * will still be allocated. That's ok, it's a static * structure in process.c anyway. * If it changes to dynamic alloc, would want to * clean it up */ printk("shouldn't happen\n"); halt(); } return; } void klog(int level, const char *fmt, ...) { va_list ap; printk("[%u.%u] ", system_time.tv_sec, system_time.tv_nsec/1000000); va_start(ap, fmt); printkv(fmt, ap); va_end(ap); } void panic(const char *fmt, ...) { va_list ap; va_start(ap, fmt); printkv(fmt, ap); va_end(ap); while (1) { allstop(); halt(); } }