嵌入式Linux文件系统的构建

插图2: 文件系统体系结构
构建文件系统最基本的要求就是系统能够在此基础上启动运行起来,所以,/sbin下的init程序必不可少。init程序是引导过程完成后内核运行的第一个程序,它能启动全部其他程序。只要init完成运行全部必要的程序,系统就开始建立并开始运行。当程序开始启动时,init读取一个配置文件inittab,这个文件位于/etc下,它确定了init在启动和关机时的工作特性。在我们开发的这个嵌入式系统中,所有的文件内容只需保留与开发要求有关的必须部分。
这个系统运行单用户模式启动:启动后立即运行rc.sysinit脚本,进行系统初始化动作。rc.sysinit脚本也进行了精简,只保留了以读写的方式重新加载(mount)根文件系统的操作(内核启动时只以只读的方式加载了根文件系统),具体rc.sysinit脚本中的内容 如下:
# Remount the root filesystem read-write
# mount -n -o remount.rw / mount -o remount.rw -n/dev/mtdblock2/mount -a
为了开发过程用户与系统能进行交互,启动了/bin/bash这个命令解释器。用户在键盘上输入某些命令,bash将读取输入加以解析然后执行该程序。/tools中的telnetd和/sbin中的pppd分别是远程登陆和串口通讯的后台程序,加入它们也是为了方便开发。
另外,为了尽量精简内核,程序都以动态链接库文件的方式编译,即当程序运行到所需库文件时才动态加载。所以保证库文件的完整性就显得相当重要。为确保运行各种程序都能在/lib目录中找到合适的库文件,就干脆对/lib中的库文件不作任何删减,而完整的/lib目录(含子目录及全部库文件)也不过2MB 大小。
● 配置文件系统用户
这一步骤的实现,体现了该嵌入式操作系统的一大特色---安全性。为了防止系统中的文件被误改或被恶意破坏,我们设置组和用户,让只有隶属于特定组的特定用户才能对特定的程序进行合法操作。/etc目录中没有列入管理组的group文件和管理用户的pass wd文件,所以在设置文件或目录的所有权时,全部用id号来代替组名和用户名。用chown命令来改变文件的所有权,如chown 0.0 i nittab(前一个“0”代表属组,后一个“0”代表用户),修改后的inittab文件的详细信息为:-rw-r-r-- 1 0 0 237 Jul 26 l0:30 inittab
将系统中所有的文件和目录按照其具体类型和要求,为其设定特定的组和用户对它的所有权。例如,/etc中的module.conf配置文件的所有权是module组和module用户。那么只有组和用户同为module的程序(比如/lib/modules/中的程序)才有权查看module.c onf文件,其他非root用户的程序都打不开这个文件。这样,除了root用户,其他不具有操作权限的用户就不可能对那些特殊文件, 如有关网络、安全等重要信息进行执行和修改。而拥有root用户权限的文件只有init和bash两个。init用于完成系统的初始化过程,并不涉及对其他文件和程序的操作;bash是开发过程中用户与系统交互的需要,便于对文件系统进行修改,开发完成后的实际系统并不需要bash,可删除。这样,各个文件和程序均在自己所属的组和用户中运行,不会互相干扰。使得整个系统有条不紊,不会发生程序越权误操作的现象。保证了操作系统本身的安全性,也让试图窃取或破坏数据的攻击者无机可乘。
根据需要,在基本文件系统上添加应用程序基本文件系统完成后,再根据开发的实际要求,在上面再构筑一些应用和服务。例如,对于所需求的网络功能,我们在/bin 中加入netstat、ping,在/sbin中加入ifconfig、route、xinetd等网络程序:为了将一些服务以模块的方式加载,以缓解内核的负担 ,我们在/sbin中加入了insmod、lsmod、modprobe、depmod、rmmod等有关操作模块的命令。还有,为了搭建开发过程的交叉编译的环境,需要用到串口通讯,所以在/sbin中加入pppd的命令,在/etc中加入PPP目录及其配置文件等等。
到此,一个满足系统需求的嵌入式Linux文件系统就基本构造完成。为了系统能在特定的嵌入式硬件设备上运行,系统中所有的二进制文件都必须是经过特定的嵌入式开发编译工具编译,将编译好的文件系统烧至嵌入式系统的开发板中,调通串口,就可以进行调试和进一步的开发了。
嵌入式Linux 文件系统的进一步开发
按照上一部份给出的文件系统体系结构,文件系统的实现主要在VFS层、物理文件系统层和MTD层。在Linux 2.4以后的版本中,JFFS2已经作为一种标准的文件系统被支持,所以使得Linux的VFS支持JFFS2并不是一件难事,在源代码中也不用做修改。下面给出在MTD层,Linux的源代码做的一些修改。另外,叙述JFFS2物理文件系统映像文件的生成。
支持MTD设备
对MTD设备的支持要经过配置内核、编写设备驱动程序和建立MTD设备这几个步骤。
第一步,配置内核参数,选中Memory Technology Devices(MTD)support,下面的子项中至少要选择MTD partitioning support、Direct char device access to MTD devices和Caching block device access to MTD devices这三项。其他的有关NFTL,CFI的支持根据需要选取。
第二步,编写针对目标平台Flash设备的MTD驱动程序,主要实现创建MTD分区和删除MTD分区的函数。创建分区的流程见图3所示。删除分区的函数比较简单,如果存在MTD分区,就调用del_mtd_partitions(struct mtd info*)删除分区,并且删除为MTD设备创建的映射表。

插图3: 创建MTD分区
第三步,将修改过的MTD驱动文件作为内核文件的补丁,并给内核文件打上这个补丁,最后,编译生成内核文件。
第四步,使用mknod命令建立MTD设备。
JFFS2映象文件的生成
首先,需要内核支持JFFS2,因此在配置内核参数时,选中File Systems下的Journaling Flash File System v2(JFFS2)support。假设从一个RAMDISK的文件系统中得到建立根文件系统所需的全部文件和系统所有的设备等信息。制作步骤如下:
评论