创建并执行用户进程
我们在proc_init()函数里初始化进程的时候, 认为启动时运行的ucore程序, 是一个内核进程("第0个"内核进程), 并将其初始化为idleproc进程。然后我们新建了一个内核进程执行init_main()函数。
我们比较lab4和lab5的init_main()有何不同。
// kern/process/proc.c (lab4)
static int init_main(void *arg) {
cprintf("this initproc, pid = %d, name = \"%s\"\n", current->pid, get_proc_name(current));
cprintf("To U: \"%s\".\n", (const char *)arg);
cprintf("To U: \"en.., Bye, Bye. :)\"\n");
return 0;
}
// kern/process/proc.c (lab5)
static int init_main(void *arg) {
size_t nr_free_pages_store = nr_free_pages();
size_t kernel_allocated_store = kallocated();
int pid = kernel_thread(user_main, NULL, 0);
if (pid <= 0) {
panic("create user_main failed.\n");
}
while (do_wait(0, NULL) == 0) {
schedule();
}
cprintf("all user-mode processes have quit.\n");
assert(initproc->cptr == NULL && initproc->yptr == NULL && initproc->optr == NULL);
assert(nr_process == 2);
assert(list_next(&proc_list) == &(initproc->list_link));
assert(list_prev(&proc_list) == &(initproc->list_link));
cprintf("init check memory pass.\n");
return 0;
}注意到,lab5新建了一个内核进程,执行函数user_main(),这个内核进程里我们将要开始执行用户进程。
do_wait(0, NULL)等待子进程退出,也就是等待user_main()退出。
我们来看user_main()和do_wait()里做了什么
于是,我们在user_main()所做的,就是执行了
这么一个函数。
如果你熟悉execve()函数,或许已经猜到这里我们做了什么。
实际上,就是加载了存储在这个位置的程序exit并在user_main这个进程里开始执行。这时user_main就从内核进程变成了用户进程。我们在下一节介绍kern_execve()的实现。
我们在user目录下存储了一些用户程序,在编译的时候放到生成的镜像里。
最后更新于
这有帮助吗?