1. 1号进程的内核态
1号进程首先运行在内核态,其函数是kernel_init,这里简单介绍一下其工作:
- 非bootcpu相关初始化
- 页分配器初始化的收尾工作
- 驱动子系统和设备树初始化
- 调用
__initcall
指定的初始化函数 - 挂载根文件系统
- 是否
__init
指定的内存 - 执行用户态init程序
2. 1号进程内核态到用户态的切换
kernel_init最后通过kernel_execve函数执行用户程序,完成内核态到用户态的切换。
这里以elf格式的init程序为例简单说明一下kernel_execve的工作流程:kernel_execve会申请新的mm_struct,记录init程序的代码段和数据段,将当前进程内核栈中记录的pc改为elf的入口地址,并将内核栈中记录的pstate改为EL0,并将内核栈记录的sp指向用户栈。在从内核态函数返回时,从栈中恢复pstate、pc、sp,实现内核态到用户态的转换,并跳转init程序的入口。