在上篇博客中讲解了制作根文件系统其实就是在分区中创建目录以及在各个目录中实现系统启动时必要的文件,在嵌入式中通常会使用busybox来制作根文件系统。因为busybox集合了很多命令、以及各种文件,可以非常方便地帮助开发人员实现一些必须的文件。busybox的下载地址。
busybox中集成了几百个命令,在一般系统中并不需要全部使用,所以可以通过配置busybox来选择这些命令、指定某些命令的功能、指定busybox的连接方法以及指定busybox的安装路径。
①配置busybox,在busybox的顶层目录中执行“make menuconfig”命令可以进入配置界面。
busybox setting----->
busybox liarary tuning --->
[*]tab completion /*设置TAB键补全*/
archival utilities----->各种压缩解压缩工具。
Linux module utilities----> 使用可加载模块。
Linux system utilities ---->支持mdev,这个可以很方便的构造/dev目录,并且可以支持热插拔设备。
②编译安装busybox,在上述配置后,执行make ARCH= ARM CROSS_COMPILE = arm-linux- (没有gcc后缀)可以编译以及安装在指定的目录下。要是在配置时没有指定安装的路径需要执行 make ARCH=arm CROSS_COMPILE=arm-linux- CONFIG_PREFIX=dir(指定目录)。编译成功后会在指定的目录中生成除了bin/busybox外,其它文件都是到bin/busybox的符号连接。
③使用glibc库构建根文件系统,交叉编译工具链里面有glibc库。交叉编译工具链中的glibc库的位置是:*/libc/usr/lib下,里面存放的文件可以分为:①加载器,如ld-2.3.6.so、ld-linux.so.2,动态程序启动前,它们被用来加载动态库。②目标文件(.o),如ctrl.o,在生成应用程序时,这些文件像一般的目标文件一样被连接。③静态库文件(.a),编译静态程序时会连接它们。④动态库文件(.so、.so.[0-9]*),编译动态程序时会用到这些文件。⑤libtool库文件(.la),在连接库文件时,这些文件会被用到,程序运行时无需这些文件。⑥gconv里面是有字符集的动态库⑦ldscripts目录,里面存放各种连接脚本,编译应用程序时使用。
开发板上只需要加载器和动态库,所以构建lib库时只需要把动态库文件以及加载器复制过去就可以。动态库根据应用程序对库的依赖来选择库文件。可以使用arm-linux-readelf -a "your binary" | grep "Shared"命令来查询依赖的库文件或者使用ldd.host 程序名 来查找依赖的库文件。
busybox会生成/bin 、/sbin、/usr/bin/、/usr/sbin 目录文件,加上上述移植了/lib库文件,基本上最小根文件系统大部分文件目录、文件已经建好。还剩下配置文件、设备文件以及其它目录文件。
④构建etc目录(主要文件有inittab、init.d/rcS、fstab),init进程根据/etc/inittab文件来创建其他子进程。
inittab可以仿照busybox中的example/inittab文件。init.d/rcS文件,是一个脚本文件,可以在里面添加自动执行的命令,如配置IP地址、挂载/ect/fstab指定的文件系统(mount -a)。fstab文件格式如下:
#device mount-point type options dump fsck order
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
fsck程序根据fsck order字段来决定磁盘的检查顺序,0表示忽略这个文件系统。
⑤构建dev目录,可以使用最原始的方法处理设备,在/dev目录下静态创建各种节点。也可以使用mdev创建设备文件,mdev是udev的简化版本,通过读取内核信息来创建设备文件。mdev主要用途有两个:初始化/dev目录、动态更新。支持热插拔。要使用mdev,需要内核支持sysfs文件系统,为了减少对flash的读写,还要支持tmpfs文件系统。先确保内核已经设置了CONFIG_SYSFS、CONFIG_TMPFS配置选项。
要在内核启动时,自动运行mdev,需要修改etc/fstab来自动挂载文件系统:
还需要修改init.d/rcS加入自动运行命令:
⑥在创建自己需要的目录如mnt root home tmp sys proc 等。
note:mdev是通过init进程来启动的,在使用mdev构造/dev之前,init进程至少要用到设备文件/dev/console、/dev/null所以这两个设备文件需要自己手动创建。
根文件系统制作好了,还需要把它制作为一个文件,即映像文件,才能烧写到存储设备上去。