void __attribute__((noreturn)) kernel_main(unsigned int _memory_size) { struct vm_translation_map *init_map; struct process *init_proc; vm_page_init(_memory_size); init_map = vm_translation_map_init(); boot_init_heap((char*) KERNEL_HEAP_BASE + PAGE_STRUCTURES_SIZE(_memory_size)); vm_address_space_init(init_map); bootstrap_vm_cache(); bool_init_kernel_process(); boot_init_thread(); // Start other threads REGISTERS[REG_THREAD_RESUME] = 0xffffffff; spawn_kernel_thread("Grim Reaper", grim_reaper, 0); init_proc = exec_program("program.elf"); // Idle task for (;;) { if (list_is_empty(&init_proc->thread_list)) { kprintf("init process has exited, shutting down\n"); REGISTERS[REG_THREAD_HALT] = 0xffffffff; } reschedule(); } }
/* init virtual memory */ status_t vm_init(kernel_args_t *kargs) { addr_t heap_base; /* Kernel's heap base */ size_t heap_size; /* Kernel's heap size */ status_t err; /* clear VM statistics */ memset(&VM_State, 0, sizeof(vm_stat_t)); /* translation map module init */ err = vm_translation_map_init(kargs); if(err) panic("vm_init: translation map init failed!\n"); /* execute architecture-specific init */ err = arch_vm_init(kargs); if(err) panic("arch_vm_init: failed!\n"); /* start platform-specific init */ err = platform_vm_init(kargs); if(err) panic("platform_vm_init: failed!\n"); /* init memory size */ err = vm_page_preinit(kargs); if(err) panic("vm_page_preinit: failed!\n"); /* init kernel's heap */ { /* compute heap size */ heap_size = ROUNDUP( vm_phys_mem_size() / SYSCFG_KERNEL_HEAP_FRAC, 1*1024*1024 /* Mbyte */ ); if(heap_size > SYSCFG_KERNEL_HEAP_MAX) heap_size = SYSCFG_KERNEL_HEAP_MAX; /* allocate heap area */ heap_base = vm_alloc_from_kargs(kargs, heap_size, VM_PROT_KERNEL_DEFAULT); /* init heap */ heap_init(heap_base, heap_size); /* Fuf... Now kmalloc and kfree is available */ } /* init vm page module */ err = vm_page_init(kargs); if(err) panic("vm_page_init: failed!\n"); /*** Important note: After this point vm_alloc_from_kargs must not be used *** because physical pages bookkeping is turned on. ***/ /* prefinal stage of translation map module init */ err = vm_translation_map_init_prefinal(kargs); if(err) panic("vm_init: prefinal stage of translation map init failed!\n"); /* start prefinal init stage of architecture-specific parts */ err = arch_vm_init_prefinal(kargs); if(err) panic("arch_vm_init_prefinal: stage failed!\n"); /* start prefinal stages of platform-specific init */ err = platform_vm_init_prefinal(kargs); if(err) panic("platform_vm_init_prefinal: stage failed!\n"); /* init address spaces module */ err = vm_address_spaces_init(kargs); if(err) panic("vm_address_spaces_init: failed!\n"); /* init vm objects module */ err = vm_objects_init(kargs); if(err) panic("vm_objects_init: failed!\n"); /* create initial kernel space */ if(vm_create_kernel_aspace("kernel_space", KERNEL_BASE, KERNEL_SIZE) == VM_INVALID_ASPACEID) panic("vm_init: failed to create initial kernel space!\n"); /*** Final stages of VM init ***/ /* final stage of translation map module init */ err = vm_translation_map_init_final(kargs); if(err) panic("vm_init: final stage of translation map init failed!\n"); /* start final init stage of architecture-specific parts */ err = arch_vm_init_final(kargs); if(err) panic("arch_vm_init_final: final stage failed!\n"); /* final stages of platform-specific init */ err = platform_vm_init_final(kargs); if(err) panic("platform_vm_init_final: final stage failed!\n"); /* final stages of vm page module init */ err = vm_page_init_final(kargs); if(err) panic("vm_page_init_final: failed!\n"); /* init memory structures */ { aspace_id kid = vm_get_kernel_aspace_id(); object_id id; char name[SYS_MAX_OS_NAME_LEN]; int i; /* create kernel_image memory object and its mapping */ id = vm_create_physmem_object(VM_NAME_KERNEL_IMAGE, kargs->phys_kernel_addr.start, kargs->phys_kernel_addr.size, VM_OBJECT_PROTECT_ALL); if(id == VM_INVALID_OBJECTID) panic("vm_init: failed to create kernel_image object!\n"); err = vm_map_object_exactly(kid, id, VM_PROT_KERNEL_ALL, kargs->virt_kernel_addr.start); if(err != NO_ERROR) panic("vm_init: failed to create mapping of kernel_image object!\n"); /* init physical page counters */ err = vm_page_init_wire_counters(kargs->virt_kernel_addr.start, kargs->virt_kernel_addr.size); if(err != NO_ERROR) panic("vm_init: failed to init counters for kernel_image object!\n"); /* create kernel stacks memory objects and mappings */ for(i = 0; i < SYSCFG_MAX_CPUS; i++) { snprintf(name, SYS_MAX_OS_NAME_LEN, VM_NAME_KERNEL_CPU_STACK_FMT, i); id = vm_create_physmem_object(name, kargs->phys_cpu_kstack[i].start, kargs->phys_cpu_kstack[i].size, VM_OBJECT_PROTECT_ALL); if(id == VM_INVALID_OBJECTID) panic("vm_init: failed to create %s object!\n", name); err = vm_map_object_exactly(kid, id, VM_PROT_KERNEL_ALL, kargs->virt_cpu_kstack[i].start); if(err != NO_ERROR) panic("vm_init: failed to create mapping of %s object!\n", name); /* init counters */ err = vm_page_init_wire_counters(kargs->virt_cpu_kstack[i].start, kargs->virt_cpu_kstack[i].size); if(err != NO_ERROR) panic("vm_init: failed to init counters for %s object!\n", name); } /* create kernel_heap memory object and its mapping */ id = vm_create_virtmem_object(VM_NAME_KERNEL_HEAP, kid, heap_base, heap_size, VM_OBJECT_PROTECT_ALL); if(id == VM_INVALID_OBJECTID) panic("vm_init: failed to create kernel_heap object!\n"); err = vm_map_object_exactly(kid, id, VM_PROT_KERNEL_ALL, heap_base); if(err != NO_ERROR) panic("vm_init: failed to create mapping of kernel_heap object!\n"); /* init counters for heap pages */ err = vm_page_init_wire_counters(heap_base, heap_size); if(err != NO_ERROR) panic("vm_init: failed to init counters for kernel_heap object!\n"); /* create bootfs_image memory object */ id = vm_create_physmem_object(VM_NAME_BOOTFS_IMAGE, kargs->btfs_image_addr.start, kargs->btfs_image_addr.size, VM_OBJECT_PROTECT_ALL); if(id == VM_INVALID_OBJECTID) panic("vm_init: failed to create bootfs_image object!\n"); } /* end of init memory structures */ return NO_ERROR; }