struct ko_process *kp_run_user(struct ko_exe *ke, char *cmdline) { struct ko_process *kp = NULL; struct kt_thread_creating_context ctx = {0}; /* Create process for it */ kp = kp_create(KP_USER, "初始化进程"); if (!kp) goto err; if (kp_exe_bind(kp, ke) == NULL) goto err; ke_handle_init(kp); /* And the first thread (entry is absolute address) */ ctx.thread_entry = ke->entry; ctx.fate_entry = ke->entry/* special first thread */; ctx.flags = KT_CREATE_RUN | KT_CREATE_STACK_AS_PARA; ctx.para = (unsigned long)cmdline; if (kt_create(kp, &ctx) == NULL) goto err; return kp; err: if (ke) { //TODO free it } if (kp) { //TODO free it } return NULL; }
struct ko_thread *kt_create_kernel(void *entry, unsigned long para) { struct kt_thread_creating_context ctx = {0}; ctx.para = para; ctx.thread_entry = entry; ctx.flags = KT_CREATE_RUN; return kt_create(kp_get_system(), &ctx); }
struct ko_thread *kt_create_driver_thread(void *ring0_stack, int stack_size, void *entry, unsigned long para) { struct kt_thread_creating_context ctx = {0}; ctx.thread_entry = entry; ctx.stack0 = ring0_stack; ctx.stack0_size = stack_size; ctx.para = para; return kt_create(kp_get_system(), &ctx); }
/** @brief Create a new user thread */ static ke_handle thread_create(struct sysreq_thread_create *req) { ke_handle h; struct ko_thread *t; struct kt_thread_creating_context ctx = {0}; ctx.thread_entry = req->entry; ctx.fate_entry = req->wrapper; ctx.para = req->para; ctx.flags = req->run?KT_CREATE_RUN:0; if ((t = kt_create(KP_CURRENT(), &ctx)) == NULL) goto err; if (KE_INVALID_HANDLE == (h = ke_handle_create((void*)t))) goto err; return h; err: if (t) { //TODO: } return KE_INVALID_HANDLE; }
/** @brief run startup process */ void ke_run_first_user_process(void *data, int size, char *cmdline) { char *first_space, first_exe_name[128] = {0}; struct ko_section *ks; void *entry_address; struct ko_exe *kee, *ke_tmp = kp_exe_create_temp(); first_space = strchr(cmdline, ' '); if (!first_space) goto err; if (first_space - cmdline >= sizeof(first_exe_name) - sizeof(xchar)) goto err; strncpy(first_exe_name, cmdline, first_space - cmdline); /* Kernel file process, because early we cannot copy lv2 table of driver */ kernel_file_process = kp_create(KP_CPL0_FAKE, "操作系统文件进程"); if (!kernel_file_process) goto err; printk("启动用户第一个可执行文件%x, size %d.\n", data, size); if (size == 0/*no file*/ || size == 1/*buffer error*/) goto err; if (elf_analyze(data, size, &entry_address, KO_EXE_TO_PRIVATE(ke_tmp)) == false) goto err; ks = ks_create(kp_get_file_process(), KS_TYPE_PRIVATE, 0, size, KM_PROT_READ|KM_PROT_WRITE); if (!ks) goto err; kee = kp_exe_create_from_file(first_exe_name, ks, KO_EXE_TO_PRIVATE(ke_tmp), entry_address); if (!kee) goto err; /* But this is a special one, we have to fill the data on it */ do { struct kt_thread_creating_context ctx = {0}; struct file_process_startup_para package; package.ks_start = ks->node.start; package.size = size; package.data = data; ctx.thread_entry = file_thread; ctx.flags = KT_CREATE_RUN; ctx.para = (unsigned long)&package; if (kt_create(kernel_file_process, &ctx) == NULL) goto err; /* Wait it to finish */ while (package.data) kt_schedule(); } while(0); /* OK, create the process */ if (kp_run_user(kee, ++first_space/*Real application*/) == false) goto err; return; err: printk("启动第一可执行文件失败。\n"); }