首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >linux如何知道rootfs在哪里?

linux如何知道rootfs在哪里?
EN

Unix & Linux用户
提问于 2018-11-02 14:58:00
回答 1查看 14.2K关注 0票数 7

我试图了解linux内核是如何知道所需的rootfs在引导位置的。

我看了这份文件:

https://www.kernel.org/doc/Documentation/filesystems/ramfs-rootfs-initramfs.txt

有一部分人感兴趣地说:

所有2.6 Linux内核都包含一个gzipped格式的"cpio“格式存档,当内核启动时,它将被解压到rootfs中.如果rootfs在提取嵌入式cpio归档文件后不包含init程序,内核将切换到旧代码来定位和挂载根分区。

我们的内核是4.X,但我猜这仍然适用吗?这听起来好像所有内核都有一个嵌入的"cpio“rootfs。

事实上,正如我们所读到的那样:

2.6内核构建过程总是创建一个cpio格式的initramfs存档,并将其链接到生成的内核二进制文件中。默认情况下,这个档案是空的.配置选项CONFIG_INITRAMFS_SOURCE ..。可用于指定initramfs存档的源。

这就引出了更多的问题:

  1. 因此,如果我希望我的rootfs在内存中,我需要将CONFIG_INITRAMFS_SOURCE设置为指向我的rootfs (大概是cpio格式)。

但这不意味着我的内核和rootfs现在是不可分割的吗?如果我想在不进行重建的情况下对RootFS做一个小小的调整,该怎么办?如果我希望将我的rootfs存储在与内核分开的地方怎么办?如何告诉内核我的rootfs的位置?

  1. 此外,如果我希望我的rootfs在物理存储中(如eMMC、闪存等),该怎么办?而不是在内存里?

它早些时候说:

如果rootfs在提取嵌入式cpio归档文件后不包含init程序,内核将切换到旧代码来定位和挂载根分区。

但是..。多么?它怎么知道在哪里找到根呢?如果是在eMMC上,我需要以某种方式告诉内核,对吗?

我使用的引导加载程序是U引导。我检查了U环境变量,看看它是否以引导arg的形式将rootfs位置传递给内核,但情况似乎并非如此.

编辑:

正如注释中指出的,rootfs的位置通过引导arg传递给内核。在我的例子中,u引导将root=/dev/mmcblk0p4 rw作为引导arg传递给内核。因此,这就回答了我的一个问题--您可以将这个位置作为引导arg传递给任何解压缩的rootfs。

我仍然不清楚如何从内核中分离出一些rootfs.tar.gz,如何告诉内核将其解压缩到内存中,并将其用作rootfs。也许这是不可能的,我只需要使用CONFIG_INITRAMFS_SOURCE?无论如何,我会阅读4.X文档。

EN

回答 1

Unix & Linux用户

发布于 2018-11-02 20:11:53

首先,不要害怕内核文档中对"2.6“的引用。目前的内核仍然是"2.6“系列的成员,但它们只是为了”营销目的“而进行了两轮重命名(因此2.6.40变成3.0,然后3.20变成4.0)。您的4.19内核通常被标记为2.6.79。

看上去这里对"rootfs“的含义有一些混淆。"rootfs“是内核内部使用的一种特殊的基于RAM的文件系统。它与"tmpfs“文件系统完全相同,这些文件系统通常被挂载到/run/dev/shm或有时/tmp之类的地方。(嗯,除非没有将"tmpfs“特性编译到内核中,否则将使用一个被剥离的称为"ramfs”的"tmpfs“。)这些文件系统只存在于页面缓存中,对于ramfs根本没有备份设备,而tmpfs如果可用,则由交换来支持。

因此,内核不需要担心“查找”"rootfs",但它需要以某种方式填充它,因为引导时整个页面缓存都是空的。这就是"initramfs文件“发挥作用的地方。这只是一个(压缩的) cpio存档(由于文档中提到的原因而不是tar ),内核将其解压缩到空的"rootfs“中。这个存档可以通过在构建过程中设置CONFIG_INITRAMFS_SOURCE直接嵌入到内核映像中,或者由引导加载程序提供( GRUB中的initrd选项就是这样做的)。这个归档文件通常是使用用户空间工具创建的,比如dracut或(令人困惑的) mkinitrd

如果cpio映像不可用或不包含可执行的/init,则内核返回到另一种方法,在该方法中查看root=命令行参数,将其解释为实际根文件系统的位置,将其挂载到/并直接执行init。但是,现在很少使用它,因为它需要直接编译到内核中的所有必要的存储和文件系统驱动程序。在大多数系统中,root=参数不是内核使用的,而是由initramfs中的/init处理的。/init (通常是systemd或shell脚本)负责加载所需的模块、挂载真正的根文件系统并切换到它。

很久以前,一种叫做"initrd“的不同机制取代了现代的"initramfs”。"initrd“(”initrd“)是一个基于RAM的块设备,它由一个真正的文件系统(如ext2)初始化,其映像就像现代的cpio归档文件一样。这就是为什么许多地方仍然使用"initrd“的名称来指这些早期启动的东西。

票数 9
EN
页面原文内容由Unix & Linux提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://unix.stackexchange.com/questions/479415

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档