BusyBox构建根文件系统
根文件系统里面就是一堆的可执行文件和其他文件组成的?难道我们得一个一个的从网上去下载这些文件?显然这是不现实的!那么有没有人或者组织专门干这个事呢?他们负责“收集”这些文件,然后将其打包,像我们这样的开发者可以直接拿来用。答案是有的,它就叫做BusyBox!其名字分为“Busy”和“Box”,也就是忙碌的盒子。盒子是用来放东西的,忙碌的是因为它要提供根文件系统所需的文件,所以忙碌。BusyBox是一个集成了大量的Linux命令和工具的软件,像ls、mv、ifconfig等命令BusyBox都会提供。BusyBox就是一个大的工具箱,这个工具箱里面集成了Linux的许多工具和命令。一般下载BusyBox的源码,然后配置BusyBox,选择自己想要的功能,最后编译即可。
BusyBox可以在其官网下载到,官网地址为:https://busybox.net/,如图所示:
编译BusyBox构建根文件系统
一般我们在Linux驱动开发的时候都是通过nfs挂载根文件系统的,当产品最终上市开卖的时候才会将根文件系统烧写到EMMC或者NAND中。使用如下命令创建名为rootfs的子目录:
mkdir rootfs
创建好的rootfs子目录就用来存放我们的根文件系统了。
将busybox-1.29.0.tar.bz2发送到Ubuntu中,然后使用如下命令将其解压:
tar -vxjf busybox-1.29.0.tar.bz2
解压完成以后进入到busybox-1.29.0目录中,此目录中的文件和文件夹如图所示:
1、修改Makefile,添加编译器
同Uboot和Linux移植一样,打开busybox的顶层Makefile,添加ARCH和CROSS_COMPILE的值,如下所示:
示例代码38.2.2.1 Makefile代码段
164 CROSS_COMPILE ?= /usr/local/arm/gcc-linaro-4.9.4-2017.01-x86_64_arm-linux-gnueabihf/bin/arm-linux-gnueabihf-
…
190 ARCH ?= arm
在示例代码38.2.2.1中CORSS_COMPILE使用了绝对路径!主要是为了防止编译出错。
2、busybox中文字符支持
如果默认直接编译busybox的话,在使用SecureCRT的时候中文字符是显示不正常的,中文字符会显示为“?”,比如你的中文目录,中文文件都显示为“?”。不知道从哪个版本开始busybox中的shell命令对中文输入即显示做了限制,即使内核支持中文但在shell下也依然无法正确显示。
所以我们需要修改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) {
19 unsigned char c = *s;
20 if (c == '\0') {
......
28 }
29 if (c < ' ')
30 break;
31 if (c >= 0x7f)
32 break;
33 s++;
34 }
35
36 #if ENABLE_UNICODE_SUPPORT
37 dst = unicode_conv_to_printable(stats, str);
38 #else
39 {
40 char *d = dst = xstrdup(str);
41 while (1) {
42 unsigned char c = *d;
43 if (c == '\0')
44 break;
45 if (c < ' ' || c >= 0x7f)
46 *d = '?';
47 d++;
48 }
......
55 #endif
56 return auto_string(dst);
57 }
第31和32行,当字符大于0X7F以后就跳出去了。 第45和46行,如果支持UNICODE码的话,当字符大于0X7F就直接输出‘?’。 所以我们需要对这4行代码进行修改,修改以后如下所示:
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 *d++ = (c >= ' ' && c < 0x7f) ? c : '?';
1023 src++;
1024 }
1025 *d = '\0';
1026 } else {
1027 d = dst = xstrndup(src, width);
1028 while (*d) {
1029 unsigned char c = *d;
1030 if (c < ' ' || c >= 0x7f)
1031 *d = '?';
1032 d++;
1033 }
1034 }
......
1040 return dst;
1041 }
......
1130
1131 return dst;
1132 }
第1022行,当字符大于0X7F以后,*d++就为‘?’。 第1030和1031行,当字符大于0X7F以后,*d也为‘?’。 修改示例代码,修改后内容如下所示:
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 }
示例代码中红色部分的代码就是被修改以后的,同样主要是禁止字符大于0X7F的时候设置为‘?’。busybox中文字符支持跟代码修改有关的就改好了,最后还需要配置busybox来使能unicode码,这个稍后我们配置busybox的时候在设置。
3、配置busybox
根我们编译Uboot、Linux kernel一样,我们要先对busybox进行默认的配置,有以下几种配置选项:
①、defconfig,缺省配置,也就是默认配置选项。
②、allyesconfig,全选配置,也就是选中busybox的所有功能。
③、allnoconfig,最小配置。
我们一般使用默认配置即可,因此使用如下命令先使用默认配置来配置一下busybox:
make defconfig
busybox也支持图形化配置,通过图形化配置我们可以进一步选择自己想要的功能,输入如下命令打开图形化配置界面:
make menuconfig