一、Busybox简介

​ 【特点】

(1-1)开源项目

​ Busybox是一个开源项目,遵循GPL v2协议。Busybox将众多的UNIX命令集合进了一个很小的可执行程序中,可以用来替代GNU fileutils、shellutils等工具集。Busybox中各种命令与相应的GNU工具相比,所能提供的选项比较少,但是对于一般的应用场景也足够了。Busybox主要用于嵌入式系统的开发中。

(1-2)程序本体较小

​ Busybox在编写过程中对文件大小进行了优化,并考虑了系统资源有限(比如内存等)的情况。与一般的GNU工具集动辄几M的体积相比,动态链接的Busybox只有几百K,即使是采用静态链接也只有1.M左右。Busybox按模块设计,可以很容易地加入、去除某些命令,或增减命令的某些选项。

(1-3)使用简单

​ 在创建根文件系统的时候,如果使用Busybox来创建根文件系统,使用起来较为方便,只需要在/dev目录下创建必要的设备节点,在/etc目录下增加一些配置文件即可,当然如果Busybox是动态链接的,那么还需要在/lib目录下包含相关的运行库文件。


​ 【官方资源】

​ URL:https://busybox.net/

​ Web页面:
在这里插入图片描述

【注】本文所记录内容时 使用的busybox版本为:1.29.0

二、Busybox源码目录结构

上图是Busybox的目录中的目录和文件。

序号目录名称功能说明
1applets实现applets框架的文件。目录中包含了几个main()的文件
2applets_sh此目录包含了几个作为shell脚本实现的applet示例。在“make install”时不会被自动安装,需要使用时,手动处理
3arch包含用于不同体系架构的makefile文件。约束busybox在不同架构体系下的编译构建过程
4archival与压缩相关命令的实现源文件。
5configsbusybox自带的默认配置文件
6console-tools与控制台相关的一些命令
7coreutils常用的一些核心命令。例如chgrp、rm等
8debianutils针对Debian的套件。
9e2fsprogs针对Linux Ext2 FS prog的命令。例如chattr、lsattr
10editors常用的编辑命令。例如diff、vi等
11findutils用于查找的命令
12includebusybox项目的头文件
13initinit进程的实现源码目录
14klibc-utilsklibc命令套件
15libbb与busybox实现相关的库文件
16libpwdgrplibpwdgrp相关的命令
17loginutils与用户管理相关的命令
18mailutils与mail相关的命令套件
19miscutils该文件下是一些杂项命令,针对特定应用场景
20modutils与模块相关的命令
21networking与网络相关的命令,例如arp
22printutilsPrint相关的命令
23procps与内存、进程相关的命令
24runit与Runit实现相关的命令
25shell与shell相关的命令
26sysklogd系统日志记录工具相关的命令
27util-linuxLinux下常用的命令,主要与文件系统操作相关的命令。
三、busybox的init进程

​ 在linux内核启动的最后阶段,会调用run_init_process()函数启动用户空间进程,对于Busybox来说,它同样将提供一个init程序,满足linux内核最后阶段的启动跳转。只要run_init_process()创建进程成功,那么此函数将不会返回了,从而从内核态进入了用户态进程。

​ busybox的init程序的描述源文件位于源代码下的init/init.c文件中。

​ 核心功能的由init_main函数实现,此函数中内容较多,将在文章《busybox的init_main函数》中分析

int init_main(int argc UNUSED_PARAM, char **argv)
{
	INIT_G();

	if (argv[1] && strcmp(argv[1], "-q") == 0) {
		return kill(1, SIGHUP);
	}

#if DEBUG_SEGV_HANDLER
	{
		struct sigaction sa;
		memset(&sa, 0, sizeof(sa));
		sa.sa_sigaction = handle_sigsegv;
		sa.sa_flags = SA_SIGINFO;
		sigaction(SIGSEGV, &sa, NULL);
		sigaction(SIGILL, &sa, NULL);
		sigaction(SIGFPE, &sa, NULL);
		sigaction(SIGBUS, &sa, NULL);
	}
#endif

	if (!DEBUG_INIT) {
		sigprocmask_allsigs(SIG_BLOCK);

     /* ........................... */
        
四、编译busybox过程总结

在准备编译前,可以先参考INSTALL、README以及examples目录和docs目录下的文件。获取到相关的构建说明、安装说明和一些使用的示例。

总体来说,编译busybox与linux、以及u-boot的过程类似:

(1)使用

make menuconfig

​ 先在宿主机上编译出用于配置busybox的图像化界面

​ 这个过程中,可能会由于缺少一些库(例如ncurses)而报错,这时将其安装即可解决。

​ 对于嵌入式系统环境,是需要使用与嵌入式系统相关联的【交叉编译器】来进行编译,所以,这里需要指定用于编译busybox的交叉编译器。

​ 在busybox源码目录下的顶层makefile文件中添加:

CROSS_COMPILE ?= #交叉编译器的路径

ARCH ?= arm 	#对应的架构,这里以arm为例

​ (经测试,笔者的1.29版本busybox可以在图形项中配置交叉编译器的路径,较低版本的可能需要手动指定)
在这里插入图片描述

(2)指定busybox编译后的安装路径。

在这里插入图片描述

从上图我们可以看出,Busybox默认的安装路径是源代码目录的_install目录(该目录不存在,安装的时候自动创建)。

(3)可以更加实际情况设置busybox的动态/静态编译

​ 笔者本文使用的【静态编译】
在这里插入图片描述

(4)使用make 编译

(5)使用make install进行安装,完成后如下图:

在这里插入图片描述

使用静态编译构建出的busybox 软件本体有1.4M大小左右

在这里插入图片描述

总结一下busybox的编译构建过程:

1、使用make menuconfig构建出图形配置界面。
2、通过配置图形配置界面的选项配置busybox的安装路径、编译工具、命令功能使能等。生成.config配置文件
3、使用make编译busybox
4、使用make install命令安装由busybox生成的根文件系统
5、完善根文件系统
6、使用和测试根文件系统
Logo

旨在为数千万中国开发者提供一个无缝且高效的云端环境,以支持学习、使用和贡献开源项目。

更多推荐