一、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页面:

android busybox top 命令执行结果解析 busybox for android ndk有什么用_根文件系统

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

二、Busybox源码目录结构

android busybox top 命令执行结果解析 busybox for android ndk有什么用_GNU_02

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

序号

目录名称

功能说明

1

applets

实现applets框架的文件。目录中包含了几个main()的文件

2

applets_sh

此目录包含了几个作为shell脚本实现的applet示例。在“make install”时不会被自动安装,需要使用时,手动处理

3

arch

包含用于不同体系架构的makefile文件。约束busybox在不同架构体系下的编译构建过程

4

archival

与压缩相关命令的实现源文件。

5

configs

busybox自带的默认配置文件

6

console-tools

与控制台相关的一些命令

7

coreutils

常用的一些核心命令。例如chgrp、rm等

8

debianutils

针对Debian的套件。

9

e2fsprogs

针对Linux Ext2 FS prog的命令。例如chattr、lsattr

10

editors

常用的编辑命令。例如diff、vi等

11

findutils

用于查找的命令

12

include

busybox项目的头文件

13

init

init进程的实现源码目录

14

klibc-utils

klibc命令套件

15

libbb

与busybox实现相关的库文件

16

libpwdgrp

libpwdgrp相关的命令

17

loginutils

与用户管理相关的命令

18

mailutils

与mail相关的命令套件

19

miscutils

该文件下是一些杂项命令,针对特定应用场景

20

modutils

与模块相关的命令

21

networking

与网络相关的命令,例如arp

22

printutils

Print相关的命令

23

procps

与内存、进程相关的命令

24

runit

与Runit实现相关的命令

25

shell

与shell相关的命令

26

sysklogd

系统日志记录工具相关的命令

27

util-linux

Linux下常用的命令,主要与文件系统操作相关的命令。

三、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可以在图形项中配置交叉编译器的路径,较低版本的可能需要手动指定)

android busybox top 命令执行结果解析 busybox for android ndk有什么用_根文件系统_03

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

android busybox top 命令执行结果解析 busybox for android ndk有什么用_交叉编译器_04

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

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

笔者本文使用的【静态编译】

android busybox top 命令执行结果解析 busybox for android ndk有什么用_交叉编译器_05

(4)使用make 编译

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

android busybox top 命令执行结果解析 busybox for android ndk有什么用_linux_06

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

android busybox top 命令执行结果解析 busybox for android ndk有什么用_busybox_07

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

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