rootfs——InitRamdisk & InitRamfs 介绍和使用

一、rootfs
    rootfs,Root FileSystem,是指根文件系统,对应/目录节点。
    rootfs又分为虚拟rootfs和真实rootfs。
    虚拟rootfs由内核自己创建和加载,仅仅存在于内存之中(后续的InitRamfs也是在这种基础上实现),其文件系统是tmpfs类型或者ramfs类型。
    真实rootfs则是指根文件系统存在于存储设备上,内核在启动过程中会在虚拟rootfs上挂载这个存储设备,然后将/目录节点切换到这个存储设备上,这样存储设备上的文件系统就会被作为根文件系统使用(后续InitRamdisk是在这种基础上实现),其文件系统类型更加丰富,可以是ext2、yaffs、yaffs2等等类型,由具体的存储设备的类型决定。


二、InitRamdisk InitRamfs
     InitRamdisk InitRamfs 技术都是 使用ram的区域来作为根文件系统。
    1、差异如下
       (1)实现原理上的差异
            InitRamdisk,初始化内存盘INITRD(INITial Ram Disk)技术,利用ramdisk的技术,将系统一部分内存区域实现为/dev/ram,把/dev/ram作为作为一个存储设备,最终将根目录切换到/dev/ram的挂载,实现将/dev/ram作为根文件系统的目的。从原理上属于真是rootfs。
            InitRamfs,将一个包含有根文件系统的文件、目录、节点的cpio压缩的描述包直接释放到虚拟rootfs的内存区域中,后续都是由rootfs来作为系统的根文件系统使用,无需块设备参与。
        (2)文件系统上的差异
             InitRamdisk,使用ext2格式的文件系统。
             InitRamfs,使用kernel内核直接支持的ROOTFS格式的文件系统。
        (3)数据传输流上的差异
             InitRamdisk,需要经过ext2文件系统和/dev/ram设备
                
             InitRamfs,直接通过ROOTFS文件系统进行
                
       (3)初始化进程init的区别
             InitRamdisk,使用根文件系统下的/linuxrc来作为init进程
             InitRamfs,使用根文件系统下的/init来作为init进程
       (4)内核支持版本上的差异
             InitRamdisk,由kernel 2.4版本上开始支持
             InitRamfs,由kernel 2.6版本上开始支持
        (5)镜像的差异和制作方式上的差异会在后面说明    

    2、优缺点
        (1) InitRamfs的优势
             InitRamfs省去了创建/dev/ram、挂接文件系统和切换根目录的操作,启动过程更会简单和快速。
           同时, InitRamfs InitRamdisk 更简单快速,而Kernel对 InitRamfs 的内部处理也更为简单。
        (2) InitRamfs的缺点
            InitRamfs使用的是cpio包,包含了文件、目录、节点的描述语言包,为了描述一个文件、目录、节点,要增加很多额外的描述文字开销。这样使得cpio包比相应的image文件大很多。
        

三、名词、类型说明
    因为网上对于initrd有很多种名词,因为在这里做解释和统一说明。
    前面已经说过了 InitRamdisk和 InitRamfs,同时 InitRamfs又分为独立式 InitRamfs和集成式 InitRamfs。
     1、InitRamdisk
        老式块设备的initrd,对应init ramdisk的镜像,格式ext2。
        网上的名词:image-initrd,也可能直接用initrd来表示 InitRamdisk,具体需要根据文章自己进行判断。

     2、独立式InitRamfs
        是指将InitRamfs的压缩包与kernel Image独立开来,对应initramfs压缩包,是一个cpio格式压缩的独立文件。
        网上的名词:cpio-initrd(本质上是属于InitRamfs类型)

     3、集成式InitRamfs
        是指将InitRamfs的cpio压缩包集成到kernel Image中,该cpio格式压缩的文件会被被链接进了内核中特殊的数据段.init.ramfs上,其中全局变量__initramfs_start和__initramfs_end分别指向这个数据段的起始地址和结束地址。内核启动时会对.init.ramfs段中的数据进行解压,然后使用它作为临时的根文件系统。
        网上的名词:initramfs(本质上确实 是属于InitRamfs类型,但是是其中的一种类型


四、 InitRamdisk InitRamfs的制作
     1、InitRamdisk
    (1)通用命令如下:
   
  1. genext2fs -b 4096 -d rootfs ramdisk
  2. gzip -9 -f ramdisk
  3. mkimage -n "My Rootfs" -A arm -O linux -T ramdisk -C gzip -d ramdisk.gz ramdisk.img
        <1>  genext2fs用于将目录生成ext2格式的ramdisk。
           -b是指制作的ramdisk大小为4096K字节。 -d是指要制作成ramdisk的根文件系统目录。
            ramdisk则是指要生成ramdisk的名称
        <2> gzip将该ramdisk以最优方式压缩为ramdisk.gz
        <3> 第三个步骤由uboot使用,mkimage命令将压缩了的ramdisk根文件系统二进制文件ramdisk.gz转换成u-boot能够辨认的二进制文件ramdisk.img,并指定ramdisk.img的名字为“My Rootfs”,处理器体系架构为arm,操作系统类型为linux,程序类型为ramdisk,程序由gzip压缩,不需要指定ramdisk的链接起始地址和入口地址。 使用FIT方式可以跳过这步。
        
    (2)在X Project项目中的制作方法如下(需要切换到tiny210分支上)
        在config.mk中修改如下:
   
  1. ##
  2. ## Defining rootfs image type that want be generate.
  3. ##
  4. ROOTFS_IMAGE_TYPE=ramdisk
  5. #ROOTFS_IMAGE_TYPE=initramfs

        在rootfs已经生成之后(busybox安装完毕),执行
   
  1. make rootfs
        最终生成的 ramdisk.gz, ramdisk.img就是 InitRamdisk需要使用的镜像。
         ramdisk.gz在FIT模式下使用, ramdisk.img在传统uImage下使用。
 
       对应的生成脚本在build/script/mkrootfs.sh中
   
  1. ## Generate ramdisk image for rootfs.
  2. if [ "$ROOTFS_IMAGE_TYPE" = "$TYPE_INITRAMDISK" ]; then
  3.         genext2fs -b 4096 -d ${ROOTFS_DIR} ${ROOTFS_OUT_DIR}/${TYPE_INITRAMDISK}
  4.         gzip -9 -f ${ROOTFS_OUT_DIR}/${TYPE_INITRAMDISK}
  5.         ${UBOOT_OUT_DIR}/tools/mkimage -n ${BOARD_NAME} -A ${BOARD_ARCH} -O linux -T ramdisk -C gzip -d ${ROOTFS_OUT_DIR}/${TYPE_INITRAMDISK}.gz ${ROOTFS_OUT_DIR}/${TYPE_INITRAMDISK}.img
  6. fi


     2、独立InitRamfs
        (1)通用命令如下:
            进入到rootfs对应目录下,执行
   
  1. find . | cpio -H newc -o > ../rootfs.cpio
  2. gzip ../rootfs.cpio
            <1> 通过find命令获取当前目录下的所有文件,然后通过cpio -H newc -o 添加压缩到rootfs.cpio中
            <2> 通过gzip将 rootfs.cpio进行压缩
            生成的 rootfs.cpio.gz就是InitRamfs使用的镜像。

        (2) 在X Project项目中的制作方法如下(需要切换到tiny210分支上)
            在config.mk中修改如下
   
  1. ##
  2. ## Defining rootfs image type that want be generate.
  3. ##
  4. #ROOTFS_IMAGE_TYPE=ramdisk
  5. ROOTFS_IMAGE_TYPE=initramfs
        在rootfs已经生成之后(busybox安装完毕),执行
    
  1. make rootfs
        最终生成的initramfs .gz, 就是 InitRamfs需要使用的镜像,在FIT模式下使用。

         对应的生成脚本在build/script/mkrootfs.sh中
   
  1. ## Generate cpio initramfs image for rootfs.
  2. if [ "$ROOTFS_IMAGE_TYPE" = "$TYPE_INITRAMFS" ]; then
  3.         cd ${ROOTFS_DIR}; find . | cpio -H newc -o > ${ROOTFS_OUT_DIR}/${TYPE_INITRAMFS}
  4.         gzip ${ROOTFS_OUT_DIR}/${TYPE_INITRAMFS}
  5.         ${UBOOT_OUT_DIR}/tools/mkimage -n ${BOARD_NAME} -A ${BOARD_ARCH} -O linux -T ramdisk -C gzip -d ${ROOTFS_OUT_DIR}/${TYPE_INITRAMFS}.gz ${ROOTFS_OUT_DIR}/${TYPE_INITRAMFS}.img
  6. fi

遇到的问题:出现了crash。
        测试方法:
        因为集成式InitRamfs已经可以使用,所以可以借助集成式InitRamfs来测试我们这种方法生成的gz包有没有问题。
    (1)测试生成的gz包有没有问题
       可以将CONFIG_INITRAMFS_SOURCE="",把生成的gz包重命名成initramfs_data.cpio.gz然后放到/usr目录下。然后重编kernel,看看能否起来,可以起来就说明gz包没有问题。
        测试结果:无法起来,说明生成的 InitRamfs包有问题    
    (2)把 集成式InitRamfs生成的gz包直接拿过来用
        测试结果:拿过来之后发现可以正常启动,说明是我在生成InitRamfs的过程有问题。
    (3)通过zcat initramfs_data.cpio.gz | cpio -i -d -H newc --no-absolute-filenames命令解压出来看一下是否正确。
        测试结果:解出来发现根目录在tools中而不是rootfs中,将
               find  $ { ROOTFS_DIR } | cpio - H newc - o > $ { ROOTFS_OUT_DIR }/ $ { TYPE_INITRAMFS }
                            修改为如下后,解压出cpio后正常,也可以正常使用了
                cd $ { ROOTFS_DIR }; find . | cpio - H newc - o > $ { ROOTFS_OUT_DIR }/ $ { TYPE_INITRAMFS }

     3、集成式InitRamfs
        (1)在对应平台的config文件中添加如下:
   
  1. CONFIG_INITRAMFS_SOURCE="源rootfs的路径"
               然后执行make命令生成kernel镜像即可,对应的 InitRamfs的cpio包会被编译到kernel镜像里面。  

        (2)以tiny210为例,在arch/arm/configs/tiny210_defconfig中修改如下:
   
  1. CONFIG_INITRAMFS_SOURCE="/home/hlos/disk3/xys/temp/project-x/tools/common/rootfs"
                执行make kernel命令之后生成zImage。
                测试结果如下:
                在build/out/linux/usr可以找到cpio包“ initramfs_data.cpio.gz
   
  1. $ du initramfs_data.cpio.gz 
  2. 1096 initramfs_data.cpio.gz
                通过如上命令测试出initramfs_data.cpio.gz是1096K。
                在配置CONFIG_INITRAMFS_SOURCE之前Image的大小是3056K,zImage的大小是1524K。
                在 配置CONFIG_INITRAMFS_SOURCE之后Image的大小是4148K, zImage的大小是2620 K。
                从zImage的差值来看刚好是 initramfs_data.cpio.gz的大小
                ( Image的差值只有1092K,为什么???
        (3) 在X Project项目中没有直接支持这种方式,可以按照上述例子已经修改。


五、 InitRamdisk InitRamfs的使用
        以下步骤需要保证 rootfs下的必须存在的目录以及可执行文件已经存在,如busybox已经安装,/dev/console已经创建等等。
     1、InitRamdisk
    (1)需要kernel中打开的宏
   
  1. CONFIG_BLK_DEV_RAM=y
  2. CONFIG_BLK_DEV_INITRD=y
  3. CONFIG_BLK_DEV_MD=y
    (2)因为InitRamdisk是使用/dev/ram来作为真是根文件系统的方式,所以需要在cmdline中指定根文件系统root=/dev/ram,这里使用的是通过dts的bootargs来传递cmdline,所以修改如下:
   
  1. bootargs = "console=ttySAC0,115200n8 root=/dev/ram rw rootwait ignore_loglevel earlyprintk";
    通 过FIT方式将ramdisk的镜像和 kernel Image打包到一起 uboot解析到FIT之后会将ramdisk 的cpio包的地址传递给kernel的。
    
   补充:在 X Project项目tiny210分支上,生成FIT镜像的命令如下
   
  1. make kernel-img
            会自动根据ROOTFS_IMAGE_TYPE来选择rootfs镜像,生成对应的ITS文件,再根据ITS文件来将kernel和rootfs镜像生成对应的FIT的ITB文件。
            也就是在制作FIT镜像上,InitRamdisk和独立式InitRamfs是兼容的。具体参考脚本gen_its.sh。
       
    2、独立式InitRamfs
    (1) 需要kernel中打开的宏
    
  1. CONFIG_BLK_DEV_RAM
  2. CONFIG_BLK_DEV_INITRD
     无需配置/dev/ram,通过FIT方式 将生成的 InitRamfs的cpio包和kernel Image打包到一起。uboot解析到FIT之后会将 InitRamfs的cpio包的地址传递给kernel的(方式和 InitRamdisk的方式一致 )。

   补充:在 X Project项目tiny210分支上,生成FIT镜像的命令如下
    
  1. make kernel-img
            会自动根据ROOTFS_IMAGE_TYPE来选择rootfs镜像,生成对应的ITS文件,再根据ITS文件来将kernel和rootfs镜像生成对应的FIT的ITB文件。
            也就是在制作FIT镜像上,InitRamdisk和独立式InitRamfs是兼容的。 具体参考脚本gen_its.sh。

    3、集成式InitRamfs
    (1) 需要kernel中打开的宏
   
  1. CONFIG_BLK_DEV_RAM
  2. CONFIG_BLK_DEV_INITRD
       无需配置/dev/ram,kernel起来之后,会通过 数据段.init.ramfs找到initramfs的位置,rootfs应该就可以正常使用了。


    
参考网站:
http://blog.youkuaiyun.com/wh_19910525/article/details/8112130( 制作 ramdisk.img,使用cpio 和 gzip
http://www.cnblogs.com/pied/archive/2013/01/29/2880718.html(initramfs实作)

initrd、rootfsinitramfs是在Linux系统中用于引导初始化的概念,它们之间有一些区别作用。 1. initrd(Initial RAM Disk)是一个临时的根文件系统,它是在系统引导过程中由内核加载到内存中的。它通常包含一些必要的驱动程序工具,用于在真正的根文件系统(rootfs)加载之前进行一些初始化操作。initrd最初是为了解决早期Linux系统在引导过程中无法识别硬件的问题而设计的。它的作用是提供一个临时的根文件系统,以便在引导过程中加载必要的驱动程序模块,从而能够识别访问硬件设备。 2. rootfs(Root File System)是Linux系统中的根文件系统,它是系统中所有其他文件系统的基础。rootfs包含了操作系统的核心文件目录结构,它是系统引导后的第一个文件系统。在引导过程中,initrd会被加载到内存中,然后解压缩到rootfs中。一旦rootfs加载完成,系统将切换到rootfs作为根文件系统,并执行init程序来完成系统的初始化启动。 3. initramfs(Initial RAM File System)是initrd的一种改进版本,它是一个压缩的文件系统映像,也是在系统引导过程中由内核加载到内存中的。与initrd不同,initramfs不需要解压缩到内存中的临时文件系统中,而是直接在内存中解压缩并挂载为根文件系统。initramfs的作用与initrd类似,它提供了一个临时的根文件系统,用于在引导过程中加载必要的驱动程序模块。 总结: - initrd是早期Linux系统中使用的临时根文件系统,用于在引导过程中加载必要的驱动程序模块。 - rootfs是Linux系统中的根文件系统,包含了操作系统的核心文件目录结构。 - initramfs是initrd的改进版本,它是一个压缩的文件系统映像,直接在内存中解压缩并挂载为根文件系统。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值