我想用 initramfs 启动一个系统,它是实际的最终文件系统,而不是用于加载驱动程序的临时 initramfs。不幸的是,Linux 在使用 initramfs 时强加了不同的(在我的例子中,是不受欢迎的)行为,至少包括以下差异:
- devtmpfs 不是自动安装的,至少一开始不是,但似乎会在稍后的某个时候自动安装,但我无法弄清楚。
- 内核尝试调用
/sbin/init
.init=
/init
我知道可以通过在 initramfs 上放置一些额外的垃圾来解决这些问题,但我宁愿它表现得像一个普通的 root fs。有什么办法可以实现这一点吗?
如果我确实需要使用 initramfs 中的用户空间脚本来解决这个问题,我至少想了解是什么触发了 devtmpfs 的自动挂载。
答案1
CONFIG_BLOCK
如果未定义,这是可以实现的,因为init/do_mounts.c
包含 in mount_root
,它在内核无法/init
在 initramfs 上执行后运行,如下所示:
#ifdef CONFIG_BLOCK
{
int err = create_dev("/dev/root", ROOT_DEV);
if (err < 0)
pr_emerg("Failed to create /dev/root: %d\n", err);
mount_block_root("/dev/root", root_mountflags);
}
#endif
在这种情况下,mount_root
无需执行任何操作即可成功,并且内核继续将 initramfs 视为适当的根文件系统。
不幸的是,关闭CONFIG_BLOCK
对于大多数用途来说并不实用。让我相信这应该有效的是,在我正在使用的特定开发板的补丁上,条件被替换为:
#if defined(CONFIG_BLOCK) && !defined(CONFIG_INITRAMFS_SOURCE)
最好添加对root=initramfs
导致mount_root
返回而不执行任何操作的支持,这应该是一个简单的单行补丁。不过,我不知道上游是否可以接受。
答案2
好吧,这已经很晚了,但我有一个可能对你有帮助的答案:
首先,您需要将 /dev/console 包含在 initramfs 中。这将允许您将 sysinit 功能报告回控制台(来自用户空间的打印将再次显示在您的主显示屏上)。接下来,如果您使用 busybox 作为 init 进程,请在 RFS 根目录中添加一个指向 busybox 的符号链接(名为 init)。问题在于 Linux 内核文件系统层几年前发生了变化。最初,您必须使用 /init 来启动系统。这被认为是一个安全漏洞,并被重新定位到 /sbin/init。后来,IIRC,它变成了 linuxrc,但我相信它现在已经被一起删除了。
在我的 inittab 中,前两行是 mount proc 和 mount devtmpfs。一切似乎都工作正常。