Linux根文件系统结构
etc下存在的配置文件:
系统启动后,使用以下命令挂接proc文件系统(常在/etc/fstab进行设置以自动挂接)
mount -t proc none /proc一些需要生成临时文件的程序要用到/tmp目录,所 以/tmp目录必须存在并可以访问。 为减少对Flash的操作,当在/tmp目录上挂接内存文件系统 :
mount -t tmpfs none /tmp BusyBox源码下载BusyBox
制作BusyBox根文件系统
所谓制作根文件系统,就是创建各种目录,并且在里面创建各种文件。比如在/bin、/sbin目录下存放各种可执行程序,在/etc目录下存放配置文件,在/lib目录下存放库文件。这节讲述如何使用Busybox来创建/bin、/sbin等目录下的可执行文件。
创建根文件系统存放目录:
cd nfs mkdir rootfs开发中一般nfs挂载进行测试文件系统,所以将目录建立在nfs下
直接修改根目录下的Makefile,防止查找编译工具链出错:
VERSION = 1 PATCHLEVEL = 29 SUBLEVEL = 0 EXTRAVERSION = NAME = Unnamed ARCH ?= arm CROSS_COMPILE ?= /usr/local/arm-gcc/gcc-linaro-4.9.4-2017.01-i686_arm-linux-gnue$测试发现在make编译添加ARCH和CROSS_COMPILE的定义还是编译出问题,编译成了x86架构的,所以这里直接修改Makefile直接定义ARCH和CROSS_COMPILE。
编译安装参考源码的INSTALL文件:
Building: ========= The BusyBox build process is similar to the Linux kernel build: make menuconfig # This creates a file called ".config" make # This creates the "busybox" executable make install # or make CONFIG_PREFIX=/path/from/root install The full list of configuration and install options is available by typing: make help ... ...修改busybox支持中文字符:libbb/printable_string.c、libbb/unicode.c
修改printable_string.c的printable_string函数,将以下语句
/* 汉字字符肯定大于0x7F,当字符大于 0X7F 以后就跳出去了,不进行操作 */ if (c >= 0x7f) break; /* 汉字字符肯定大于0x7F,如果支持 UNICODE 码的话,当字符大于 0X7F 就直接输出‘?’,汉字必定显示不了*/ if (c < ' ' || c >= 0x7f) *d = '?';改成如下
/* 当字符大于 0X7F 以后就跳出去了,注释掉该语句即可 */ /* if (c >= 0x7f) break; */ /* 如果支持 UNICODE 码的话,当字符大于 0X7F 就直接输出‘?’,那改成大于0x7F还输出即可 */ /* if (c < ' ' || c >= 0x7f) */ if (c < ' ') *d = '?';从代码看会发现,如果字符大于0x7f就会跳出循环停止操作以及如果支持UNICODE编码,字符大于0x7f就会输出’?',汉字字符肯定大于0x7F,所以汉字必定不会显示 。
修改unicode.c的unicode_conv_to_printable2函数,将以下语句
*d++ = (c >= ' ' && c < 0x7f) ? c : '?'; if (c < ' ' || c >= 0x7f) *d = '?';改成如下
*d++ = (c >= ' ') ? c : '?'; if (c < ' ') *d = '?';编译前也需要配置busybox :三种配置项
defconfig, 默认配置allyesconfig,全选配置,即选中BusyBox所有功能allnoconfig,最小配置一般使用默认配置即可。
make defconfig make menuconfig /* BusyBox也支持图形化配置 */需要取消或设置的一些选项:
Settings ---> --- Build Options [ ] Build static binary (no shared libs)取消Build static binary (no shared libs)静态编译,默认是不选中的。动态编译出来的库会静态编译的小 采用静态编译的 DNS 会出问题,无法进行域名解析
勾选vi-style line editing commands
Settings ---> [ ] vi-style line editing commands启用vi样式的行编辑。 在shell中,该模式可以是用“set -o vi”和“set +o vi”打开或关闭功能。
取消Simplified modutils
Linux Module Utilities ---> [*] Simplified modutilsSimplified modutils默认会选中,需要取消
确保 mdev选项以及其子选项被选中
Linux System Utilities ---> [*] mdev (16 kb) [*] Support /etc/mdev.conf [*] Support subdirs/symlinks [*] Support regular expressions substitutions when renaming device [*] Support command execution at device addition/removal [*] Support loading of firmware默认都是被选中的。
使能unicode 编码支持,确保选中 Support Unicode 和Check $LC_ALL, $LC_CTYPE and $LANG environment variables
Settings ---> [*]Support Unicode [*] Check $LC_ALL, $LC_CTYPE and $LANG environment variablesSupport Unicode默认是选中。
其他配置选项根据需要进行配置。
编译:
ares@ubuntu:~/nfs/rootfs/busybox-1.29.1$ cat build_busybox.sh #!/bin/bash make ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- -j8安装:
ares@ubuntu:~/nfs/rootfs/busybox-1.29.1$ cat install_busybox.sh #!/bin/bash make install CONFIG_PREFIX=/home/ares/nfs/rootfs aares@ubuntu:~/nfs/rootfs$ ls bin linuxrc sbin usrbin、linuxrc、sbin以及usr是安装后生成的内容 若uboot的环境变量bootargs 设置 init=/linuxrc,则linuxrc可以作为用户空间的init程序
用户态空间的 init 程序是 busybox 来生成的
向rootfs添加lib库linux应用程序运行需要动态库或静态库,从安装生成目录来看,显然没有库文件,负责编译好的应用程序放到系统中也无法运行。所以要添加库文件。
在ubuntu下一般使用/lib和/usr/lib存放库文件。
创建lib和usr/lib ares@ubuntu:~/nfs/rootfs$ mkdir lib ares@ubuntu:~/nfs/rootfs$ ls bin lib linuxrc sbin usr ares@ubuntu:~/nfs/rootfs/usr$ mkdir lib ares@ubuntu:~/nfs/rootfs/usr$ ls bin lib sbin 拷贝库文件到rootfs中 ares@ubuntu:/usr/local/arm_gcc/gcc-linaro-4.9.4-2017.01-i686_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib$ sudo cp *so* *.a /home/ares/nfs/rootfs/lib/ -d -d,表示保留链接文件属性 ares@ubuntu:/usr/local/arm_gcc/gcc-linaro-4.9.4-2017.01-i686_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/usr/lib$ sudo cp *so* *.a /home/ares/nfs/rootfs/usr/lib/ -d这些库文件中有个特殊文件:
guangjie@ubuntu:/usr/local/arm-gcc/gcc-linaro-4.9.4-2017.01-i686_arm-linux-gnueabihf/arm-linux-gnueabihf/libc/lib$ ls ld-linux-armhf.so.3 -l lrwxrwxrwx 1 11827 9000 24 Feb 1 2017 ld-linux-armhf.so.3 -> ld-2.19-2014.08-1-git.so ld-linux-armhf.so.3 ,是链接文件上面复制的库文件并不是每个都会用到,可以根据应用程序的依赖关系保留需要用到的,以此来减小rootfs的空间占用。 通过ldd命令可以查看应用程序依赖关系,但主机的ldd命令架构和嵌入式的架构一般不同,无法查看。
guangjie@ubuntu:~/nfs/rootfs$ ldd hello linux-vdso.so.1 (0x00007ffeacad9000) libc.so.6 => /lib/x86_64-linux-gnu/libc.so.6 (0x00007f5265cd1000) /lib64/ld-linux-x86-64.so.2 (0x00007f52662c4000) 嵌入式平台查看依赖关系方法 arm-linux-gnueabihf-readelf -a "your binary" | grep "Shared"如
guangjie@ubuntu:~/nfs/rootfs$ arm-linux-gnueabihf-readelf -a hello | grep "Shared" 0x00000001 (NEEDED) Shared library: [libc.so.6] 查看库大小 ares@ubuntu:~/nfs/rootfs$ du ./lib/ ./usr/lib/ -sh 57M ./lib/ 67M ./usr/lib/创建目录
busybox编译后安装已经生成bin、sbin、usr三个目录。需要手动添加其他目录。 如dev、proc、mnt、sys、tmp 、root等
打包 sudo tar -vcjf busybox_rootfs.tar.bz2 * 初步测试启动信息:
VFS: Mounted root (ext3 filesystem) on device 179:2. devtmpfs: mounted Freeing unused kernel memory: 400K (8090e000 - 80972000) hub 1-1:1.0: USB hub found hub 1-1:1.0: 2 ports detected can't run '/etc/init.d/rcS': No such file or directory Please press Enter to activate this console. / # ls bin hello linuxrc proc sys dev hello.c lost+found root tmp driver lib mnt sbin us从can't run '/etc/init.d/rcS': No such file or directory可以看出文件系统还存在问题。
完善rootfs 创建/etc/init.d/rcS 文件
rcS是个shell脚本文件,可以在其中指定linux启动后需要自动启动的服务
创建脚本/etc/init.d/rcS
#!/bin/sh PATH=/sbin:/bin:/usr/sbin:/usr/bin:$PATH # 将命令路径保存到环境变量中 LD_LIBRARY_PATH=$LD_LIBRARY_PATH:/lib:/usr/lib # 保存库文件到环境变量 export PATH LD_LIBRARY_PATH # 导出环境变量,使全局可见 mount -a # mount 命令来挂载所有的文件系统 文件系统由文件/etc/fstab mkdir /dev/pts # 创建目录/dev/pts mount -t devpts devpts /dev/pts # 将 devpts 挂载到/dev/pts 目录 echo /sbin/mdev > /proc/sys/kernel/hotplug # 使用mdev来管理热插拔设备,使可以自动创建设备节点 mdev -s #使用 mdev 来管理热插拔设备赋予脚本可执行权限
sudo chmod 777 rcS 创建/etc/fstab 文件格式
[file system> [mount point] [type] [options] [dump] [pass] [file system] 要挂载的特殊的设备,也可以是块设备[mount point] , 挂载点[type] 文件系统类型,比如 ext2、ext3、proc、romfs、tmpfs 等[options] 挂载选项,主机man mount可以查看挂载选项[dump],为 1 的话表示允许备份,为 0 不备份,一般不备份,因此设置为 0[pass],磁盘检查设置, 0 表示不检查。根目录‘/’设置为 1,其他的都不能设置为 1,其他的分区从 2 开始。一般不在 fstab 中挂载根目录,故一般设置为 0创建/etc/fstab 文件
proc /proc proc defaults 0 0 tmpfs /tmp tmpfs defaults 0 0 sysfs /sys sysfs defaults 0 0 创建/etc/inittab 文件格式:
[id]:[runlevels]:[action]:[process] [id],每个指令的标识符,不能重复。对于 busybox 的 init 来说,id有着特殊意义,一般用来指定启动进程的控制 tty,一般我们将串口或者 LCD 屏幕设置为控制 tty[runlevels],对 busybox 来说此项无用,空着[action],动作,用于指定可能用到的动作参考 busybox 的 examples/inittab 文件,创建自己的inittab文件:
::sysinit:/etc/init.d/rcS # 系统启动后运行/etc/init.d/rcS脚本 console::askfirst:-/bin/sh # console 作为控制台终端,也就是 ttymxc0 ::restart:/sbin/init # 重启的话运行/sbin/init ::ctrlaltdel:/sbin/reboot # 按下 ctrl+alt+del 组合键执行/sbin/reboot重启系统 ::shutdown:/bin/umount -a -r # 关机执行/bin/umount,也就是卸载各个文件系统 ::shutdown:/sbin/swapoff -a # 关机执行/sbin/swapoff,也就是关闭交换分区测试根文件系统
执行测试程序:
/ # ./hello hello world创建中文文件:
/ # touch 网盘aig挤干净i宁、.txt / # / # / # ls bin lost+found busybox_rootfs.tar.bz2 mnt dev proc driver root etc sbin hello sys hello.c tmp lib usr linuxrc 网盘aig挤干净i宁、.txt
1.本站遵循行业规范,任何转载的稿件都会明确标注作者和来源;2.本站的原创文章,会注明原创字样,如未注明都非原创,如有侵权请联系删除!;3.作者投稿可能会经我们编辑修改或补充;4.本站不提供任何储存功能只提供收集或者投稿人的网盘链接。 |