- 浏览: 171974 次
- 性别:
- 来自: 南京
文章分类
最新评论
【转载】 http://www.ibm.com/developerworks/cn/linux/l-busybox/index.html
BusyBox 最初是由 Bruce Perens 在 1996 年为 Debian GNU/Linux 安装盘编写的。其目标是在一张软盘上创建一个可引导的 GNU/Linux 系统,这可以用作安装盘和急救盘。一张软盘可以保存大约 1.4-1.7MB 的内容,因此这里没有多少空间留给 Linux 内核以及相关的用户应用程序使用。
BusyBox 许可证
BusyBox 揭露了这样一个事实:很多标准 Linux 工具都可以共享很多共同的元素。例如,很多基于文件的工具(比如
grep
和
find
)都需要在目录中搜索文件的代码。当这些工具被合并到一个可执行程序中时,它们就可以共享这些相同的元素,这样可以产生更小的可执行程序。实际上,BusyBox 可以将大约 3.5MB 的工具包装成大约 200KB 大小。这就为可引导的磁盘和使用 Linux 的嵌入式设备提供了更多功能。我们可以对 2.4 和 2.6 版本的 Linux 内核使用 BusyBox。
为了让一个可执行程序看起来就像是很多可执行程序一样,BusyBox 为传递给 C 的 main 函数的参数开发了一个很少使用的特性。回想一下 C 语言的 main 函数的定义如下:
POSIX 环境
int main( int argc, char *argv[] )
|
在这个定义中,argc
是传递进来的参数的个数(参数数量),而
argv
是一个字符串数组,代表从命令行传递进来的参数(参数向量)。argv
的索引 0 是从命令行调用的程序名。
清单 2 给出的这个简单 C 程序展示了 BusyBox 的调用。它只简单地打印
argv
向量的内容。
清单 2. BusyBox 使用
argv[0]
来确定调用哪个应用程序
// test.c
#include <stdio.h>
int main( int argc, char *argv[] )
{
int i;
for (i = 0 ; i < argc ; i++) {
printf("argv[%d] = %s\n", i, argv[i]);
}
return 0;
}
|
调用这个程序会显示所调用的第一个参数是该程序的名字。我们可以对这个可执行程序重新进行命名,此时再调用就会得到该程序的新名字。另外,我们可以创建一个到可执行程序的符号链接,在执行这个符号链接时,就可以看到这个符号链接的名字。
清单 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 的 Web 站点上下载最新版本的 BusyBox(请参看 参考资料 一节的内容)。与大部分开放源码程序一样,它是以一个压缩的 tarball 形式发布的,我们可以使用清单 4 给出的命令将其转换成源代码树。(如果我们下载的版本不是 1.1.1,那就请在这个命令中使用适当的版本号以及特定于这个版本号的命令。)
$ tar xvfz busybox-1.1.1.tar.gz
$
|
结果会生成一个目录,名为 busybox-1.1.1,其中包含了 BusyBox 的源代码。要编译默认的配置(其中包含了几乎所有的内容,并禁用了调试功能),请使用
defconfig
make 目标:
BusyBox 源代码树
httpd
、ifconfig
等)都在 ./networking 目录中;标准的模块工具(包括insmod
、rmmod
和
lsmod
)都在 ./modutils 目录中;编辑器(例如
vi
和流编辑器,如
awk
和
sed
)都在 ./editors 目录中。makefile 配置、编译和安装所使用的各个文档都在这个目录树的根目录中。
$ 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 的内容。如果您熟悉 Linux 内核的编译过程,就会注意到
menuconfig
与配置 Linux 内核的内容所使用的目标相同。实际上,它们都采用了相同的基于 ncurses 的应用程序。
使用手工配置,我们可以指定在最终的 BusyBox 映像中包含的命令。我们也可以对 BusyBox 环境进行配置,例如包括对 NSA(美国国家安全代理)的安全增强 Linux(SELinux),指定要使用的编译器(用来在嵌入式环境中进行交叉编译)以及 BusyBox 应该静态编译还是动态编译。图 1 给出了
menuconfig
的主界面。在这里我们应该可以看到可以为 BusyBox 配置的不同类型的应用程序(applet)。
多体系结构支持
要手工配置 BusyBox,请使用下面的命令:
$ make menuconfig
$ make
$
|
这为我们提供了可以调用的 BusyBox 的二进制文件。下一个步骤是围绕 BusyBox 构建一个环境,包括将标准 Linux 命令重定向到 BusyBox 二进制文件的符号链接。我们可以使用下面的命令简单地完成这个过程:
$ make install
$
|
默认情况下,这会创建一个新的本地子目录 _install,其中包含了基本的 Linux 环境。在这个根目录中,您会找到一个链接到 BusyBox 的
linuxrc
程序。这个
linuxrc
程序在构建安装盘或急救盘(允许提前进行模块化的引导)时非常有用。同样是在这个根目录中,还有一个包含操作系统二进制文件的 /sbin 子目录。还有一个包含用户二进制文件的 /bin 目录。在构建软盘发行版或嵌入式初始 RAM 磁盘时,我们可以将这个 _install 目录迁移到目标环境中。我们还可以使用 make 程序的
PREFIX
选项将安装目录重定向到其他位置。例如,下面的代码就使用 /tmp/newtarget 根目录来安装这些符号链接,而不是使用 ./_install 目录:
$ make PREFIX=/tmp/newtarget install
$
|
使用
install
make 目标创建的符号链接都来自于 busybox.links 文件。这个文件是在编译 BusyBox 时创建的,它包含了已经配置的命令清单。在执行
install
时,就会检查 busybox.links 文件确定要创建的符号链接。
到 BusyBox 的命令行链接也可以使用 BusyBox 在运行时动态创建。CONFIG_FEATURE_INSTALLER
选项就可以启用这个特性,在运行时可以这样执行:
$ ./busybox --install -s
$
|
-s
选项强制创建这些符号链接(否则就创建硬链接)。这个选项要求系统中存在 /proc 文件系统。
BusyBox 包括了几个编译选项,可以帮助为我们编译和调试正确的 BusyBox。
help
|
显示 make 选项的完整列表 |
defconfig
|
启用默认的(通用)配置 |
allnoconfig
|
禁用所有的应用程序(空配置) |
allyesconfig
|
启用所有的应用程序(完整配置) |
allbareconfig
|
启用所有的应用程序,但是不包括子特性 |
config
|
基于文本的配置工具 |
menuconfig
|
N-curses(基于菜单的)配置工具 |
all
|
编译 BusyBox 二进制文件和文档(./docs) |
busybox
|
编译 BusyBox 二进制文件 |
clean
|
清除源代码树 |
distclean
|
彻底清除源代码树 |
sizes
|
显示所启用的应用程序的文本/数据大小 |
在定义配置时,我们只需要输入
make
就可以真正编译 BusyBox 二进制文件。例如,要为所有的应用程序编译 BusyBox,我们可以执行下面的命令:
$ make allyesconfig
$ make
$
|
如果您非常关心对 BusyBox 映像的压缩,就需要记住两件事情:
-
永远不要编译为静态二进制文件(这会将所有需要的库都包含到映像文件中)。相反,如果我们是编译为一个共享映像,那么它会使用其他应用程序使用的库(例如
/lib/libc.so.X
)。 - 使用 uClibc 进行编译,这是一个对大小进行过优化的 C 库,它是为嵌入式系统开发的;而不要使用标准的 glibc (GNU C 库)来编译。
BusyBox 中的命令并不支持所有可用选项,不过这些命令都包含了常用的选项。如果我们需要知道一个命令可以支持哪些选项,可以使用
--help
选项来调用这个命令,如清单 12 所示。
$ ./busybox wc --help
BusyBox v1.1.1 (2006.04.09-15:27+0000) multi-call binary
Usage: wc [OPTION]... [FILE]...
Print line, word, and byte counts for each FILE, and a total line if
more than one FILE is specified. With no FILE, read standard input.
Options:
-c print the byte counts
-l print the newline counts
-L print the length of the longest line
-w print the word counts
$
|
这些特定的数据只有在启用了
CONFIG_FEATURE_VERBOSE_USAGE
选项时才可以使用。如果没有这个选项,我们就无法获得这些详细数据,但是这样可以节省大约 13 KB 的空间。
向 BusyBox 添加一个新命令非常简单,这是因为它具有良好定义的体系结构。第一个步骤是为新命令的源代码选择一个位置。我们要根据命令的类型(网络,shell 等)来选择位置,并与其他命令保持一致。这一点非常重要,因为这个新命令最终会在 menuconfig 的配置菜单中出现(在下面的例子中,是 Miscellaneous Utilities 菜单)。
对于这个例子来说,我将这个新命令称为
newcmd
,并将它放到了 ./miscutils 目录中。这个新命令的源代码如清单 13 所示。
#include "busybox.h"
int newcmd_main( int argc, char *argv[] )
{
int i;
printf("newcmd called:\n");
for (i = 0 ; i < argc ; i++) {
printf("arg[%d] = %s\n", i, argv[i]);
}
return 0;
}
|
接下来,我们要将这个新命令的源代码添加到所选子目录中的
Makefile.in
中。在本例中,我更新了
./miscutils/Makefile.in
文件。请按照字母顺序来添加新命令,以便维持与现有命令的一致性:
MISCUTILS-$(CONFIG_MT) += mt.o
MISCUTILS-$(CONFIG_NEWCMD) += newcmd.o
MISCUTILS-$(CONFIG_RUNLEVEL) += runlevel.o
|
接下来再次更新 ./miscutils 目录中的配置文件,以便让新命令在配置过程中是可见的。这个文件名为 Config.in,新命令是按照字母顺序添加的:
config CONFIG_NEWCMD
bool "newcmd"
default n
help
newcmd is a new test command.
|
这个结构定义了一个新配置项(通过
config
关键字)以及一个配置选项(CONFIG_NEWCMD
)。新命令可以启用,也可以禁用,因此我们对配置的菜单属性使用了
bool
(Boolean)值。这个命令默认是禁用的(n
表示 No),我们可以最后放上一个简短的 Help 描述。在源代码树的 ./scripts/config/Kconfig-language.txt 文件中,我们可以看到配置语法的完整文法。
接下来需要更新 ./include/applets.h 文件,使其包含这个新命令。将下面这行内容添加到这个文件中,记住要按照字母顺序。维护这个次序非常重要,否则我们的命令就会找不到。
USE_NEWCMD(APPLET(newcmd, newcmd_main, _BB_DIR_USER_BIN, _BB_SUID_NEVER))
|
这定义了命令名(newcmd
),它在 Busybox 源代码中的函数名(newcmd_main
),应该在哪里会为这个新命令创建链接(在这种情况中,它在 /usr/bin 目录中),最后这个命令是否有权设置用户 id(在本例中是 no)。
倒数第二个步骤是向 ./include/usage.h 文件中添加详细的帮助信息。正如您可以从这个文件的例子中看到的一样,使用信息可能非常详细。在本例中,我只添加了一点信息,这样就可以编译这个新命令了:
#define newcmd_trivial_usage "None"
#define newcmd_full_usage "None"
|
最后一个步骤是启用新命令(通过
make menuconfig
,然后在 Miscellaneous Utilities 菜单中启用这个选项)然后使用
make
来编译 BusyBox。
使用新的 BusyBox,我们可以对这个新命令进行测试,如清单 18 所示。
$ ./busybox newcmd arg1
newcmd called:
arg[0] = newcmd
arg[1] = arg1
$ ./busybox newcmd --help
BusyBox v1.1.1 (2006.04.12-13:47+0000) multi-call binary
Usage: newcmd None
None
|
就是这样!BusyBox 开发人员开发了一个优秀但非常容易扩展的工具。
BusyBox 是为构建内存有限的嵌入式系统和基于软盘系统的一个优秀工具。BusyBox 通过将很多必需的工具放入一个可执行程序,并让它们可以共享代码中相同的部分,从而对它们的大小进行了很大程度的缩减,BusyBox 对于嵌入式系统来说是一个非常有用的工具,因此值得我们花一些时间进行探索。
学习
-
您可以参阅本文在 developerWorks 全球站点上的
英文原文
。
-
uClibc
是
glibc
一个精简内存需求的替代品。尽管它需要的资源比 glibc 少,但是将应用程序移植到 uClibc 上通常只需要重新编译即可。
-
Open Group 站点上的
POSIX FAQ
可以帮助我们学习更多有关 POSIX 的知识。这个规范的第 3 部分详细介绍了 shell 和工具的相关内容。
-
LinuxTiny
是用来减少 2.6 版本的 Linux 内核对内存和磁盘需求的一系列补丁,它只有 2MB 大小的 RAM。如果您对精简 2.6 版本的 Linux 内核感兴趣,请尝试一下 Matt Mackall 所开发的这个工具。
-
在
developerWorks Linux 专区
可以找到为 Linux 开发人员准备的更多资源。
-
随时关注
developerWorks 技术事件和网络广播
。
获得产品和技术
-
下载
BusyBox
的最新版本。我们可以找到最新的新闻、勘误以及使用并改进 BusyBox 的教程。
-
在您的下一个开发项目中采用
IBM 试用软件
,这可以从 developerWorks 上直接下载。
讨论
-
通过参与
developerWorks blogs
加入 developerWorks 社区。
发表评论
-
linux系统命令、配置
2012-01-10 13:42 686查看那系统版本: lsb_release -a una ... -
linux gdb 调试
2012-01-04 23:11 9251. gcc或make生成debug版本--> test ... -
linux tar.bz2解压命令
2011-11-29 16:32 893bzip2 -d gcc-4.1.0.tar.bz2 ... -
linux设置mysql innodb_lock_wait_timeout的值
2011-11-15 20:11 14515root权限下: vi /etc/my.cnf 在[mys ... -
linux libc.so误操作之后恢复
2011-11-14 18:58 1373使用这个命令, LD_PRELOAD=<real li ... -
linux 命令 ——文件操作
2011-11-07 20:43 908#shell命令 追加模式 #统计目录文件大小 d ... -
下一代文件系统btrfs
2011-10-17 09:25 924来源: http://www.ibm.com/de ... -
linux zip unzip 密码 压缩 解压缩
2011-10-13 13:33 12632zip -P password zipfile.zip sou ...
相关推荐
《ARM嵌入式Linux系统开发详解(第2版)》共分4篇。 第1篇 介绍了嵌入式系统入门、嵌入式软硬件系统、ARM处理器、嵌入式Linux、软件开发环境建立和第一个Linux应用程序; 第2篇 介绍了Linux应用程序编程基础、开发多...
《ARM嵌入式Linux系统开发详解(第2版)》共分4篇。 第1篇 介绍了嵌入式系统入门、嵌入式软硬件系统、ARM处理器、嵌入式Linux、软件开发环境建立和第一个Linux应用程序; 第2篇 介绍了Linux应用程序编程基础、开发多...
《ARM嵌入式Linux系统开发详解(第2版)》共分4篇。 第1篇 介绍了嵌入式系统入门、嵌入式软硬件系统、ARM处理器、嵌入式Linux、软件开发环境建立和第一个Linux应用程序; 第2篇 介绍了Linux应用程序编程基础、开发多...
《ARM嵌入式Linux系统开发详解(第2版)》共分4篇。 第1篇 介绍了嵌入式系统入门、嵌入式软硬件系统、ARM处理器、嵌入式Linux、软件开发环境建立和第一个Linux应用程序; 第2篇 介绍了Linux应用程序编程基础、开发多...
《ARM嵌入式Linux系统开发详解(第2版)》共分4篇。 第1篇 介绍了嵌入式系统入门、嵌入式软硬件系统、ARM处理器、嵌入式Linux、软件开发环境建立和第一个Linux应用程序; 第2篇 介绍了Linux应用程序编程基础、开发多...
本篇将围绕“ARM嵌入式Linux系统开发详解源代码”这一主题,深入探讨相关知识点。 1. **ARM架构与指令集** - ARM架构:ARM(Advanced RISC Machines)是一种精简指令集计算机(RISC)架构,以其高效能、低功耗的...
本篇文章将深入探讨嵌入式Linux在ARM上的开发过程,包括系统构建、驱动开发、应用程序设计等多个方面。 一、嵌入式Linux系统构建 在基于ARM的硬件平台上搭建嵌入式Linux系统,首先需要准备交叉编译工具链,这是...
- **BusyBox官方文档**:提供了BusyBox的详细使用指南和配置说明。 - **Linux内核文档**:涵盖了Linux内核开发和配置的各个方面,是深入学习Linux内核开发的重要资源。 通过上述步骤和指导,你可以构建出一个符合...
《update.zip:系统更新与BusyBox安装详解》 在IT领域,系统更新是维护设备安全性和功能完整性的关键步骤。而“update.zip”文件通常与Android系统的刷机更新紧密相关,这种文件允许用户通过手动方式对设备进行系统...
本篇文章将深入探讨嵌入式Linux应用程序开发的核心概念、关键技术和实际应用。 首先,我们要了解嵌入式系统的基本概念。嵌入式系统是集成在更大系统中的专用计算机系统,它负责特定的功能,具有高效能、低功耗、...
本篇主要介绍如何在DOM盘上裁剪构建一个精简版的Linux系统,使其能够独立启动并包含常用命令集。 **一、DOM盘分区** 1. **硬件准备**:确保DOM盘已正确连接到台式机的IDE接口,与硬盘或光驱共用一个接口可能需要...
### Linux根文件系统制作详解 #### 一、引言 在深入探讨Linux根文件系统的制作之前,我们先来了解一下根文件系统的基本概念及其在Linux系统中的作用。根文件系统是Linux系统启动后的第一个文件系统,它包含了系统...
这篇文章就给大家总结一下我自己使用过的六种减小镜像大小的方法。 1. 使用Alpine Linux Alpine Linux是一个基于BusyBox和Musl Libc的Linux发行版,其最大的优势就是小。一个纯的基础Alpine Docker镜像在压缩后仅有...
本篇文章旨在通过分析给定文件中的关键信息,详细解释这一过程中的每一个步骤及其背后的原理。 #### 二、安装Linux环境 首先,需要在计算机上安装一个支持Android移植的Linux发行版,如Ubuntu Linux。选择Ubuntu ...
本篇将详细介绍U970工具箱及其相关组件,以及如何使用它们来实现刷机和root操作。 首先,U970工具箱是一款专为LG U970手机设计的实用工具集,它声称与U930兼容,意味着这两款设备有着相似的硬件和软件结构。该工具...
4. **busybox**:BusyBox集合了许多常见的Unix命令,为安卓提供了一个精简版的Linux命令行环境。在ROOT后,它有助于设备的维护和故障排除。 5. **rageagainstthecage**:这是一个利用安全漏洞实现ROOT的工具,有时...