据我所知, initrd
充当块设备,因此需要一个文件系统驱动程序(如ext2
)。 内核必须具有至少一个内置模块,用于检测的文件系统initrd
。 在这篇文章中, 介绍的initramfs,初始RAM磁盘的一种新的模式 ,它是写的是:
但实际上的ramdisk由于缓存的浪费,甚至更多的内存。 Linux是设计来缓存所有文件和读取或写入目录条目块设备,因此Linux将数据复制到从RAMDISK到“页面缓存”(文件数据),和“目录项缓存”(对于目录项) 。 ramdisk的假装的缺点是嵌段装置它得到像块装置处理过的。
什么是page cache
和dentry cache
? 在该段,这是否意味着,因为得到的数据复制ramdisk
被视为块设备,因此,所有的数据被缓存?
在constrast, ramfs
:
几年前,Linus Torvalds的有一个不错的主意:如果有什么的Linux的缓存可以安装像一个文件系统? 只要保持在高速缓存中的文件,直到他们被删除或系统重启从来没有摆脱他们的? 莱纳斯编写了一个名为“RAMFS”缓存围在一个小包装,和其他内核开发人员创建了一个名为“tmpfs的”(这可以写入数据,因此它消耗之前填补了交换空间,并限制特定挂载点的大小改进版所有可用内存)。 initramfs的是tmpfs的实例。
这些基于RAM的文件系统会自动扩大或缩小以适合它们所包含的数据的大小。 将文件添加到RAMFS(或扩展现有文件)自动分配更多的内存,和删除或截断文件释放该存储器。 有块设备和高速缓存之间没有重复,因为没有块设备。 在缓存中的副本是数据的唯一副本。 最重要的是,这不是新的代码,但对于现有的Linux缓存代码,这意味着它增加了几乎没有大小,非常简单,而且是基于非常行之有效的基础设施的新应用程序。
总之, ramfs
只是文件打开并加载到内存中,不是吗?
两者initrd
和ramfs
在编译时拉链,但不同的是, initrd
是解压到通过在启动内核被安装在块设备,而ramfs
经由的cpio解压到存储器中。 我对么? 或者是ramfs
一个很小的文件系统?
最后,直到这一天, initrd
图像仍然在最新的内核中呈现。 但是,是initrd
实际上ramfs
今天使用和名字只是由于历史的目的是什么?
目录项(和inode)高速缓存
在Linux文件系统的子系统有三层。 该VFS(虚拟文件系统),它实现了系统调用接口和处理交叉挂载点和默认权限和限制检查。 它下面是文件系统个别司机和那些反过来接口为块设备驱动程序(磁盘,存储卡,等等;网络接口除外)。
VFS和文件系统之间的接口是几类(这是显而易见C,所以含函数指针和这样的结构,但它是面向对象的接口概念上)。 三个主要类别是inode
,其描述了在一个文件系统中,任何对象(文件或目录) dentry
,它描述了在目录条目和file
,其描述了通过一种方法文件打开。 在安装时,文件系统驱动程序创建inode
和dentry
为它的根和其他的人都当进程要访问一个文件,并最终过期按需创建。 这是一个目录项和inode缓存。
是的,它意味着对于每个打开的文件,并到根目录下的任何必须有inode
和dentry
代表它的内核内存分配的结构。
页面缓存
在Linux中,包含用户级数据的每个存储器页由统一表示page
结构。 这可能标志着该页面是匿名的(可能会被交换如果可用交换空间)或与之相关联inode
的一些文件系统(可能会写回,并从文件系统重新读取),它可以是任意数量的存储器的一部分地图,即在某个进程的地址空间可见。 当前加载到内存中的所有页面的总和是页面缓存。
该页面用于实现mmap接口,并同时要定期的读写系统调用可以通过其他方式在文件系统中实现,大部分的接口使用也使用页面通用功能。 有通用的功能,即当被请求的文件读取分配页,并调用文件系统,以填补他们,一个接一个。 对于基于块的设备文件系统,它只是计算相应的地址和代表该填充块设备驱动程序。
兰德福(RAMDISK)
兰德福是规则的块设备。 这允许分层在它上面的任何文件系统,但它是由块设备的界面的限制。 而刚刚方法,以填补在主叫者分配一个页面,并将其写回。 这正是需要什么样盘,存储卡,USB大容量存储和这种真实的块设备,但RAMDISK这意味着,存在于内存中的数据进行两次,一次是在兰德福的记忆,一旦由分配的内存呼叫者。
这是实施的老办法initrd
。 从时候的initrd是稀有奇特occurence。
TMPFS
Tmpfs的是不同的。 这是一个虚拟的文件系统。 它提供了VFS的方法是绝对的最低限度,使其工作(因为这样它的索引节点,目录项和文件的方法应该做的出色的文档)。 如果有相应的inode和目录项的inode缓存,在文件被创建和永不过期,除非该文件被删除时创建的文件只存在。 当数据被写入否则表现为匿名者的页面相关联的文件(数据可存储交换, page
结构,只要文件存在继续使用)。
这意味着有数据没有额外的拷贝在内存中,整个事情是一个非常简单并且由于是稍快了。 它只是使用的数据结构,充当缓存的任何其他文件系统,因为它的主要存储。
这是实施的新的方式initrd
( initramfs
,但图像仍称只是initrd
)。
它,也可以实现“POSIX共享存储器”的方式(这只是意味着tmpfs的被安装在/dev/shm
和应用程序可以随意那里创建文件和的mmap它们;简单且有效的)和最近甚至/tmp
和/run
(或/var/run
)通常具有的tmpfs安装尤其是在笔记本电脑,以保持磁盘由具有旋转起来或避免SSD的情况下,一些磨损。
我认为你是对所有。
所不同的是很容易看到,如果你遵循启动时所需的步骤:
initrd
- 甲
ramdev
块设备被创建。 它是一种基于RAM的块的装置,其是使用存储器而不是物理磁盘的模拟硬盘。 - 在
initrd
文件读取并解压缩到设备,因为如果你没有zcat initrd | dd of=/dev/ram0
zcat initrd | dd of=/dev/ram0
或类似的东西。 - 该
initrd
中包含文件系统的图像,所以现在你可以挂载文件系统和往常一样: mount /dev/ram0 /root
。 当然,文件系统需要驱动程序,所以如果你使用的ext2,ext2的司机已被在内核编译。 - 完成!
initramfs
- 甲
tmpfs
被安装: mount -t tmpfs nodev /root
。 该tmpfs的不需要驱动程序,它始终是在内核。 没有设备需要,没有额外的驱动程序。 - 该
initramfs
是直接解压缩到这个新的文件系统: zcat initramfs | cpio -i
zcat initramfs | cpio -i
或类似。 - 完成!
是的,它仍然是所谓initrd
在许多地方,虽然它是一个initramfs
,特别是在引导装载程序,因为对他们来说仅仅是一个BLOB。 所不同的是由操作系统在引导时作出。
要添加之间的另一个显着的区别initrd
和initramfs
上述优异的答案没有提及。
- 随着
initrd
内核默认移交到用户空间的pid 1
在/sbin/init
- 但是较新的initramfs变化的东西并执行
pid 1
在/init
因为它可能成为一个陷阱(见https://unix.stackexchange.com/a/147688/24394 )
最小的可运行QEMU的例子和新手解释
在这个答案,我将:
- 提供一个最小的可运行Buildroot里面+ QEMU例如你要测试的东西出来
- 解释这两个之间最根本的区别对于初学者非常谁都有可能使用Google这个
希望这些将作为一个基础来验证和理解上的差异的更具体的内部细节。
最小设置是在这里完全自动化的 ,这也是入门相应 。
因为它们运行,并且在回购解释设置打印出QEMU命令,我们可以很容易产生以下三种类型的工作靴:
根文件系统是一个ext2“硬盘”:
qemu-system-x86_64 -kernel normal/bzImage -drive file=rootfs.ext2
根文件系统是在initrd中:
qemu-system-x86_64 -kernel normal/bzImage -initrd rootfs.cpio
-drive
没有给出。
rootfs.cpio
包含相同的文件作为rootfs.ext2
,除了他们是在CPIO格式,这是类似.tar
:它系列化目录,而对其进行压缩。
根文件系统是在initramfs中:
qemu-system-x86_64 -kernel with_initramfs/bzImage
无论-drive
也不-initrd
中给出。
with_initramfs/bzImage
与选项相同编译内核normal/bzImage
,除了一个: CONFIG_INITRAMFS_SOURCE=rootfs.cpio
指向完全相同的CPIO从-initrd
例子。
通过比较的设置,我们可以得出每个最根本的属性:
在硬盘安装,QEMU的bzImage加载到内存中。
这项工作通常是由引导程序/固件进行实时硬件做的,例如GRUB 。
Linux内核启动,然后用它的驱动程序从磁盘读取根文件系统。
在initrd设置,QEMU做一些进一步的引导程序的工作,除了装载内核到内存:还吧:
- 加载
rootfs.cpio
到内存 - 通知关于它的内核: https://unix.stackexchange.com/questions/89923/how-does-linux-load-the-initrd-image
那么这个时候,内核只使用rootfs.cpio
直接从内存,因为没有硬盘存在。
写入不在重新启动后持久的,因为一切都在内存
initramfs中的设置,我们所建立的内核有点不同:我们也给rootfs.cpio
内核构建系统。
然后内核编译系统知道如何坚持内核映像和CPIO汇集成一个单一的形象。
因此,我们需要做的是bzImage的传递到QEMU。 QEMU加载到图像,就像它没有为其他设置,但没有别的要求:在CPIO也被加载到内存中,因为它被粘在内核映像!