文件 | 描述 |
---|---|
export | 用来配置NFS文件系统(可选) |
fstab | 用来指明当执行mount -a时需要挂载的文件系统(可选) |
mtab | 用来显示已经加载的文件系统(可选) |
ftpusers | 启动FTP时配置用户访问权限(可选) |
group | 用来配置NFS文件系统(可选) |
inittab | init进程配置文件(可选) |
ld.so.conf | 其他共享库的路径(可选) |
passwd | 密码文件(可选) |
系统启动后,使用以下命令挂接proc文件系统(常在/etc/fstab进行设置以自动挂接)
mount -t proc none /proc
一些需要生成临时文件的程序要用到/tmp目录,所 以/tmp目录必须存在并可以访问。
为减少对Flash的操作,当在/tmp目录上挂接内存文件系统 :
mount -t tmpfs none /tmp
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 :三种配置项
一般使用默认配置即可。
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 modutils
Simplified 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 variables
Support 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 usr
bin
、linuxrc
、sbin
以及usr
是安装后生成的内容
若uboot的环境变量bootargs
设置 init=/linuxrc
,则linuxrc
可以作为用户空间的init
程序
用户态空间的 init 程序是 busybox 来生成的
linux应用程序运行需要动态库或静态库,从安装生成目录来看,显然没有库文件,负责编译好的应用程序放到系统中也无法运行。所以要添加库文件。
在ubuntu下一般使用/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
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
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
上面复制的库文件并不是每个都会用到,可以根据应用程序的依赖关系保留需要用到的,以此来减小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
可以看出文件系统还存在问题。
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
格式
[file system> [mount point] [type] [options] [dump] [pass]
创建/etc/fstab 文件
proc /proc proc defaults 0 0
tmpfs /tmp tmpfs defaults 0 0
sysfs /sys sysfs defaults 0 0
格式:
[id]:[runlevels]:[action]:[process]
动作 | 描述 |
---|---|
sysinit | 在系统初始化的时候 process 才会执行一次 |
respawn | 当 process 终止以后马上启动一个新的 |
askfirst | 和 respawn 类似,在运行 process 之前在控制台上显示“Please press Enter to activate this console.”。只要用户按下“Enter”键以后才会执行 process |
wait | 告诉 init,要等待相应的进程执行完以后才能继续执行 |
once | 仅执行一次,而且不会等待 process 执行完成 |
restart | 当 init 重启的时候才会执行 process |
ctrlaltdel | 当按下 ctrl+alt+del 组合键才会执行 process |
shutdown | 关机的时候执行 process |
参考 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