创建用户进程
- 先fork一个进程
- 再用exec偷梁换柱
具体exec过程:
- 调用系统调用(触发软中断),传入进程名等参数(包括进程名长度、用户进程程序存放地址、用户进程程序长度)
- 在系统调用中:
- 检查当前进程是否为用户进程(通过检查mm是否等于null,如何是内核进程,则mm==null)
- 如果是用户进程,则将mm的引用次数-1(因为创建完新用户进程之后,当前进程就被新的用户进程取代了。
- 如果引用次数-1之后刚好=0,说明这块内存区域没有别的进程在用,可以直接释放
- 进行内存释放
- 如果是内核进程,不做操作,因为mm此时为Null.
- 调用load_icode来读入用户进程的程序。(因为此时系统没有文件系统,所有用户进程是通过链接文件,放在整个系统的elf文件中的)
- load_icode中:
- 建立一个新的内存管理器mm
- 建立新页表
- 分配内存空间,复制进程的程序段(TEXT)和数据段(DATA)到新空间
- 分配BSS段空间,并初始化为0
- BSS段用于存放全局变量等,因为初始化为0,所以全局变量如果没有初值,就是0
- 建立用户进程的栈空间
- 切换页表到用户页表中(新页表)
- 设置trapframe的各项值,用于切换到用户进程(注意,此时还没切换到用户进程)
- 真正切换到用户进程的方式与内核进程的切换是一样的,见上一篇文章。