term_t bif_run_slice2(term_t Pid, term_t Reductions, process_t *ctx) { process_t *proc; term_t retval, retval1; term_t res; if (!is_pid(Pid) || !is_int(Reductions)) return A_BADARG; proc = proc_lookup(pid_serial(Pid)); res = proc_main(proc, int_value2(Reductions), &retval); if (res == AI_DONE) { //proc_destroy(proc); //- process should not be destroyed now //- as we may need to notify links first retval1 = marshal_term(retval, proc_gc_pool(ctx)); result(make_tuple2(AI_DONE, retval1, proc_gc_pool(ctx))); } else { if (res == AI_YIELD) result(res); else { retval1 = marshal_term(retval, proc_gc_pool(ctx)); result(make_tuple2(res, retval1, proc_gc_pool(ctx))); } } return AI_OK; }
static void spawn_init_start(int8_t *cmd_line) { proc_t *init_proc = proc_make(noval); // group leader set later assert(init_proc != 0); init_proc->cap.regs[0] = parse_cmd_line(&init_proc->hp, cmd_line); assert(init_proc->cap.regs[0] != noval); init_proc->cap.live = 1; init_proc->init_call_mod = A_INIT; init_proc->init_call_func = A_BOOT; init_proc->init_call_arity = 1; export_t *exp = code_base_lookup(A_INIT, A_BOOT, 1); assert(exp != 0); init_proc->cap.ip = exp->entry; module_info_t *mi = code_base_module_by_name(A_INIT, 0); assert(mi != 0); init_proc->cap.cp = mi->code_starts + mi->code_size-1; scheduler_enlist0(init_proc); // pid assigned init_proc->group_leader = init_proc->pid; // init is its own leader proc_main(init_proc); /* UNREACHANBLE */ }
apr_status_t teeterl_exec(const char *m, const char *f, const char *as[]) { process_t *proc; term_t result, retval; term_t args = nil; term_t args1; // [args] term_t cons = nil; lst_add(args, cons, ztol(m, g_xpool), g_xpool); lst_add(args, cons, ztol(f, g_xpool), g_xpool); if (as != 0) { const char **p = as; while (*p) lst_add(args, cons, ztol(*p++, g_xpool), g_xpool); } args1 = make_list(args, g_xpool); proc = proc_spawn(g_base, g_atoms, A_INIT, A_RUN, args1); if (proc == 0) { printf("Unable to spawn init:run()\n"); return APR_ENOPROC; } do { result = proc_main(proc, 1000000, &retval); } while (result == AI_YIELD); if (result == A_ERROR) { proc_print_error(proc, retval); return APR_ENOPROC; } else if (result == A_THROW) { printf("*** not caught: %s\n", stringify_term(retval, g_atoms, g_mempool)); return APR_ENOPROC; } else if (result == A_EXIT) { printf("*** exited: %s\n", stringify_term(retval, g_atoms, g_mempool)); return APR_ENOPROC; } else if (result == AI_DONE) { //normal exit, do nothing } else { proc_print_init_exits_unexpectedly(proc, result, retval); return APR_ENOPROC; } return APR_SUCCESS; }
// 从汇编阶段,进入C语言的阶段,传承了Unix的典型思想 // 汇编只负责引导和必要的硬件打交道的阶段 void start_ling(start_info_t *si) { //-------- init phase 1 -------- // //start_info包含的是xen的初始化信息 //是xen在启动GuestOS的时候,放在特定的地方 memcpy(&start_info, si, sizeof(*si)); phys_to_machine_mapping = (unsigned long *)start_info.mfn_list; HYPERVISOR_update_va_mapping((unsigned long)&shared_info, __pte(start_info.shared_info | 7), UVMF_INVLPG); HYPERVISOR_shared_info = &shared_info; //进行时钟初始化 time_init(); // sets start_of_day_wall_clock // use the time value to seed PRNG mt_seed(start_of_day_wall_clock); #if defined(__x86_64__) HYPERVISOR_set_callbacks(0, 0, 0); #else /* __x86_64__ */ HYPERVISOR_set_callbacks(0, 0, 0, 0); #endif mm_init(start_info.nr_pages, start_info.pt_base, start_info.nr_pt_frames); nalloc_init(); events_init(); grants_init(); console_init(mfn_to_virt(start_info.console.domU.mfn), start_info.console.domU.evtchn); xenstore_init(mfn_to_virt(start_info.store_mfn), start_info.store_evtchn); xenstore_read("name", my_domain_name, sizeof(my_domain_name)); //print_xenstore_values(); if (disk_vbd_is_present()) disk_init(); lwip_init(); netfe_init(); //-------- init phase 2 -------- // if (nalloc_no_memory()) fatal_error("init phase 2: no memory"); sys_stats_init(); atoms_init(); embed_init(); code_base_init(); scheduler_init(); ets_init(); pcre_init(); counters_init(); //print_start_info(); //print_xenmem_info(); //run_alloc_tests(); //run_mm_tests(); //print_xenstore_values(); //run_bignum_tests(); //printk("\r\nLing %s is here\r\n", quote_and_expand(LING_VER)); proc_main(0); // preliminary run spawn_init_start(start_info.cmd_line); //while (1) // HYPERVISOR_sched_op(SCHEDOP_block, 0); /* UNREACHABLE */ }