450 likes | 632 Views
第七章 嵌入式文件系统移植与挂载. 主要内容. 7.1 嵌入式文件系统综述 7.2 Ramdisk 根文件系统 7.3 busybox 移植 7.4 添加系统文件 7.5 库编译方式 静态编译 动态编译 7.6 文件系统的引导与挂载 7.7 Ramdisk 制作. 7.1 嵌入式文件系统综述. 嵌入式文件系统: Ext2/ Ext3 Romfs Ramdisk Cramfs Jffs/jffs2 Tmpfs Yaffs 用户可以根据可靠性、健壮性和/或增强的功能的需求来选择文件系统的类型。. Linux 对文件系统的要求.
E N D
主要内容 • 7.1 嵌入式文件系统综述 • 7.2 Ramdisk根文件系统 • 7.3 busybox移植 • 7.4 添加系统文件 • 7.5 库编译方式 • 静态编译 • 动态编译 • 7.6 文件系统的引导与挂载 • 7.7 Ramdisk制作
7.1 嵌入式文件系统综述 • 嵌入式文件系统: • Ext2/ Ext3 • Romfs • Ramdisk • Cramfs • Jffs/jffs2 • Tmpfs • Yaffs • 用户可以根据可靠性、健壮性和/或增强的功能的需求来选择文件系统的类型。
Linux对文件系统的要求 • 要求文件系统在频繁的文件操作(例如,新建,删除,截断)下能够保持较高的读写性能,要求低碎片化。 • Linux下的日志文件系统(XFS,ReiserFS,Ext3等)能保持数据的完整性,但消耗过多系统资源,的弱点使之不能成为嵌入式系统中的主流应用。并且这些都是专门为硬盘这类的存储设备优化,对于flash这类的存储介质并不适用。 • 因为现有的嵌入式文件系统的碎片化的问题,大部分的嵌入式设备只给用户提供了只读文件系统,给用户带来不便。 • 嵌入式文件系统的载体是以Flash为主的存储介质,所以为了延长Flash的使用寿命,应该尽量减少对Flash的写入操作。 • 文件系统采用Direct I/O的话,使I/O效率明显降低,增加了写入次数;但采用延时写的话,虽然能够降低碎片问题,如果加入日志系统的话,又不能保证数据的安全性。这是一个矛盾。
PDA闪存类通常使用以下几种文件系统:CRAMFS、RAMFS、JFFS2、yaffs,有时也用EXT2,不过其效果欠佳。PDA闪存类通常使用以下几种文件系统:CRAMFS、RAMFS、JFFS2、yaffs,有时也用EXT2,不过其效果欠佳。
第二版扩展文件系统(Ext2fs) • Ext2fs 是 Linux 事实上的标准文件系统,它已经取代了它的前任 — 扩展文件系统(或 Extfs)。Extfs 支持的文件大小最大为 2 GB,支持的最大文件名称大小为 255 个字符 — 而且它不支持索引节点(包括数据修改时间标记)。
它的优点是:Ext2fs 支持达 4 TB 的内存。Ext2fs 文件名称最长可以到 1012 个字符。当创建文件系统时,管理员可以选择逻辑块的大小(通常大小可选择 1024、2048 和 4096 字节)。Ext2fs 了实现快速符号链接:不需要为此目的而分配数据块,并且将目标名称直接存储在索引节点(inode)表中。这使性能有所提高,特别是在速度上。
Ramdisk 文件系统 • Ramdisk是通过将计算机的 RAM 用作设备来创建和挂装文件系统的一种机制。 • 用 Ramdisk 挂装 Ext2fs通过使用 Ramdisk 的概念,可以在嵌入式设备中创建并挂装 Ext2 文件系统(以及用于这一目的的任何文件系统)。
RomFS文件系统 • uClinux系统多采用Romfs文件系统,Romfs是一种相对简单、占用空间较少的文件系统。空间的节约来自于两个方面:首先内核支持Romfs文件系统比支持ext2文件系统需要更少的代码;其次romfs文件系统相对简单,在建立文件系统超级块(Superblock)需要更少的存储空间。Romfs是只读的文件系统,禁止写操作,因此系统同时需要虚拟盘(RAMDISK)支持临时文件和数据文件的存储。 • 只读文件系统,可以放在ROM空间,也可以在系统的RAM中,嵌入式linux中常用来作根文件系统。
CRAMFS文件系统 • CRAMFS中的数据已被压缩,属于只读性文件系统,不能在闪存中修改。用户想获取数据时,CRAMFS先把数据送到RAM中,用户从RAM中读取。一般CRAMFS的上层为RAMFS文件系统,经修改过的文件都保存在RAM中。 • RAMFS和CRAMFS结合的缺陷在于,一旦出现掉电等特殊情况,保存在RAMFS中的修改数据将全部丢失。
JFFS2文件系统 • 为此Linux采用了新的文件系统-JFFS2,它允许在闪存中直接进行修改,在掉电时会自动保存数据。JFFS2的数据压缩方式和CRAMFS一样,其数据可存放在全部的闪存区域中,数据的写入和删除分布在很大一片区域中以防止同样的块会被重复使用。
MTD设备与JFFS文件系统 JFFS2是比较常用的嵌入式日志文件系统。JFFS2 因为有以下这些 优点而在无盘嵌入式设备中越来越受欢迎: • JFFS2 在扇区级别上执行闪存擦除/写/读操作要比 Ext2 文件系统好。 • JFFS2 提供了比 Ext2fs 更好的崩溃/掉电安全保护。当需要更改少量数据时,Ext2 文件系统将整个扇区复制到内存(DRAM)中,在内存中合并新数据,并写回整个扇区。这意味着为了更改单个字,必须对整个扇区(64 KB)执行读/擦除/写例程 ― 这样做的效率非常低。要是运气差,当正在 DRAM 中合并数据时,发生了电源故障或其它事故,那么将丢失整个数据集合,因为在将数据读入 DRAM 后就擦除了闪存扇区。JFFS2 附加文件而是重写整个扇区,并且具有崩溃/掉电安全保护这一功能。
MTD设备与JFFS文件系统 • 这可能是最重要的一点:JFFS2 是专门为象闪存芯片那样的嵌入式设备创建的,所以它的整个设计提供了更好的闪存管理。 • 除了JFFS2之外,另外一种的嵌入式文件系统的选择是YAFFS2。
Yaffs与jffs2文件系统比较 • Nand上yaffs文件系统的优势• 专门为Nand flash设计的日志文件系统,提供磨损平衡和调电恢复的鲁棒性。 Yaffs将文件组织成固定大小(512B)的数据段,在进行文件修改时,总是先写入新的数据块,然后将旧的的数据块从文件中删除。 • jffs/jffs2文件系统的缺点: •不适合大容量的Nand flash • jffs的日志通过jffs_node建立在RAM中,占用RAM空间:对于128MB的Nand大概需要4MB的空间来维护节点 • 启动的时候需要扫描日志节点,不适合大容量的Nand flash
tmpfs文件系统 当 Linux 运行于嵌入式设备上时, 设备就成为功能齐全的单元,许多守护进程会在后台运行并生成许多日志消息。另外,所有内核日志记录机制,象 syslogd、dmesg 和 klogd,会在 /var 和 /tmp 目录下生成许多消息。由于这些进程产生了大量数据,所以允许将所有这些写操作都发生在闪存是不可取的。由于在重新引导时这些消息不需要持久存储,所以这个问题的解决方案是使用 tmpfs。
tmpfs 是基于内存的文件系统,它主要用于减少对系统的不必要的闪存写操作这一唯一目的。因为 tmpfs 驻留在 RAM 中,所以写/读/擦除的操作发生在 RAM 中而不是在闪存中。因此,日志消息写入 RAM 而不是闪存中,在重新引导时不会保留它们。tmpfs 还使用磁盘交换空间来存储,并且当为存储文件而请求页面时,使用虚拟内存(VM)子系统。
tmpfs 的优点包括:a) 动态文件系统大小 — 文件系统大小可以根据被复制、创建或删除的文件或目录的数量来缩放。使得能够最理想地使用内存。b) 速度 — 因为 tmpfs 驻留在 RAM,所以读和写几乎都是瞬时的。即使以交换的形式存储文件,I/O 操作的速度仍非常快。 • tmpfs 的一个缺点是当系统重新引导时会丢失所有数据。因此,重要的数据不能存储在 tmpfs 上。
7.2 Ramdisk根文件系统 • RAM:内存,Disk:磁盘,在linux中可以将一部分内存当作分区来使用,称之为Ramdisk.对于一些经常被访问、并且不会被更改的文件,可以将它们通过Ramdisk放在内存中,能够明显地提高系统性能。 • Ramdisk工作于虚拟文件系统(VFS)层,不能格式化,但可以创建多个Ramdisk.虽然现在磁盘价钱越来越便宜,但对于一些我们想让其访问速度很高的情况下,Ramdisk还是很好用的。
Ramdisk应用 • 如果对计算机速度要求较高,可以通过增加内存来实现,使用ramdisk技术。一个Ramdisk就是把内存假设为一个磁盘驱动器,并且在它的上面存储文件。假设计有几个文件要频繁的使用,如果将它们加到内存当中,程序运行速度会大幅度提高,因为内存的读写速度远高于磁盘。划出部分内存提高整体性能,不亚于更换新的CPU。便WEB服务器这样的计算机,需要大量读取和交换特定的文件,因此,在WEB服务器上建立Ramdisk会大大提高网络读取速度。
Ramdisk优点与缺陷 • Ramdisk就是将内存模拟为磁盘空间。无论什么时候你使用Ramdisk,实际上你是在使用内存而不是硬盘。在这一点上既有优点又有缺点。 • 最基本的,最大的优点是你在使用内存,你所做的一切都会快一些,因为磁盘的速度较内存慢。最大的缺点是如果你改变了数据库服务器的内容并且重新启动机器时,所做的一切改动都将丢失。
7.3 busybox移植 • Busybox简介 • BusyBox 最初是由 Bruce Perens 在 1996 年为 Debian GNU/Linux 安装盘编写的。其目标是在一张软盘上创建一个可引导的 GNU/Linux 系统,这可以用作安装盘和急救盘。 • BusyBox 是按照 GNU General Public License(GPL)许可证发行的。这意味着如果我们在一个项目中使用 BusyBox,就必须遵守这个许可证。
Busybox简介 • 为了使用根文件系统,我们使用了Busybox,这个工具是一个单一映像,其中包含了很多在linux系统上通常可以找到的工具.Busybox的优点是它将很多工具打包成一个文件,同时还可以共享它们的通用元素,这样可以极大地减少映像文件的大小.这对于嵌入式系统来说非常理想.Busybox被称为”瑞士军刀”. • 将Busybox映像从自已的源目录中拷贝到自已的根目录下的,然后创建符号连接,它们都指向Busybox工具,Busybox会判断所调用的是哪个工具,并执行这个工具的功能.
busybox移植 • 1 下载最新的busybox源码 www.busybox.net处下载最新的源码包,目前最新稳定版本为busybox-1.10.1.tar.gz • 2 修改busybox/makefile,指定交叉编译器和编译平台. ARCH ?= arm CROSS_COMPILE ?= arm-none-linux-gnueabi- • 3 make menuconfig配置选项 进入到busybox/,执行make menuconfig
少数需要修改的配置选项如下 • Busybox Settings ---> Build Options ---> [*] Build BusyBox as a static binary (no shared libs) //(1) Installation Options ---> [*] Don't use /usr //(2)Linux System Utilities ---> [*] mdev //(3) [] Support /etc/mdev.conf [*] Support command execution at device addition/removalShells ---> Choose your default shell (msh) ---> //(4)
配置说明 • (1) 静态编译busybox时需要选上此选项(2) 这个选项也一定要选,否则make install后,busybox将安装在原系统的/usr下,这将覆盖掉系统原有的命令.选择这个选项后,make install后会在busybox目录下生成一个叫_install的目录,里面有busybox和指向他的链接.(3) 成功移植完内核后,由于没有启动udev,造成/dev下没有设备文件。也就是说所有的设备都没有挂接进来。最新的busybox已经包含了udev的简化版本即mdev,且使用非常简单。 要使用mdev还需要在根文件系统的配置文件中进行设置,具体方法附后。 • Support /etc/mdev.conf此选项应该除去,对mdev的配置可在rcS脚本文件中进行,如若不去掉此选项,系统启动时,会提示到不到//etc/mdev.conf而报错.(4) 由于ash功能不够强大,不能支持tab补齐,历史纪录等等的高级功能,所以使用busybox里面的msh代替ash.
配置完成后: Cd busybox • make.即可完成编译. • Make install 将根文件系统目录安装在busybox/_install目录 • busybox/_install下内容为: bin linuxrc sbin usr
查看busybox依赖的库 • #arm-none-linux-gnueabi-readelf –a busybox| grep “Shared library” • 0x00000001 (NEEDED) Shared library: [libcrypt.so.1] • 0x00000001 (NEEDED) Shared library: [libm.so.6] • 0x00000001 (NEEDED) Shared library: [libc.so.6] • 可以发现busybox依赖以上三个库,要特别注意的是,不仅要将此三个库拷到开发板/root/myroot/lib中,还应该继续用arm-none-linux-gnueabi-readelf查看这三个库又分别依赖哪些库,依此类推,直到没有依赖库为止.与此同时,应使用ls –l命令查看这些库文件分别与哪些库有链接,应该将以上查到的所有的依赖库和链接库拷过去才行!
7.4 添加系统文件 创建根文件系统目录 • $ mkdir /root/myroot • $ cd /root/myroot • $ mkdir lib var mnt home root dev etc tmp proc sys • $ chmod 1777 tmp • $ mkdir usr/bin usr/lib usr/sbin • $ mkdir var/lib var/run var/log • $ mkdir dev/pty dev/shm
创建设备文件 • 在devfs或udev启动前,内核引导需要用到一些尚未创建的设备文件,这就需要我们在内核尚未启动前创建好所必须的一些设备文件。 • $ cd /rootfs/dev • $ mknod –m 600 mem c 1 1 • $ mknod –m 666 null c 1 3 • $ mknod –m 666 zero c 1 5 • $ mknod –m 644 random c 1 8 • $ mknod –m 600 console c 5 1 • $ mknod –m 666 tty c 5 0 • (3) 将busybox/_install下的所有内容拷贝到/root/myroot • Cp –a busybox/_install /root/myroot
编写相关的配置文件 • 编写相关的配置文件 • /root/myroot /etc/inittab • / root/myroot /etc/init.d/rcS • / root/myroot /etc/profile • / root/myroot /etc/fstab • / root/myroot /etc/passwd
inittab 文件 • ::sysinit:/etc/rcS • /dev/ttyS0::askfirst:/bin/sh -l • ::restart:/sbin/init • ::shutdown:/bin/umount -al
fstab 文件 • proc /proc proc defaults 0 0 • sysfs /sys sysfs defaults 0 0 • tmpfs /tmp tmpfs defaults 0 0 • tmpfs /var tmpfs defaults 0 0
profile 文件 • export LD_LIBRARY_PATH=/lib:/usr/lib • export HOME=/root • # other • cd $HOME
rcS文件 • #!/bin/sh • mount -t tmpfs mdev /dev • mount -a • echo /sbin/mdev > /proc/sys/kernel/hotplug • mdev -s • hostname hjp270 • /home/bin/boa • insmod /home/module/gspca.ko
7.5 库编译方式 • 静态编译 • 动态编译
7.6 文件系统的引导与挂载 • NFS网络文件系统方式挂载 bootargs root=/dev/nfs rw nfsroot=192.168.1.66:/root/myroot mem=64M ip=192.168.1.98 init=/linuxrc console=ttyS0,115200 • 本地ramdisk挂载 bootargs root=/dev/ram initrd=a0800000,400000 init=/linuxrc console=ttyS0,115200 ip=192.168.1.98
7.7 Ramdisk制作 • dd if=/dev/zero of=ramdisk.image bs=1k count=8192 //生成一个8192KB大小的映像文件ramdisk.image,当把此文件mount到一个目录中的时候,使用df命令就可以看到此文件系统的使用情况——使用多少空间,剩余多少空间。 • mke2fs ramdisk.image //格式化刚制作的ramdisk.image • 格式化后的ramdisk.image,使用mount –o loop ramdisk.image /mnt后,里面只有lost+found目录, ramdisk.image.gz也就是按照以上步骤制作后,拷贝了编译器中提供的一些库,busybox及链接,可执行文件以及一些脚本文件后使用gzip压缩而成的。