内核启动流程2-C语言部分的最后一个函数init_post()
最后分析最终调用用户空间init进程的函数init_post().
static noinline int init_post(void)这是一个非_init函数。强制让它为非内联函数,以防gcc让它内联到init()中成为init.text段的一部分。
async_synchronize_full();
free_initmem();
这两行用于释放所有init.*段所占用内存。
unlock_kernel();
释放大内核锁,使该线程可以在其他处理器上运行。
mark_rodata_ro();
通过修改页表,保证只读数据段为只读属性。对ARM架构而言是空操作。
system_state=SYSTEM_RUNNING;
设置系统状态为运行状态。
numa_default_policy();
设定NUMA系统的内存访问策略为默认。对于2440/6410,是空操作。
if(sys_open((const char __user *) “/dev/console”,O_RDWR,0)<0)
printk(KERN_WARNING "Warning;unable to open an initial console.\n");
这是kernel_init打开的第一个文件,也是该进程的标准输入。这里需要打开"/dev/console",如果没有这个节点,系统就出错。可能的原因是:
1)制作文件系统时,忘记 创建/dev/console节点。
2)文件系统挂载问题,挂载上的文件系统不是什么都没有,就是挂载错了节点。
(void) sys_dup(0);
(void) sys_dup(0);
复制两次标准输入(0)的文件描述符(它是上面打开的"/dev/console",即系统控制台):
一个作为标准输出(1),另一个作为标准出错(2)。现在标准输入、标准输出、标准出错都是"/dev/console"了。
该console在内核启动参数中可以配置为某个串口(ttySACn、ttySn等等),也可以是虚拟控制台(tty0)。因此在串口或者显示器上看到之后的系统登录提示。
current->signal->flags |=SIGNAL_UNKILLABLE;
设置当前进程(init)为不可以杀进程(忽略致命的信号)
if(ramdisk_execute_command)
{
run_init_process(ramdisk_execute_command);
printk(KERN_WARNING "Failed to execute %s\n",ramdisk_execute_command);
}
如果指定了ramdisk_execute_command,则执行它表示的内存磁盘的用户空间init进程。
if(execute_command)
{
run_init_process(execute_command);
printk(KERN_WARNING "Failed to execute %s. attempting" "default...\n",execute_command);
}
execute_command在init_setup()函数中被初始化,而后者会将命令行参数中"init="的参数值赋值给execute_command,因此,如果在命令行参数中设置了"init"参数,则执行该参数指定用户空间init进程。
run_init_process("/sbin/init");
run_init_process("/etc/init");
run_init_process("/bin/init");
run_init_process("/bin/sh");
panic("No init found.Try passing init=option to kernel.");
最后代码表示:在检查完ramdisk_execute_command和execute_command为空的情况下,顺序执行上述初始化程序,如果没有找到,就打印错误信息,并挂起内核。出现这个内核挂起错误的原因:
1)启动参数配置有问题,通过命令行参数指定的init程序系统没有找到,且默认的那4个程序也不在文件系统里。
2)文件系统挂载有问题,文件不存在。
3)init程序没有执行权限。
至此,内核的初始化结束,系统正式进入用户空间的init进程。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· 提示词工程——AI应用必不可少的技术
· .NET周刊【3月第1期 2025-03-02】