Linux使用busybox构建文件系统

准备工作

1.打开busybox官网

从官网地址下载busybox源码,官网地址为: https://busybox.net/
Linux使用busybox构建文件系统_第1张图片

2.选择版本下载

Linux使用busybox构建文件系统_第2张图片

3.解压缩

使用如下命令创建名为 rootfs 的子目录:

mkdir rootfs

创建好的 rootfs 子目录就用来存放我们的根文件系统了。
将 busybox-1.29.0.tar.bz2 发送到 Ubuntu 中,存放位置大家随便选择。然后使用如下命令将
其解压:

tar -vxjf busybox-1.29.0.tar.bz2

解压完成以后进入到 busybox-1.29.0 目录中,此目录中的文件和文件夹如下图所示:
Linux使用busybox构建文件系统_第3张图片

makefile和支持中文配置

1. 修改 Makefile,添加编译器

同 Uboot 和 Linux 移植一样,打开 busybox 的顶层 Makefile,添加 ARCH 和 CROSS_COMPILE
的值,如下所示:

CROSS_COMPILE ?= /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-
......
ARCH ?= arm

注意: CORSS_COMPILE 使用了绝对路径!主要是为了防止编译出错.

2.取消 busybox 对中文显示的限制

因为直接使用源码会使中文乱码,所以我们需要修改 busybox 源码,取消 busybox 对中文显示的限制,
打开文件 busybox-1.29.0/libbb/printable_string.c,找到函数 printable_string,缩减后的函数内容如下:

12 const char* FAST_FUNC printable_string(uni_stat_t *stats, const char
*str)
13 {
14 char *dst;
15 const char *s;
16
17 s = str;
18 while (1) {
......
30 if (c < ' ')
31 break;
32 /* 注释掉下面这个两行代码 */
33 /* if (c >= 0x7f)
34 break; */
35 s++;
36 }
37
38 #if ENABLE_UNICODE_SUPPORT
39 dst = unicode_conv_to_printable(stats, str);
40 #else
41 {
42 char *d = dst = xstrdup(str);
43 while (1) {
44 unsigned char c = *d;
45 if (c == '\0')
46 break;
47 /* 修改下面代码 */
48 /* if (c < ' ' || c >= 0x7f) */
49 if( c < ' ')
50 *d = '?';
51 d++;
52 }
......
59 #endif
60 return auto_string(dst);
61 }

接着打开文件 busybox-1.29.0/libbb/unicode.c,找到如下内容:

1003 static char* FAST_FUNC unicode_conv_to_printable2(uni_stat_t
*stats, const char *src, unsigned width, int flags)
1004 {
1005 char *dst;
1006 unsigned dst_len;
1007 unsigned uni_count;
1008 unsigned uni_width;
1009
1010 if (unicode_status != UNICODE_ON) {
1011 char *d;
1012 if (flags & UNI_FLAG_PAD) {
1013 d = dst = xmalloc(width + 1);
......
1022 /* 修改下面一行代码 */
1023 /* *d++ = (c >= ' ' && c < 0x7f) ? c : '?'; */
1024 *d++ = (c >= ' ') ? c : '?';
1025 src++;
1026 }
1027 *d = '\0';
1028 } else {
1029 d = dst = xstrndup(src, width);
1030 while (*d) {
1031 unsigned char c = *d;
1032 /* 修改下面一行代码 */
1033 /* if (c < ' ' || c >= 0x7f) */
1034 if(c < ' ')
1035 *d = '?';
1036 d++;
1037 }
1038 }
......
1044 return dst;
1045 }
......
1047
1048 return dst;
1049 }

3、配置 busybox

根我们编译 Uboot、 Linux kernel 一样,我们要先对 busybox 进行默认的配置,有以下几种
配置选项:
①、 defconfig,缺省配置,也就是默认配置选项。
②、 allyesconfig,全选配置,也就是选中 busybox 的所有功能。
③、 allnoconfig,最小配置。
我们一般使用默认配置即可,因此使用如下命令先使用默认配置来配置一下 busybox:
make defconfig
busybox 也支持图形化配置,通过图形化配置我们可以进一步选择自己想要的功能,输入
如下命令打开图形化配置界面:
make menuconfig
打开以后如下图所示:
Linux使用busybox构建文件系统_第4张图片

4.具体配置

1.静态编译配置

配置路径如下:

Location:
-> Settings
-> Build static binary (no shared libs)

选项“Build static binary (no shared libs)”用来决定是静态编译 busybox 还是动态编译,静
态编译的话就不需要库文件,但是编译出来的库会很大。动态编译的话要求根文件系统中有库
文件,但是编译出来的 busybox 会小很多。这里我们不能采用静态编译!因为采用静态编译的
话 DNS 会出问题!无法进行域名解析,配置如下图所示:
Linux使用busybox构建文件系统_第5张图片

2. vi配置

继续配置如下路径配置项:

Location:
-> Settings
-> vi-style line editing commands

结果如下图所示:
Linux使用busybox构建文件系统_第6张图片

3.Simplified modutils配置

继续配置如下路径配置项:
Location:
-> Linux Module Utilities
-> Simplified modutils
默认会选中“Simplified modutils”,这里我们要取消勾选!!结果如下图所示:
Linux使用busybox构建文件系统_第7张图片

4.System Utilities配置

继续配置如下路径配置项:
Location:
-> Linux System Utilities
-> mdev (16 kb) //确保下面的全部选中,默认都是选中的
结果如下图所示:
Linux使用busybox构建文件系统_第8张图片

5. 使能 busybox 的 unicode 编码以支持中文

最后就是使能 busybox 的 unicode 编码以支持中文,配置路径如下:

Location:
-> Settings
	-> Support Unicode //选中
	-> Check $LC_ALL, $LC_CTYPE and $LANG environment variables //选中

结果如下图所示:
Linux使用busybox构建文件系统_第9张图片

5.其它配置

根据自己需求进行合理配置。

5. 编译 busybox

配置好 busybox 以后就可以编译了,我们可以指定编译结果的存放目录,我们肯定要将编
译结果存放到前面创建的 rootfs 目录中,输入如下命令:

make
make install CONFIG_PREFIX=/home/user/linux/nfs/rootfs

CONFIG_PREFIX 是指定编译出来的根文件系统存放位置。
编译结果如下:
Linux使用busybox构建文件系统_第10张图片
生成的目录内容如下:
在这里插入图片描述
从图中可以看出, rootfs 目录下有 bin、 sbin 和 usr 这三个目录,以及 linuxrc 这个文
件。前面说过 Linux 内核 init 进程最后会查找用户空间的 init 程序,找到以后就会运行这个用
户空间的 init 程序,从而切换到用户态。如果 bootargs 设置 init=/linuxrc,那么 linuxrc 就是可以
作为用户空间的 init 程序,所以用户态空间的 init 程序是 busybox 来生成的。
busybox 的工作就完成了,但是此时的根文件系统还不能使用,还需要一些其他的文件,

6.完善 rootfs

1 创建/etc/init.d/rcS 文件

rcS 是个 shell 脚本, Linux 内核启动以后需要启动一些服务,而 rcS 就是规定启动哪些文件的脚本文件。在 rootfs 中创建/etc/init.d/rcS 文件,然后在 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
mkdir /dev/pts
mount -t devpts devpts /dev/pts
echo /sbin/mdev > /proc/sys/kernel/hotplug
mdev -s

第 1 行,表示这是一个 shell 脚本。
第 3 行, PATH 环境变量保存着可执行文件可能存在的目录,这样我们在执行一些命令或
者可执行文件的时候就不会提示找不到文件这样的错误。
第 4 行, LD_LIBRARY_PATH 环境变量保存着库文件所在的目录。
第 5 行,使用 export 来导出上面这些环境变量,相当于声明一些“全局变量”。
第 7 行,使用 mount 命令来挂载所有的文件系统,这些文件系统由文件/etc/fstab 来指定,
所以我们一会还要创建/etc/fstab 文件。
第 8 和 9 行,创建目录/dev/pts,然后将 devpts 挂载到/dev/pts 目录中。
第 11 和 12 行,使用 mdev 来管理热插拔设备,通过这两行, Linux 内核就可以在/dev 目录下自动创建设备节点。

创建好文件/etc/init.d/rcS 以后一定要给其可执行权限!
使用如下命令给予/ec/init.d/rcS 可执行权限:

chmod 777 rcS

设置好以后就重新启动 Linux 内核.

2.创建/etc/fstab 文件

在 rootfs 中创建/etc/fstab 文件, fstab 在 Linux 开机以后自动配置哪些需要自动挂载的分区,
格式如下:

:要挂载的特殊的设备,也可以是块设备,比如/dev/sda 等等。
:挂载点。
:文件系统类型,比如 ext2、 ext3、 proc、 romfs、 tmpfs 等等。
:挂载选项,在 Ubuntu 中输入“man mount”命令可以查看具体的选项。一般使用 defaults,也就是默认选项, defaults 包含了 rw、 suid、 dev、 exec、 auto、 nouser 和 async。
:为 1 的话表示允许备份,为 0 不备份,一般不备份,因此设置为 0。
:磁盘检查设置,为 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

fstab 文件创建完成以后重新启动 Linux.

3.创建/etc/inittab 文件

inittab 的详细内容可以参考 busybox 下的文件 examples/inittab。 init 程序会读取/etc/inittab
这个文件, inittab 由若干条指令组成。每条指令的结构都是一样的,由以“:”分隔的 4 个段组成,格式如下:
:::
:每个指令的标识符,不能重复。但是对于 busybox 的 init 来说, 有着特殊意义。
对于 busybox 而言用来指定启动进程的控制 tty,一般我们将串口或者 LCD 屏幕设置为控
制 tty。
: 对 busybox 来说此项完全没用,所以空着。
:动作,用于指定可能用到的动作。 busybox 支持的动作如表所示:

创建一个/etc/inittab,在里面输入如下内容:

#etc/inittab
::sysinit:/etc/init.d/rcS
console::askfirst:-/bin/sh
::restart:/sbin/init
::ctrlaltdel:/sbin/reboot
::shutdown:/bin/umount -a -r
::shutdown:/sbin/swapoff -a

第 2 行,系统启动以后运行/etc/init.d/rcS 这个脚本文件。
第 3 行,将 console 作为控制台终端,也就是 ttymxc0。
第 4 行,重启的话运行/sbin/init。
第 5 行,按下 ctrl+alt+del 组合键的话就运行/sbin/reboot,看来 ctrl+alt+del 组合键用于重
启系统。
第 6 行,关机的时候执行/bin/umount,也就是卸载各个文件系统。
第 7 行,关机的时候执行/sbin/swapoff,也就是关闭交换分区。
/etc/inittab 文件创建好以后就可以重启开发板即可,至此!根文件系统要创建的文件就已经全部完成了。

文件系统测试

比如我们自己编写的软件运行是否正常、是否支持软件开机自启动、中文支持是否正常以及能不能链接等。
在 ubuntu 下使用 vim 编辑器新建一个 hello.c 文件,在 hello.c 里面输入如下内容:

#include 

int main(void)
{
	 while(1) {
	 printf("hello world!\r\n");
	 sleep(2);
	}
 	return 0;
}
arm-linux-gnueabihf-gcc hello.c -o hello

将其hello拷贝到 rootfs/drivers 目录下,在开发板中输入如下命令来执行这
个可执行文件:

cd /drivers //进入 drivers 目录
./hello //执行 hello

结果如下图所示:
Linux使用busybox构建文件系统_第11张图片
到此测试完成。

你可能感兴趣的:(Linux驱动,linux,运维,服务器,嵌入式,驱动开发)