解释 “No working init found.” 启动挂起信息

作者:

Andreas Mohr <andi at lisas period de> Cristian Souza <cristianmsbr at gmail period com>

本文档提供了一些导致加载 init 二进制文件失败的高级原因(大致按照执行顺序排列)。

  1. 无法挂载根文件系统:设置 “debug” 内核参数(在启动加载程序配置文件或 CONFIG_CMDLINE 中)以获取更详细的内核消息。

  2. init 二进制文件在根文件系统中不存在:确保您具有正确的根文件系统类型(并且 root= 内核参数指向正确的分区),所需的驱动程序(例如存储硬件(例如 SCSI 或 USB!)和文件系统(ext3、jffs2 等))已内置(或者作为模块,由 initrd 预加载)。

  3. 控制台设备损坏:可能 console= setup 中存在冲突 --> 初始控制台不可用。例如,由于串行 IRQ 问题(例如缺少基于中断的配置),某些串行控制台不可靠。尝试使用不同的 console= device 或例如 netconsole=

  4. 二进制文件存在但依赖项不可用:例如,init 二进制文件所需的库依赖项(例如 /lib/ld-linux.so.2)丢失或损坏。使用 readelf -d <INIT>|grep NEEDED 查找需要哪些库。

  5. 二进制文件无法加载:确保二进制文件的架构与您的硬件匹配。例如,i386 与 x86_64 不匹配,或者尝试在 ARM 硬件上加载 x86。如果您尝试在此处加载非二进制文件(shell 脚本?),则应确保脚本在其 shebang 标头行 (#!/...) 中指定一个完全正常工作的解释器(包括其库依赖项)。在处理脚本之前,最好先测试一个简单的非脚本二进制文件,例如 /bin/sh 并确认其成功执行。要了解更多信息,请将代码添加到 init/main.c 以显示 kernel_execve() 的返回值。

每当您发现新的失败原因时,请扩展此说明(毕竟加载 init 二进制文件是一个关键且困难的过渡步骤,需要尽可能地使其轻松),然后向 LKML 提交补丁。进一步的 TODO

  • 通过一个 struct 数组来实现各种 run_init_process() 调用,该数组可以存储 kernel_execve() 结果值,并在失败时通过迭代所有结果来记录所有内容(非常重要的可用性修复)。

  • 尝试使实现本身更具帮助性,例如,通过在受影响的位置提供额外的错误消息。