ramdisk/ramfs/tmpfs/initrd/initramfs/rootfs/cpio

本文详细解析了RAMFS、RAMDISK、TMPFS、INITRD及INITRAMFS的概念与区别,介绍了它们在Linux系统中的应用,特别是初始化过程中的作用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >


一 RAMDISK VS INITRD 
  先简单介绍一下ramdisk,Ramdisk是虚拟于RAM中的盘(Disk)。对于用户来说,可以把RAM disk与通常的硬盘分区(如/dev/hda1)同等对待来使用 
  # mkfs.ext2 /dev/ram0 
  # mount /dev/ram0 
  # mkdir /mnt/rd 
  # mount /dev/ram0 /mnt/rd 
  # ls /mnt/rd 
  lost+found 
  # df -h /dev/ram0 
  编译到核心时,可以通过下面的一些核心命令行参数来配置Ramdisk: 
  ramdisk_size - ramdisk的大小(Kbytes); 
  initrd概述 
  上面已经提到,Ramdisk需要先格式化然后理能使用。那么,如果核心希望使用ramdisk该如何做呢?于是initrd产生了,initrd全称是 initial RAM disk ,它提供一种让核心可以简单使用Ramdisk的能 
  力,简单的说,这些能力包括: 
  格式化一个 Ramdisk; 
  加载文件系统内容到Ramdisk; 
  将Ramdisk作为根文件系统; 
  我们可以将initrd形像的比作Norton Ghost备份的硬盘分区,而Linux启动阶段的Ramdisk相当于一个未格式化的硬盘分区,核心可以直接将initrd的内容释放到一个未初始化的Ramdisk里,这个过程与 
  Ghost恢复一个分区的过程十分相似。于是,相应的内容被加载到相应的Ramdisk中,同时,这个Ramdisk也被格式化成某种由initrd格式所表达的分区格式。 
  initrd与Ghost备份的分区有许多相似之处,例如,它有一定的大小,包含分区上的文件系统格式等。initrd支持的格式包括: 
  Ext2文件系统; 
  Romfs文件系统; 
  cramfs文件系统; 
  minix文件系统; 
  1)传统方法制作initrd 
  # mkfs.ext2 /dev/ram0 
  # mount /dev/ram0 /mnt/rd 
  # cp _what_you_like_ /mnt/rd 
  # dd if=/dev/ram0 of=/tmp/initrd 
  # gzip -9 /tmp/initrd 
  (由此可见,initrd文件就是ext2格式的盘,当它释放到没有格式的ramdisk的时候,ramdish自然被格式化成ext2格式的盘了,这个格式是由initrd决定的。) 
  这个过程也最能够解释initrd的本质,对于Linux来说,Ramdisk的一个块设备,而initrd是这个块设备上所有内容的“克隆”(由命令dd来完成)而生成的文件。核心中加载initrd相关的代码则用于完 
  成将相反的过程,即将这一个文件恢复到Ramdisk中去。 
  2)通过loop设备来制作initrd的过程: 
  # dd if=/dev/zero of=/tmp/initrd bs=1024 count=4096 # 制作一个4M的空白文件 
  # losetup /dev/loop0 /tmp/initrd # 映射到loop设备上; 
  # mkfs.ext2 /dev/loop0 # 创建文件系统; 
  # mount /dev/loop0 /mnt/rd 
  # cp _what_you_like_ /mnt/rd # 复制需要的文件; 
  # umount /mnt/rd 
  # losetup -d /dev/loop0 
  # gzip -9 /tmp/initrd 
  3)另外使用loop设备制作initrd的过程 
  # dd if=/dev/zero of=/tmp/initrd bs=1024 count=4096 # 制作一个4M的空白文件 
  # mkfs.ext2 /tmp/initrd 
  # mount /tmp/initrd /mnt/rd -t ext2 -o loop=/dev/loop0 
  # cp _what_you_like_ /mnt/rd # 复制需要的文件; 
  # umount /mnt/rd 
  # gzip -9 /tmp/initrd 
  (由此可见,loop就是一个设备文件,initrd必须和设备文件绑定或映射或等同,才进行近一步的操作。mount可分解成losetup /dev/loop0 /tmp/initrd and mount /dev/loop0 /mnt/rd) 
  使用ram disk初始化(initrd) 
  initrd提供了在boot loader下加载ram disk的方法。该ram disk可以被作为根文件系统挂载进来,里面的程序也可以运行。然后,新的根文件系统可以从其他设备挂载。之前的根(来自initrd)可以被 
  转移到一个目录然后被卸载。 
  initrd主要设计用来使系统启动于两个条件,一个是内核来自于非常小的驱动器,一个是额外的模块需要从initrd中加载。 
  当使用initrd,典型的系统启动顺序如下: 
  1. boot loader加载内核并初始化ram disk 
  2. 内核把initrd转化成正常的ram disk 并释放initrd使用的内存 
  3. initrd作为root被挂载,赋予读写权限。 
  4. /linuxrc被执行(这可以是任何可执行文件,如脚本,运行在uid 0,可以做任何初始化)。 
  5. linuxrc挂载真正的根文件系统 
  6. linuxrc使用pivot_root系统调用把根文件系统放在根目录。 
  7. 正常的启动序列(/sbin/init)在根文件系统上执行。 
  8. initrd文件系统被移去。 
  二 RAMFS VS TMPFS vs ramdisk vs initramfs 
  1.ramdisk是由块设备来实现的,必须格式化成某种文件格式才能使用,需要设备文件,例如ram0等,initrd就是initial ramdisk;编译内核时须将block device中的Ramdisk支持选上,它下面还有两个 
  选项,一个是设定Ramdisk的大小,默认是4096k;另一个是initrd的支持。其不足之处是大小固定,之后不能改变。 
  2.ramfs就是内存文件系统,不需要格式化,不需要设备文件,可以动态增长; 
  3.tmpfs是虚拟内存文件系统,它不同于传统的用块设备形式来实现的ramdisk,也不同于针对物理内存的Ramfs,Tmpfs可以使用物理内存,也可以使用交换分区。在Linux内核中,虚拟内存资源由物理内 
  存(RAM)和交换分区组成,这些资源是由内核中的虚拟内存子系统来负责分配和管理。 Tmpfs就是和虚拟内存子系统来"打交道"的,它向虚拟内存子系统请求页来存储文件,它同Linux的其它请求页的
部分一样,不知道分配给自己的页是在内存中还是在交换分区中。Tmpfs同Ramfs一样,其大小也不是固定的,而是随着所需要的空间而动态的增减。使用tmpfs,首先你编译内核时得选择"虚拟内存文件 
  系统支持(Virtual memory filesystem support)" ,然后就可以加载tmpfs文件系统了。 
  4.rootfs是ramfs的特殊实例, 在2.6的内核中必然存在。rootfs不能被卸载(与其添加特殊代码用来维护空的链表,不如把rootfs节点始终加入,因此便于kernel维护:简单、精炼。rootfs是ramfs的一 
  个空实例,占用空间极小)。大部分其他的文件系统安装于rootfs之上。 
  5.initramfs:2.6的Linux内核包含有gzip压缩的cpio格式的文档,可以在内核引导的时候解压缩为rootfs 
  6.补充:通常情况下,Linux的所有文件在内存中都有缓存。需要读取的数据页从支撑存储设备(block device)中读取后,缓存于内存。在支撑存储设备中的数据页执行marked as clean操作。当虚拟文件系统需要支撑存储设备中的数据页内存时,可以释放。基于同样的机制,支撑存储设备的写入操作(写入文件然后写回支撑存储设备,marked as clean)后,也可以释放占用的数据页内存。对于文件目录占用的缓存(dentry: directory entry),也存在同样的机制。但是,ramfs中不需要支撑存储设备(没有支撑缓存,但是有缓存)。也就是说,写入ramfs的文件可以正常的分配 page cache and dentry cache,但是不能写入支撑存储设备。这些page cache and dentry cache不能被VM释放、回收。由于ramfs可以基于现有的Linux的文件系统结构,用于实现ramfs的代码很小。一般而言,支撑存储设备的缓存被安装为一个文件系统。所以,ramfs不能通过menuconfig选择,是必然进入内核的。在 ramfs的下面可以一直写入数据,直到写满内存为止。由于VM(Vitual Memory)认为文件应该被写回支撑存储设备,而不是交换空间(swap space),所以VM不能释放ramfs分配的内存。从而,只有root用户(or trusted user)才能进行ramfs写操作。 
  例1 
  # mkdir -p /RAM1 
  # mount -t ramfs none /RAM1 
  例2 
  # mkdir -p /RAM1 
  # mount -t ramfs none /RAM1 -o maxsize=10000 
  例3 
  # mkdir -p /mnt/tmpfs 
  # mount tmpfs /mnt/tmpfs -t tmpfs 
  例如4 
  # mount tmpfs /mnt/tmpfs -t tmpfs -o size=32m 
  三 initrd vs initramfs 
  1. initrd是一个单独的文件;initramfs和Linux内核链接在一起(/usr目录下的程序负责生成initramfs文档)。 
  2. initrd是一个压缩的文件系统映像(可以是ext2等,需要内核的驱动);initramfs是类似tar的cpio压缩文档。内核中的cpio解压缩代码很小,而且init数据在boot后可以丢弃。 
  3. initrd运行的程序(initd,不是init)进行部分setup后返回内核;initramfs执行的init程序不返回内核(如果/init需要向内核传递控制权,可以再次安装在/目录下一个新的root设备并且启动一个新 
  的init程序)。 
  4. 切换到另一个root设备时,initrd执行pivot_root后,卸载ramdisk;initramfs是rootfs,既不能 pivot_root,也不能卸载。initramfs会删掉rootfs的所有内容(find -xdev / -exec rm '{}' ';') 
  ,再次安装root到rootfs(cd /newmount; mount --move . /; chroot .),把stdin/sdout/stderr挂在新的/dev/console上,重新执行init。由于这是一个相当困难的实现过程(包括在使用一个命令之前 
  把它删除),所以klibc工具包引入一个帮助程序/utils/run_init.c来执行上述过程。其他大部分工具包(包括busybox) 把这个命令称为"switch_root"。 
  问题: 
  在嵌入式中,rootfs即initramfs就是最终的根文件文件系统,是不是说这个根也是ramfs文件系统呢,没有和设备绑定的?命令行用到ram0,但ram0不是和ramdisk相关的嘛,如下 
  # cat cmdline 
  console=ttyS1,57600n8 root=/dev/ram0 
  # mount 
  rootfs on / type rootfs (rw) 
  proc on /proc type proc (rw) 
  none on /var type ramfs (rw) 
  none on /etc type ramfs (rw) 
  none on /tmp type ramfs (rw) 
  none on /media type ramfs (rw) 
  none on /sys type sysfs (rw) 
  none on /dev/pts type devpts (rw) 
  none on /proc/bus/usb type usbfs (rw) 
  mdev on /dev type ramfs (rw) 
  devpts on /dev/pts type devpts (rw) 

 原文地址 http://www.cnzer.cn/view-6612-2.html

Reference:

Linux 初始 RAM 磁盘(initrd)概述 http://www.ibm.com/developerworks/cn/linux/l-initrd.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值