BusyBox 简化嵌入式 Linux 系统 (转载)
BusyBox 简化嵌入式 Linux 系统 (转载)
2011年03月30日
很不错的介绍BusyBox的文章,
转载于:http://www.ibm.com/developerworks/cn/linux/l-busybox/
BusyBox 的诞生
BusyBox 最初是由 Bruce Perens 在 1996 年为 Debian GNU/Linux
安装盘编写的。其目标是在一张软盘上创建一个可引导的 GNU/Linux 系统,这可以用作安装盘和急救盘。一张软盘可以保存大约 1.4-1.7MB
的内容,因此这里没有多少空间留给 Linux 内核以及相关的用户应用程序使用。
BusyBox 许可证 BusyBox 是按照 GNU
General Public License(GPL)许可证发行的。这意味着如果我们在一个项目中使用 BusyBox,就必须遵守这个许可证。我们可以在
BusyBox Web 站点(请参看本文后面
参考资料
一节的内容)上看到这个许可证的内容。BusyBox 团队似乎正忙于监视违反这个许可证的情况。实际上,他们维护了一个 “Hall of Shame”
页面来说明违反者的情况。
BusyBox 揭露了这样一个事实:很多标准 Linux 工具都可以共享很多共同的元素。例如,很多基于文件的工具(比如 grep
和
find)都需要在目录中搜索文件的代码。当这些工具被合并到一个可执行程序中时,它们就可以共享这些相同的元素,这样可以产生更小的可执行程序。实际上,
BusyBox 可以将大约 3.5MB 的工具包装成大约 200KB 大小。这就为可引导的磁盘和使用 Linux 的嵌入式设备提供了更多功能。我们可以对 2.4
和 2.6 版本的 Linux 内核使用 BusyBox。
BusyBox 是如何工作的?
为了让一个可执行程序看起来就像是很多可执行程序一样,BusyBox 为传递给 C 的 main 函数的参数开发了一个很少使用的特性。回想一下 C 语言的
main 函数的定义如下:
POSIX 环境 尽管 BusyBox 的目标
是提供一个相当完整的 POSIX(可移植操作系统接口)环境,这是一个期望,而不是一种需求。这些工具虽然并不完整,但是它们提供了我们期望的主要功能。
清单
1. C 的 main 函数 int main( int argc, char *argv[] )
在这个定义中,argc 是传递进来的参数的个数(参数数量),而 argv
是一个字符串数组,代表从命令行传递进来的参数(参数向量)。argv 的索引 0 是从命令行调用的程序名。
清单 2 给出的这个简单 C 程序展示了 BusyBox 的调用。它只简单地打印 argv 向量的内容。
清单 2. BusyBox 使用 argv[0] 来确定调用哪个应用程序 // test.c
#include
int main( int argc, char *argv[] )
{
int i;
for (i = 0 ; i
调用这个程序会显示所调用的第一个参数是该程序的名字。我们可以对这个可执行程序重新进行命名,此时再调用就会得到该程序的新名字。另外,我们可以创建一个到可执行程序的符号链接,在执行这个符号链接时,就可以看到这个符号链接的名字。
清单 3. 在使用新命令更新 BusyBox 之后的命令测试 $ gcc -Wall -o test test.c
$ ./test arg1 arg2
argv[0] = ./test
argv[1] = arg1
argv[2] = arg2
$ mv test newtest
$ ./newtest arg1
argv[0] = ./newtest
argv[1] = arg1
$ ln -s newtest linktest
$ ./linktest arg
argv[0] = ./linktest
argv[1] = arg
BusyBox 使用了符号链接以便使一个可执行程序看起来像很多程序一样。对于 BusyBox
中包含的每个工具来说,都会这样创建一个符号链接,这样就可以使用这些符号链接来调用 BusyBox 了。BusyBox 然后可以通过
argv[0] 来调用内部工具。
配置并编译 BusyBox
我们可以从 BusyBox 的 Web 站点上下载最新版本的 BusyBox(请参看
参考资料
一节的内容)。与大部分开放源码程序一样,它是以一个压缩的 tarball 形式发布的,我们可以使用清单 4
给出的命令将其转换成源代码树。(如果我们下载的版本不是 1.1.1,那就请在这个命令中使用适当的版本号以及特定于这个版本号的命令。)
清单 4. 展开 BusyBox $ tar xvfz busybox-1.1.1.tar.gz
$
结果会生成一个目录,名为 busybox-1.1.1,其中包含了 BusyBox
的源代码。要编译默认的配置(其中包含了几乎所有的内容,并禁用了调试功能),请使用 defconfig make 目标:
BusyBox 源代码树 BusyBox
的源代码树组织得很好。这些工具都基于它们的用途进行了分类,并存储在单独的子目录中。例如,网络工具和守护进程(如
httpd、ifconfig 等)都在 ./networking 目录中;标准的模块工具(包括
insmod、rmmod 和 lsmod)都在 ./modutils
目录中;编辑器(例如 vi 和流编辑器,如 awk 和 sed)都在
./editors 目录中。makefile 配置、编译和安装所使用的各个文档都在这个目录树的根目录中。
清单
5. 编译默认的 BusyBox 配置 $ cd busybox-1.1.1
$ make defconfig
$ make
$
结果是一个相当大的 BusyBox 映像,不过这只是开始使用它的最简单的方法。我们可以直接调用这个新映像,这会产生一个简单的 Help
页面,里面包括当前配置的命令。要对这个映像进行测试,我们也可以对一个命令调用 BusyBox 来执行,如清单 6 所示。
清单 6. 展示 BusyBox 命令的执行和 BusyBox 中的 ash shell $ ./busybox pwd
/usr/local/src/busybox-1.1.1
$ ./busybox ash
/usr/local/src/busybox-1.1.1 $ pwd
/usr/local/src/busybox-1.1.1
/usr/local/src/busybox-1.1.1 $ exit
$
在这个例子中,我们调用了 pwd(打印工作目录)命令,使用 BusyBox 进入了 ash
shell,并在 ash 中调用了 pwd。
手工配置
如果您正在构建一个具有特殊需求的嵌入式设备,那就可以手工使用 menuconfig make 目标来配置 BusyBox
的内容