前面提到的文件系统都是基于Flash存储器的,而本文介绍的这些文件系统都是利用RAM来作为他们的存储空间。它们共同的优点都是读写的速度非常快(因为是在内存中读写),而缺点也很明显,就是当系统复位之后会丢失所有数据。




二、基于RAM的文件系统




1、Ramdisk文件系统



     Ramdisk是将一部分固定大小的内存当做分区来使用。它并非一个实际的文件系统,而是一种将实际的文件系统装入内存的机制,并且可以作为根文件系统。


A、特点


     a. 将一些经常访问但不会修改的文件通过ramdisk放入内存,可明显提高系统的性能;


     b. 和CRAMFS、JFFS2相比,压缩率不高,占用资源多;


     c. 存取速度快;


     d. 只读文件系统,掉电数据丢失。


B、创建方法


     a. 内核起来之后创建和挂载方式



    1. 查看系统可用的ramdisk
    2. #ls -al /dev/ram*
    3.  内核将ramdisk作为一个设备文件来管理,未格式化之前还不占用内存空间
    4. #mke2fs /dev/ram0
    5.  这个命令就格式化了一个ramdisk,出现以下提示:
    6. mke2fs 1.41.12 (17-May-2010)
    7. Filesystem label=
    8. OS type: Linux
    9. Block size=1024 (log=0)
    10. Fragment size=1024 (log=0)
    11. Stride=0 blocks, Stripe width=0 blocks
    12. 16384 inodes, 65536 blocks
    13. 3276 blocks (5.00%) reserved for the super user
    14. First data block=1
    15. Maximum filesystem blocks=67108864
    16. 8 block groups
    17. 8192 blocks per group, 8192 fragments per group
    18. 2048 inodes per group
    19. Superblock backups stored on blocks: 
    20. , 24577, 40961, 57345
    21. 
    22. Writing inode tables: done 
    23. Writing superblocks and filesystem accounting information: done
    24. 
    25. This filesystem will be automatically checked every 36 mounts or
    26. 180 days, whichever comes first. Use tune2fs -c or -i to override.
    27. 
          加载ramdisk 
      
    28.   #mkdir /mnt/ramdisk
    29.   #mount /dev/ram0 /mnt/ramdisk
    30. 
          可以查看创建的ramdisk的大小 
      
    31.    
       root@jgf:~/qihuan 
       # df -k /dev/ram0              
       Filesystem           1K-blocks      Used Available Use% Mounted on
       /dev/ram0                63461      1289     58896   3% /mnt/ramdisk32. 
          卸载 
      
    33. #umount /mnt/ramdisk


    b. 如何创建ramdisk镜像文件


         提供一个脚本用于将准备好的rootfs文件夹创建为ramdisk.img,可在ubuntu上运行,原来还是利用ubuntu的mke2fs命令格式化一块ram,在mount到/mnt下面,再将rootfs拷贝到其中,在拷贝出来便成为了ramdisk.img镜像文件。


         make_ramdisk.sh



    1. #!/bin/bash
    2.  
    3. ...clean before img
    4. -f /tmp/ramdisk.img
    5.  
    6.  # Ramdisk Constants
    7. = 80 * 1024 * 1024
    8. =8192
    9. =1024
    10.  
    11.  # Create an empty ramdisk image
    12. dd if=/dev/zero of=/tmp/ramdisk.img bs=$BLKSIZE count=$RDSIZE
    13.  
    14. file system
    15. /sbin/mke2fs -F -m 0 -b $BLKSIZE /tmp/ramdisk.img $RDSIZE
    16.  
    17.  # Mount it so that we can populate
    18. -p /mnt/ramdisk
    19. /tmp/ramdisk.img /mnt/ramdisk -t ext2 -o loop
    20.  
    21. (subdirectories)
    22. -ar ./rootfs/* /mnt/ramdisk/
    23.  
    24. -p /mnt/ramdisk/sys
    25. -p /mnt/ramdisk/proc
    26. -p /mnt/ramdisk/var
    27. -p /mnt/ramdisk/tmp
    28. -p /mnt/ramdisk/mnt
    29. -p /mnt/ramdisk/dev
    30.  
    31. ...
    32. /mnt/ramdisk
    33. /tmp/ramdisk.img ./
    34. -fr /mnt/ramdisk


         这时便生成了ramdisk.img,可以在你的ubuntu上挂载试验一下



    1. #mount ramdisk.img /mnt/ -o loop
    2. #ls /mnt
    3. bin etc init lost+found modules proc sys usr dev home lib mnt sbin tmp var


         如果实现将其烧写到nand的某个分区中,然后uboot启动的时候,需要一些参数配置,并且需要在读取内核之后紧接着将其也读到内存的相应位置,再启动linux:


    1. define CONFIG_BOOTARGS "root=/dev/ram0 rw console=ttyS0,115200 mem=64mb initrd=0x41000000,0x800000 init=/linuxrc"
    2. "mtdparts default; nand read 0x41000000 0xe00000 0x800000; nand read 0x40008000 0x400000 0x300000; bootm 0x40008000;"


    当然,在嵌入式中,对于ramdisk的支持需要一些配置,列出:



    1. 1、General setup --->
    2. [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
    3. --->
    4. <*> Second extended fs support 
    5. --->
    6. [*] Block devices ---> 
    7. --- Block devices
    8. <*> Loopback device support 
    9. <*> Cryptoloop Support
    10. <*> RAM block device support
    11. (16) Default number of RAM disks 
    12. (8192) Default RAM disk size (kbytes)
    13. 
               2、ramdisk是基于EXT2的,所以需要支持EXT2,当然,也有EXT3类型的ramdisk 
      
    14. 
               3、这里可以指定ramdisk的最大空间


    2、RamFS和TmpFS文件系统


     


    不能格式化,可以创建多个,创建时可以指定其最大能使用的内存大小,并且可以读写。


    嵌入式Linux中许多的后台守护进程会生成很多的日志消息,还有内核日志记录机制,如syslogd、dmesg和klogd等,会在/var/ 和 /tmp/目录下生成许多的消息。如果这些消息都保存在Flash中,势必极大的消耗Flash的使用寿命,这里最好的方法是使用RamFS。


         与传统的ramdisk相比,不同之处在于其不可以格式化,文件系统大小可以动态变化。


     A、挂载方式


    1. #mkdir /mnt/ramfs
    2. #mount -t ramfs none /mnt/ramfs
    3. /dev/设备节点
    4. (kB单位)
    5. #mount -t ramfs none /mnt/ramfs -o maxsize=2000
    6. /etc/rc.d等文件里面会看到这样的内容
    7. #mount -t tmpfs tmpfs /var -o size=512k
    8. #mkdir -p /var/tmp
    9. #mkdri -p /var/log
    10. #ln -s /var/tmp /tmp
    11. /var上创建了ramfs并将其大小限制为512k,同时tmp和log目录成为ramfs的一部分以便在RAM中存储日志消息。
    12. /etc/fstab中,语法为
    13. /var tmpfs size=32m 0 0
    14. /var上挂装一个新的ramfs的文件系统



        

    3、initramfs文件系统



         这个文件系统也是基于ramfs的,不过最大的区别就是,在内核中配置了选项之后,可以将其和内核镜像打包在一起,并支持例如gzip等的压缩,可以进一步的简化uboot的配置和镜像的大小。


         内核配置


    1.  General setup --->
    2.    [*] Initial RAM filesystem and RAM disk (initramfs/initrd) support
    3.      (../ramdisk/rootfs) Initramfs source file(s)
    4.      (0) User ID to map to 0 (user root)
    5.      (0) Group ID to map to 0 (group root)
    6.      [*] Support initial ramdisks compressed using gzip




         对于initramfs,就可以不用在去配置file system下面的那些个文件系统选项,也可以去掉块设备里面列出的关于ramdisk的相关选项。


         这里是可以指定你的rootfs的目录的,内核会将其与img镜像编在一起, 生成的initramfs根文件系统镜像在Linux源码树的usr目录下。名字叫initramfs_data.cpio.gz,它是gz格式的压缩文件。我的一个6.6M的rootfs和2.5的img,合并之后只有大概5M左右,比较理想。这对于Flash大小敏感的项目来说,是一个很理想的选择。


         在作为前期内核调试的时候,这个方法应该是十分实用的,可以不要在去单独编译根文件系统。


         具体可以参照http://www.arm9home.net/simple/index.php?t5645.html



         相应的在uboot中的配置可以修改为


      1.  bootargs=root=/dev/ram0 rw console=ttyS0,115200 mem=64mb
      2.  bootcmd=mtdparts default; nand read 0x40008000 0x100000 0x800000; bootm 0x40008000;





           这里也就是只要读一个uImage就行了,已经包含了rootfs镜像了。