/** * This is the first real C function ever called. It performs a lot of * hardware-specific initialization, then creates a pseudo-context to * execute the bootstrap function in. */ void kmain() { GDB_CALL_HOOK(boot); dbg_init(); dbgq(DBG_CORE, "Kernel binary:\n"); dbgq(DBG_CORE, " text: 0x%p-0x%p\n", &kernel_start_text, &kernel_end_text); dbgq(DBG_CORE, " data: 0x%p-0x%p\n", &kernel_start_data, &kernel_end_data); dbgq(DBG_CORE, " bss: 0x%p-0x%p\n", &kernel_start_bss, &kernel_end_bss); page_init(); pt_init(); slab_init(); pframe_init(); acpi_init(); apic_init(); pci_init(); intr_init(); gdt_init(); /* initialize slab allocators */ #ifdef __VM__ anon_init(); shadow_init(); #endif vmmap_init(); proc_init(); kthread_init(); #ifdef __DRIVERS__ bytedev_init(); blockdev_init(); #endif void *bstack = page_alloc(); pagedir_t *bpdir = pt_get(); KASSERT(NULL != bstack && "Ran out of memory while booting."); context_setup(&bootstrap_context, bootstrap, 0, NULL, bstack, PAGE_SIZE, bpdir); context_make_active(&bootstrap_context); panic("\nReturned to kmain()!!!\n"); }
static int kthread_handler(void *arg) { #define k_ctx ((kthread_context_t *)arg) #if 0 printf("Thread to be scheduled on cpu\n"); #endif kthread_init(k_ctx); #if 0 printf("\nThread (tid : %u, pid : %u, cpu : %d, cpu-apic-id %d) ready to run !!\n\n", k_ctx->tid, k_ctx->pid, k_ctx->cpuid, k_ctx->cpu_apic_id); #endif k_ctx->kthread_app_func(NULL); #undef k_ctx // free(arg); return 0; }
/* initialize ethread */ void ethread_init(struct ethread *thread, struct eprocess *process, struct task_struct *tsk) { ktrace("\n"); /* attach to the containing process */ ref_object((PVOID)process); write_lock(&process->ep_lock); thread->threads_process = process; write_unlock(&process->ep_lock); /* FIXME create a thread object and hook in to the Linux task */ thread->et_task = tsk; atomic_set(&thread->et_count, 0); /* FIXME */ thread->et_ops = (struct ethread_operations *)ðread_ops; INIT_LIST_HEAD(&thread->lpc_reply_chain); INIT_LIST_HEAD(&thread->irp_list); INIT_LIST_HEAD(&thread->active_timer_list_head); thread->active_timer_list_lock = SPIN_LOCK_UNLOCKED; thread->thread_lock = SPIN_LOCK_UNLOCKED; /* FIXME: semaphore_init */ thread->cid.unique_process = process->unique_processid; thread->win32_start_address = 0; /* context->Eax, default is 0 */ lock_process(process); list_add_tail(&thread->thread_list_entry, &process->thread_list_head); unlock_process(process); add_ethread(thread->et_task, thread); if (atomic_read(&thread->et_count) == 1) /* FIXME: add this to win32_thread.c */ ref_object(thread); kthread_init(&thread->tcb, process); } /* end ethread_init */
/** * This is the first real C function ever called. It performs a lot of * hardware-specific initialization, then creates a pseudo-context to * execute the bootstrap function in. */ void kmain() { GDB_CALL_HOOK(boot); dbg_init(); dbgq(DBG_CORE, "Kernel binary:\n"); dbgq(DBG_CORE, " text: 0x%p-0x%p\n", &kernel_start_text, &kernel_end_text); dbgq(DBG_CORE, " data: 0x%p-0x%p\n", &kernel_start_data, &kernel_end_data); dbgq(DBG_CORE, " bss: 0x%p-0x%p\n", &kernel_start_bss, &kernel_end_bss); page_init(); pt_init(); slab_init(); pframe_init(); acpi_init(); apic_init(); pci_init(); intr_init(); gdt_init(); /* initialize slab allocators */ #ifdef __VM__ anon_init(); shadow_init(); #endif vmmap_init(); proc_init(); kthread_init(); #ifdef __DRIVERS__ bytedev_init(); blockdev_init(); #endif void *bstack = page_alloc(); pagedir_t *bpdir = pt_get(); KASSERT(NULL != bstack && "Ran out of memory while booting."); /* This little loop gives gdb a place to synch up with weenix. In the * past the weenix command started qemu was started with -S which * allowed gdb to connect and start before the boot loader ran, but * since then a bug has appeared where breakpoints fail if gdb connects * before the boot loader runs. See * * https://bugs.launchpad.net/qemu/+bug/526653 * * This loop (along with an additional command in init.gdb setting * gdb_wait to 0) sticks weenix at a known place so gdb can join a * running weenix, set gdb_wait to zero and catch the breakpoint in * bootstrap below. See Config.mk for how to set GDBWAIT correctly. * * DANGER: if GDBWAIT != 0, and gdb is not running, this loop will never * exit and weenix will not run. Make SURE the GDBWAIT is set the way * you expect. */ while (gdb_wait) ; context_setup(&bootstrap_context, bootstrap, 0, NULL, bstack, PAGE_SIZE, bpdir); context_make_active(&bootstrap_context); panic("\nReturned to kmain()!!!\n"); }
extern void gtthread_app_init() { kthread_context_t *k_ctx, *k_ctx_main; kthread_t k_tid; unsigned int num_cpus, inx; /* Initialize shared schedule information */ ksched_info_init(&ksched_shared_info); /* kthread (virtual processor) on the first logical processor */ k_ctx_main = (kthread_context_t *)MALLOCZ_SAFE(sizeof(kthread_context_t)); k_ctx_main->cpuid = 0; k_ctx_main->kthread_app_func = >thread_app_start; kthread_init(k_ctx_main); kthread_init_vtalrm_timeslice(40000ULL); kthread_install_sighandler(SIGVTALRM, k_ctx_main->kthread_sched_timer); kthread_install_sighandler(SIGUSR1, k_ctx_main->kthread_sched_relay); /* Num of logical processors (cpus/cores) */ num_cpus = (int)sysconf(_SC_NPROCESSORS_CONF); #if 0 fprintf(stderr, "Number of cores : %d\n", num_cores); #endif /* kthreads (virtual processors) on all other logical processors */ for(inx=1; inx<num_cpus; inx++) { k_ctx = (kthread_context_t *)MALLOCZ_SAFE(sizeof(kthread_context_t)); k_ctx->cpuid = inx; k_ctx->kthread_app_func = >thread_app_start; /* kthread_init called inside kthread_handler */ if(kthread_create(&k_tid, kthread_handler, (void *)k_ctx) < 0) { fprintf(stderr, "kthread creation failed (errno:%d)\n", errno ); exit(0); } printf( "kthread(%d) created !!\n", inx); } { /* yield till other kthreads initialize */ int init_done; yield_again: sched_yield(); init_done = 0; for(inx=0; inx<GT_MAX_KTHREADS; inx++) { /* XXX: We can avoid the last check (tmp to cur) by * temporarily marking cur as DONE. But chuck it !! */ if(kthread_cpu_map[inx]) init_done++; } assert(init_done <= num_cpus); if(init_done < num_cpus) goto yield_again; } #if 0 /* app-func is called for main in gthread_app_exit */ k_ctx_main->kthread_app_func(NULL); #endif return; }
void kernel_init(multiboot_info_t *mboot_info) { extern char __start_bss[], __stop_bss[]; memset(__start_bss, 0, __stop_bss - __start_bss); /* mboot_info is a physical address. while some arches currently have the * lower memory mapped, everyone should have it mapped at kernbase by now. * also, it might be in 'free' memory, so once we start dynamically using * memory, we may clobber it. */ multiboot_kaddr = (struct multiboot_info*)((physaddr_t)mboot_info + KERNBASE); extract_multiboot_cmdline(multiboot_kaddr); cons_init(); print_cpuinfo(); printk("Boot Command Line: '%s'\n", boot_cmdline); exception_table_init(); cache_init(); // Determine systems's cache properties pmem_init(multiboot_kaddr); kmem_cache_init(); // Sets up slab allocator kmalloc_init(); hashtable_init(); radix_init(); cache_color_alloc_init(); // Inits data structs colored_page_alloc_init(); // Allocates colors for agnostic processes acpiinit(); topology_init(); kthread_init(); /* might need to tweak when this happens */ vmr_init(); file_init(); page_check(); idt_init(); kernel_msg_init(); timer_init(); vfs_init(); devfs_init(); train_timing(); kb_buf_init(&cons_buf); arch_init(); block_init(); enable_irq(); run_linker_funcs(); /* reset/init devtab after linker funcs 3 and 4. these run NIC and medium * pre-inits, which need to happen before devether. */ devtabreset(); devtabinit(); #ifdef CONFIG_EXT2FS mount_fs(&ext2_fs_type, "/dev/ramdisk", "/mnt", 0); #endif /* CONFIG_EXT2FS */ #ifdef CONFIG_ETH_AUDIO eth_audio_init(); #endif /* CONFIG_ETH_AUDIO */ get_coreboot_info(&sysinfo); booting = 0; #ifdef CONFIG_RUN_INIT_SCRIPT if (run_init_script()) { printk("Configured to run init script, but no script specified!\n"); manager(); } #else manager(); #endif }