Ramdisk简介

导读:
  先简单介绍一下ramdisk,Ramdisk是虚拟于RAM中的盘(Disk)。对于用户来说,可以把RAM disk与通常的硬盘分区(如/dev/hda1)同等对待来使用,例如:
  
redice # mkfs.ext2 /dev/ram0mke2fs 1.38 (30-Jun-2005)Filesystem label=OS

type: LinuxBlock size=1024(log=0)Fragment size=1024 (log=0)2048 inodes,

8192 blocks409 blocks (4.99%) reserved for the super

userFirst data block=11 block group8192 blocks per group, 8192 fragments

per group2048 inodes per group
  
Writing inode tables: doneWriting superblocks and filesystem

accounting information: done
  
This filesystem will be automatically checked every 24 mounts or180 days,

whichever comes first.

Use tune2fs -c or -i to override.
  
redice # mount /dev/ram0 /mnt/rdredice # ls /mnt/rdlost+foundredice

# mount/dev/hda2 on / type ext3proc

on /proc type proc (rw)/dev/ram0 on /tmp/xxx type ext2 (rw)

  当然,Ramdisk与硬盘分区有其不同的地方,例如RAM
  disk不适合作为长期保存文件的介质,掉电后Ramdisk的内容会随内存内容的消失而消失。Ramdisk的其中一个优势是它的读写速度高,可以被用
  作需要高速读写的文件。但在2.6版本后,Ramdisk的这一作用开始被tmpfs(Virtual memory file system
  support)取代。
  回到上面的例子,我们格式化了一个ramdisk(/dev/ram0)并且将其mount到/mnt/rd目录下,那么这个Ramdisk有多大呢?先看一下:
  
redice # df -h /dev/ram2Filesystem

容量 已用 可用 已用% 挂载点/dev/ram0

7.8M 1.0K 7.4M 1% /mnt/rd

  从上面的信息看出,ramdisk有大约7.8M的可用空间。我们再试一下另外的文件系统,重新格式化成minix分区并挂接试一下:
  
redice # umount /mnt/rdredice # mkfs.minix /dev/ram02752 inodes8192

blocksFirstdatazone=90 (90)

Zonesize=1024Maxsize=268966912
  
redice # mount /dev/ram0 /mnt/rdredice # df -h /dev/ram0Filesystem

容量 已用 可用 已用% 挂载点/dev/ram0

8.0M 1.0K 8.0M 1% /mnt/rd

  现在看出来了,的确是8M(这同时说明,EXT2文件系统本身要占用一定的存储空间,相比之下minix文件系统要少些),这个空间是在编译核心时就确定下来了,在配置Ramdisk时,有一个叫 Default RAM disk size 的参数决定默认情况下Ramdisk的大小。可以通过核心命令行参数(ramdisk_size)来改变这个值,例如要设置Ramdisk的大小为16M,在grub中可以用:
  
# grub.conf -default=0timeout=10splashimage=(hd0,0)/grub/splash.xpm.gztitle

Redice Linuxroot (hd0,0)

kernel /vmlinuz ro root=LABEL=/ hdc=ide-scsi ramdisk_size=16384

initrd /initrd

  这样,Ramdisk的大小就变成16M了。这个参数是Ramdisk直接编译到核心时才能使用的,如果Ramdisk编译为模块,则应该使用模块参数来设置Ramdisk的大小:
  
redice # insmod rd rd_size=16384

  
  
  编译到核心时,可以通过下面的一些核心命令行参数来配置Ramdisk:
  ramdisk_size - ramdisk的大小(Kbytes);
  ramdisk - 与ramdisk_size的作用相同;
  ramdisk_blocksize - ramdisk的块大小,默认情况为1024;
  当以模块的形式译时,模块支持以下几个加载参数:
  rd_size - 同上面的ramdisk_size或ramdisk参数;
  rd_blocksize - 同上面的ramdisk_blocksize;
   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文件系统;
  如果核心选择了Gzip支持(通常这是默认的,在init/do_mounts_rd.c中定义的BUILD_CRAMDISK宏)还可以使用Gzip压缩的initrd。相关的代码可以在核心源码 drivers/block/rd.c:identify_ramdisk_image 中找到。
   制作initrd
  制作initrd传统的作法是通过软盘(显然过时了,不介绍了)、ramdisk或loop设备(/dev/loop)。通过ramdisk来制作的方法比较简单(以ext2文件系统为例):
  
redice # mkfs.ext2 /dev/ram0redice

# mount /dev/ram0 /mnt/rdredice

# cp _what_you_like_ /mnt/rd

# 把需要的文件复制过去redice # dd if=/dev/ram0 of=/tmp/initrdredice

# gzip -9 /tmp/initrd

  这个过程也最能够解释initrd的本质,对于Linux来说,Ramdisk的一个块设备,而
  initrd是这个块设备上所有内容的“克隆”(由命令dd来完成)而生成的文件。核心中加载initrd相关的代码则用于完成
  将相反的过程,即将这一个文件恢复到Ramdisk中去。
  通过loop设备来制作initrd的过程:
  
redice # dd if=/dev/zero of=/tmp/initrd bs=1024 count=4096 # 制作一个4M的空白文件

redice # losetup /dev/loop0 /tmp/initrd

# 映射到loop设备上;redice # mkfs.ext2 /dev/loop0

# 创建文件系统;redice # mount /dev/loop0 /mnt/rdredice # cp _what_you_like_ /mnt/rd

# 复制需要的文件;redice # umount /mnt/rdredice # losetup -d /dev/loop0redice

# gzip -9 /tmp/initrd

  不过,现在已经有了一些更好的工具来完成这些工作,包括genromfs(uClinux里常用的工
  具),genext2fs,mkcramfs等。这些工具提供了一些方便开发的新特性,例如,不需要上面烦索的过程,只要将文件复制到某个目录中,将其作
  为根目录,即可生成initrd;另一个重要的改进是,这些工具都可以以普通用户的身份来生成initrd。
  未完,待续…(补充有关如何加载|ARM中如何使用initrd作为根文件系统等)
   链接和参考文档
   文档
  Linux文档中关于ramdisk的介绍,核心目录里 Documentation/ramdisk.txt;
  Linux文档中关于initrd的介绍,核心目录 Documentation/initrd.txt;
  Linux文档中关于tmpfs的介绍,核心目录 Documentation/filesystems/tmpfs.txt;
  How to use a Ramdisk for Linux
   资源
  genromfs- genromfs is a space-efficient, small, read-only filesystem originally for Linux and used by some Linux based projects.
  genext2fs
  - Simply, it generates an ext2 filesystem as a normal (i.e. non-root)
  user. It doesn’t require you to mount the image file to copy files on
  it. It doesn’t even require you to be the superuser to make device
  nodes or set group/user ids.
  cramfs
  - cramfs is a Linux filesystem designed to be simple, small, and to
  compress things well. It is used on a number of embedded systems and
  small devices.
  使用ram disk初始化(initrd)
  initrd提供了在boot loader下加载ram disk的方法。该ram disk可以被作为根文件系统挂载进来,里面的程序也可以运行。然后,新的根文件系统可以从其他设备挂载。之前的根(来自initrd)可以被转移到一个目录然后被卸载。
  initrd主要设计用来使系统启动于两个条件,一个是内核来自于非常小的驱动器,一个是额外的模块需要从initrd中加载。
  本文给出initrd的概要描述,更具体的可以参考[1]。
  操作
  当使用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文件系统被移去。
  注意,改变根目录不牵扯卸载他。
  挂载在initrd的文件系统仍然可以被访问。
  启动命令选项
  initrd添加了如下新的选项:
  initrd= (e.g. LOADLIN)
  加载特定的文件作为初始的ram disk。当使用lilo,你应该在/etc/lilo.conf中指定
  ram disk镜像文件位置,使用INITRD变量。
  noinitrd
  initrd数据被保留却不转化成ram disk,正常的根文件系统被加载。initrd的数据可以 从/dev/initrd中读取。注意,在initrd中的数据可以是任意结构的,不一定要是文件系统镜像。该选项多用于调试。
  注意:/dev/initrd是只读的,而且只能被使用一次。只要最后一个进程关闭它,所有的数据将会释放掉,而/dev/initrd将不再被打开。
  root=/dev/ram0 (without devfs)
  root=/dev/rd/0 (with devfs)
  initrd作为根文件系统被挂载,随后正常的启动顺序中,ram disk 仍然作为root。
  安装
  首先,用于initrd文件系统的目录在根文件系统上被创建:
  #mkdir /initrd
  名字不是很重要。更多的可以参考pivot_root(2)的man。
  在启动过程中,如果根文件系统被创建(如果你有软盘启动),那么根文件系统应该创建/initrd目录。
  如果initrd没有被挂载,他里面的内容仍然可以被访问,通过以下的方法(注意,这在使用devfs时不可用):
  # mknod /dev/initrd b 1 250
  # chmod 400 /dev/initrd
  第二步,内核编译的时候必须支持ram disk并启动ram disk使能。所有从initrd中执行的程序必须被编译到内核中。
  第三步,你必须创建ram disk镜像。这可以通过在块设备上创建文件系统实现,把所需的文件拷贝,然后把文件拷贝到initrd文件。根据最新的内核,至少三种设备可以用:
  l 软盘(慢,却随处可用)
  l ram disk(快,需要物理内存)
  l loopback device(最高档)
  我将介绍loopback device方法:
  保证loopback device被内核支持
  创建一个空的文件系统,拥有合适的大小:
  # dd if=/dev/zero of=initrd bs=300k count=1
  # mke2fs -F -m0 initrd
  如果空间不多,你可以用minix fs而不是ext2
  挂载文件系统
  # mount -t ext2 -o loop initrd /mnt
  创建控制台设备(如果用devfs,就没必要)
  # mkdir /mnt/dev
  # mknod /mnt/dev/console c 5 1
  拷贝initrd环境需要的所有文件。不要忘掉最重要的文件/linuxrc.
  注意,/linuxrc必须有执行权限。
  正确的initrd环境可以不用重启就可以通过命令行测试:
  # chroot /mnt /linuxrc
  卸载文件系统
  # umount /mnt
  现在initrd被保存在initrd文件中。还可以压缩他。
  # gzip -9 initrd
  为了试验initrd,你可以创建一个急救盘,只需创建/linuxrc到/bin/sh的符号链接。
  你还可以试着把initrd更小。
  最后,你要启动内核并加载initrd.几乎所有的boot loader都支持initrd.
  虽然启动进程兼容老的机制,下面的启动命令行还是得给出:
  root=/dev/ram0 init=/linuxrc rw
  如果不使用devfs.或者
  root=/dev/rd/0 init=/linuxrc rw
  如果使用devfs.
  使用 LOADLIN,只要执行
  LOADLIN initrd=
  e.g. LOADLIN C:/LINUX/BZIMAGE initrd=C:/LINUX/INITRD.GZ root=/dev/ram0
  init=/linuxrc rw
  使用LILO,你添加选项INITRD= 到/etc/lilo.conf中,使用APPEDN命令即可。
  image = /bzImage
  initrd = /boot/initrd.gz
  append = “root=/dev/ram0 init=/linuxrc rw”
  然后运行 /sbin/lilo
  对于其他的启动程序,请参考相应的文档。

本文转自
http://czdj2000.yo2.cn/articles/linux%e4%b8%ad%e7%9a%84ramdisk%e4%b8%8einitrd.html
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值