• Linux中的Ramdisk和Initrd


    Ramdisk简介
    先简单介绍一下ramdisk,Ramdisk是虚拟于RAM中的盘(Disk)。对于用户来说,能把RAM disk和通常的硬盘分区(如/dev/hda1)同等对待来使用,例如:
    redice # mkfs.ext2 /dev/ram0
    mke2fs 1.38 (30-Jun-2005)
    Filesystem label=
    OS type: Linux
    Block size=1024 (log=0)
    Fragment size=1024 (log=0)
    2048 inodes, 8192 blocks
    409 blocks (4.99%) reserved for the super user
    First data block=1
    1 block group
    8192 blocks per group, 8192 fragments per group
    2048 inodes per group
    Writing inode tables: done
    Writing superblocks and filesystem accounting information: done
    This filesystem will be automatically checked every 24 mounts or
    180 days, whichever comes first.  Use tune2fs -c or -i to override.
    redice # mount /dev/ram0 /mnt/rd
    redice # ls /mnt/rd
    lost+found
    redice # mount
    /dev/hda2 on / type ext3
    proc 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/ram2
    Filesystem            容量  已用 可用 已用% 挂载点
    /dev/ram0             7.8M  1.0K  7.4M   1% /mnt/rd
    从上面的信息看出,ramdisk有大约7.8M的可用空间。我们再试一下另外的文件系统,重新格式化成minix分区并挂接试一下:
    redice # umount /mnt/rd
    redice # mkfs.minix /dev/ram0
    2752 inodes
    8192 blocks
    Firstdatazone=90 (90)
    Zonesize=1024
    Maxsize=268966912
    redice # mount /dev/ram0 /mnt/rd
    redice # df -h /dev/ram0
    Filesystem            容量  已用 可用 已用% 挂载点
    /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=0
    timeout=10
    splashimage=(hd0,0)/grub/splash.xpm.gz
    title Redice Linux
            root (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/ram0
    redice # mount /dev/ram0 /mnt/rd
    redice # cp _what_you_like_  /mnt/rd    # 把需要的文件复制过去
    redice # dd if=/dev/ram0 of=/tmp/initrd
    redice # 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/rd
    redice # cp _what_you_like_ /mnt/rd                        # 复制需要的文件;
    redice # umount /mnt/rd
    redice # losetup -d /dev/loop0
    redice # gzip -9 /tmp/initrd
    不过,目前已有了一些更好的工具来完成这些工作,包括genromfs(uClinux里常用的工具),genext2fs,mkcramfs等。这些工具提供了一些方便研发的新特性,例如,不必上面烦索的过程,只要将文件复制到某个目录中,将其作为根目录,即可生成initrd;另一个重要的改进是,这些工具都能以普通用户的身份来生成initrd。
    未完,待续…(补充有关怎么加载|ARM中怎么使用initrd作为根文件系统等)
    链接和参考文件
    文件

    原文:http://czdj2000.yo2.cn/articles/linux%E4%B8%AD%E7%9A%84ramdisk%E4%B8%8Einitrd.html

  • 相关阅读:
    vue项目实战:原生百度地图api的使用
    vue项目实战:页面公共组件的全局注册动态引入的考虑
    celery+django的定时任务设置
    celery.exceptions.NotRegistered: 'tasks.add' + celery delay 坑 + python manage.py check 查看状态
    from __future__ import absolute_import的作用
    Django与celery集成:异步任务原理和过程
    python -m pip install --upgrade pip --default-timeout=100 -i http://pypi.douban.com/simple/ --trusted-host pypi.douban.com
    Django 的安全
    django集成sentry实现日志上报和钉钉告警
    TypeScript(21): 装饰器
  • 原文地址:https://www.cnblogs.com/hicjiajia/p/2582634.html
Copyright © 2020-2023  润新知