根文件系统制作(二)
在前面已经把根文件系统所需要的文件、目录全部都制作好了,接下来讨论如何把它移植到嵌入式系统开发板上。
要把根文件系统的所有目录和文件移植到arm开发板上,需要一个名叫mtd.utils的工具软件,它可以直接到官网(ftp://ftp.infradead.org/pub/mtd-utils/)上去下载源码,同时还需要zlib库(http://zlib.net/)和lzo库(http://www.oberhumer.com/opensource/lzo/)的支持,另外还有utils-linux工具(https://mirrors.edge.kernel.org/pub/linux/utils/util-linux/)也需要下载。关于mtd.utils工具的具体制作方法有些复杂,请自行参考其它教程,这里就不再讨论了。
下面仍以硕数公司的S3C2416核心板为例来进行讨论,通过使用制作好的mtd.utils工具来对根文件系统进行移植。
首先参考前面的方法,使用SD卡把开发板启动起来,启动完成后执行“cd /opt/mtd-utils”进入该目录,可以看到该目录下就有制作好的mtd.utils工具。使用SD卡启动起来后的根文件系统是基于ramdisk的,它并没有使用NandFlash,所以完全可以使用mtd.utils工具来直接在NandFlash上制作UBIFS格式的根文件系统,下面就来讨论一下制作方法。
为了方便操作,可先把前面制作好的根文件系统打成一个包,在虚拟机下进入到根目录,然后执行“tar -zcvf rootfs.tar.gz /rootfs”,其中rootfs.tar.gz是要生成的打包文件,“/rootfs”是根文件系统所在的目录。完成后就会在根目录下生成rootfs.tar.gz文件,把这个文件拷贝到用于启动开发板的SD卡上,就可以进行移植了。接着使用这张SD卡把开发板上的Linux启动进来,然后进入到/opt/mtd-utils目录下,按以下步骤进行操作。
首先执行“./flash_eraseall /dev/mtd2”,把根文件系统所在分区的内容全部擦除掉。其中,flash_eraseall是mtd-utils目录下的一个可执行程序,“/dev/mtd2”指的就是根文件系统所在的分区(mtd0为UBoot分区、mtd1为Kernel分区)。然后执行“./ubiattach /dev/ubi_ctrl -m 2”,同样ubiattach也是一个可执行程序,它用于链接MTD设备(MTD设备描述原始Flash设备)到UBI并且创建相应的UBI设备(相反的程序是ubidetach)。其中“/dev/ubi_ctrl”是一个设备节点文件,如果没有可执行“mknod /dev/ubi_ctrl c 10 63”来创建它,“-m 2”是指attach的是mtd2分区。ubiattach执行完后的效果如下图所示。
完成后接着执行“./ubimkvol /dev/ubi0 -N rootfs -s 100MiB”,同样ubimkvol也是一个可执行程序,它用于创建一个卷(相反的程序是ubirmvol),卷才是最终用户挂载文件系统的地方,其中“/dev/ubi0”也是一个设备节点,它是在执行上一步ubiattach时被创建出来的,“-N”是后面跟的是此卷的名称,“-s”后面跟的是大小。ubimkvol执行完后的效果如下图所示。
完成后就可以执行挂载命令了。先执行“mkdir -p /tmp/nand”创建一个挂载点,然后执行“mount -t ubifs /dev/ubi0_0 /tmp/nand”进行挂载,其中“/dev/ubi0_0”是一个设备节点,它是在执行上一步ubimkvol时被创建出来的,“-t ubifs”是指挂载的文件系统为UBIFS形式,挂载完后的效果如下图所示。
至此,操作/tmp/nand目录就是操作根文件系统分区mtd2了,这就方便多了,下一步只需要把前面制作好的根文件系统拷贝过来即可。
执行“cd /mnt/sd”进入到SD卡的目录,确认一下rootfs.tar.gz文件存在(若没有内容可能需要重新挂载下SD卡),然后执行“tar -zxvf rootfs.tar.gz -C /tmp/nand”,“-C”是指把根文件系统解压到后面的“/tmp/nand”目录下。完毕后就可进入到“/tmp/nand”目录下查看一下,可见多了一个rootfs的目录,这就是解压后的目录,进入该目录就可以看到前面制作的根文件系统的目录和文件了。当然,制作好的根文件系统rootfs目录也可以通过NFS方式进行拷贝,这样就省去了打包和解压的过程,只不过在拷贝时要加上参数“-d”,以避免在拷贝过程中busybox的链接文件被破坏。
完成后还需要把根文件系统移动一下,因为前面在挂载ubi0_0(UBIFS卷)时是挂载到“/tmp/nand”目录下的,而目前在nand目录下还多出了一个rootfs的目录,所以需要执行一下命令“mv /tmp/nand/rootfs/* ../”,把rootfs下的所有文件和目录都移动到nand目录下(即rootfs分区下),然后再执行“rm -fr /tmp/nand/rootfs”把rootfs目录删除。最后执行“sync”命令同步一下NandFlash即可。
上述全部完成后,可执行“umount /tmp/nand”命令进行反挂载,然后执行“poweroff”关机命令,完成后给开发板断电,去除SD卡并跳线到NandFlash启动,随后给开发板上电。可看到启动完成后,开发板就进入到了console界面,且从中可以看到,基于UBIFS的根文件系统已经挂载成功了。插入一张SD卡,然后再拔出,再插入一个U盘,然后再拔出,从显示中可以看出,都实现了外存储器的自动挂载和反挂载,执行ls命令,可看到整个完整的根文件目录,如下图所示。
至此,整个基于UBIFS的根文件系统移植完毕。
当然,除了直接在NandFlash上制作根文件系统之外,也可能通过映像烧写的方式来制作UBIFS格式的根文件系统,这同样需要借助mtd-utils工具来实现。下面就来讨论一下这种方法。
要制作根文件系统映像,需要mkfs.ubifs和ubinize两个工具,其中mkfs.ubifs是用来将某个文件夹制作为UBIFS映像文件的,制作出的映像可在U-Boot下使用“ubi write”命令烧写到NandFlash上。但是,一般的U-Boot都不具备这个命令,因此还需要使用ubinize这个工具来把刚才生成的UBIFS映像文件转换成为通用的、可直接烧写在NandFlash上的格式(带有UBI文件系统镜像卷标)。下面就具体来看。
首先使用mkfs.ubifs工具将根文件系统目录rootfs制作成UBIFS映像,执行以下命令:
mkfs.ubifs -r /rootfs -m 2048 -e 126976 -c 992 -o ubifs.img
以上命令将/rootfs目录内容制作成UBIFS形式的映像文件,文件名为ubifs.img。其中,参数“-r”指定了根文件系统所在的目录,参数“-m”指定了最小I/O操作的大小,也就是NandFlash中一个页(page)的大小,参数“-e”指定了逻辑擦除快的大小,参数“-c”指定了最大的逻辑块号,参数“-o”指定输出文件的名称。
接下来使用ubinize工具把刚才生成的ubifs.img映像文件转换成为通用的Flash烧写格式,执行以下命令:
ubinize -o ubi.img -m 2048 -p 128KiB -s 512 -O 2048 ubinize.cfg
上述命令中的ubinize.cfg是一个配置文件,其内容如下:
[ubifs]
mode=ubi
image=ubifs.img
vol_id=0
vol_size=100MiB
vol_type=dynamic
vol_alignment=1
vol_name=rootfs
vol_flags=autoresize
该文件指明了要转换文件的名称及其他一些配置参数。其生成的UBIFS形式的根文件系统映像ubi.img就可在U-Boot下使用通用的“nand write”命令来进行烧写了。
在以上操作中要说明两点:一是两个工具命令mkfs.ubifs和ubinize都是mtd-utils下的可执行程序,但由于此时是在虚拟机下使用,所以在制作该命令时不要进行交叉编译,否则mkfs.ubifs和ubinize只能运行在ARM开发板系统下;二是命令使用中涉及到的参数要根据开发板所使用的NandFlash来具体确定。如果弄不清楚,还是推荐使用前面直接在NandFlash上建立根文件系统的形式进行移植。