ramfs,rootfs,initramfs

云计算分享者 2024-02-23 03:32:32
什么是ramfs?ramfs是一个很简单的文件系统,其将Linux的磁盘缓存能力(page cache和dentry cache)做成了一个可以自动伸缩大小的基于ram的文件系统. Linux中所有的文件都会在内存中cache. 从磁盘上读出来的内容会一直被保存在内存中,这样在需要时候可以马上被使用,当然,这些内容会被标记为clean的,这样当vm系统需要内存的时候,这些内存可以被释放. 同理,写入文件的内容在真正写入到磁盘之后也会被标记为clean的. 对于dentry,dentry cache也有相同的效果,这样能极大加速对目录的访问. 对于ramfs,没有磁盘,所有操作都在内存中. 文件写入ramfs的时候,dentry cache和page cache的分配和使用和一般的文件系统是相同的,但是因为没有真正的磁盘可以写入. 所以这些page总是被标记为dirty的,那么在VM子系统扫描clean page进行回收的时候,这些page就不会被回收. 由于ramfs需要的大量基础代码都已经在linux cache部分了,所以实现ramfs需要的代码是很少的.所以,ramfs不是linux kernel的一个可选的功能(不能通过menuconfig来选择是否编译),因为这部分代码量很少. ramfs和ramdisk以前有一个"ram disk"(/dev/ram*),它会使用一块内存来作为文件系统的backing store(写入数据的部分),也就是磁盘.这个block device是固定大小的. 这个block device是固定大小的,所以上面的文件系统也是固定大小的. 使用ram disk也需要在fake block device(内存)和page cache, dentry cache(另一块内存)之间进行数据复制. 而且需要对这块内存mkfs进行文件系统初始化. 对比ramfs, ram disk对应cpu和内存都有很大的浪费.ram disk是不需要的,ramfs就够了. ram disk现在不使用了还有一个原因.随着loopback device的引入,我们可以使用一个文件来作为一个block device,然后在mount的时候加上-o loop就可以了. ramfs和tmpfsramfs有一个缺点,可以不断向里面写入数据,直到把内存写满. 从ramfs演变出了一种tmpfs,其在ramfs的基础上添加了可以使用的内存限制,而且可以将数据swap到交换分区. rootfsrootfs是一种特殊的ramfs(当tmpfs可用的时候,为tmpfs),在linux kernel中总是存在.rootfs不能被卸载.大部分的情况下我们都是对rootfs overmount一个新的文件系统,然后将rootfs里面的内容清空,一个不包含任何内容的ramfs(tmpfs)只占用很少的空间(这个就是启动过程中的switch-root). 如果CONFIG_TMPFS配置了,那么rootfs使用tmpfs,不然使用ramfs.当然可以直接加`rootfstype=ramfs`来强制使用ramfs. initramfslinux kernel现在会使用一个cpio+gzip的img文件,在启动的时候这个文件的内容被解压到rootfs中.然后kernel检查里面是不是有一个/init文件,如果有的话,那么启动为pid 1.这个文件要做的最重要的事情就是加载各种启动,然后将真正的root device挂载起来. 如果没有/init,那么kernel就会进入到老的代码,自己去寻找根分区进行挂载,然后执行/sbin/init. 这个过程和老版本的initrd有如下区别: initrd总是一个单独的文件,而initramfs和Linux kernel总是相关的initrd是一个gzip压缩的filesystem image(一般是ext2文件系统)所以需要kernel里面有相应的文件系统驱动.而initramfs的img文件是一个cpio+gzip的一般文件,内核里面这部分代码会简单很多.在initrd里面运行的代码(是/initrd而不是/init)会执行一些初始化的事情然后返回到kernel.而initramfs里面的/init不需要返回内核,其一般都overmount一下/,然后使用switch root到新的/跑新的init进程.当需要切换到新的root device,initrd需要使用pivot_root,然后umount初始的ramdisk.initramfs是一个rootfs,不能pivot_root它,也不能umount它. 在initramfs中,是将rootfs里面的所有东西删除了以释放占用的内存空间(find -xdev / -exec rm '{}' ';'),然后将rootfs进行overmount(cd /sysroot;mount --move . /;chroot .),然后执行/sysroot里面的init(1). 当然,这部分操作肯定是不能用上面的这些命令来做的,所以有一个switch_root命令实现这个功能.
0 阅读:0

云计算分享者

简介:感谢大家的关注