上期文章中,笔者向各位介绍了 musl,一个 Glibc 的替代方案,它的主要优势体现在更加整洁的代码、更小的二进制体积和更优秀的静态链接支持。而本期文章的主角:BusyBox 则是 GNU Coreutils 的替代方案之一,提供了包含 ls、cat、echo、grep、sh 等 Linux 中不可或缺的命令行工具。在官网的介绍中,BusyBox 的开发者们是这样介绍它的:嵌入式 Linux 的瑞士军刀。
珠玉在前
GNU Coreutils + Bash 的组合一直是各大 Linux 发行版中的“黄金搭档”,如今几乎所有的 Linux 发行版默认都会使用它们作为默认的 Shell 和基础工具包,Coreutils 包含了一系列每个 Linux 用户都再熟悉不过的命令:ls、cat、grep...几乎所有你熟悉的“开箱即用”的 Linux 工具都是 Coreutils 的一部分,不过在桌面发行版中广受欢迎的它却在嵌入式开发中遇到了一个问题,一个永恒的、经典的问题:成本,或者换句话来说,体积。Coreutils 丰富功能的代价之一就是体积的膨胀,这使得它不适用于嵌入式环境这种对体积要求极为严苛的环境,于是 BusyBox 应运而生。
BusyBox 做的最关键的一件事就是:压缩体积,它在诞生之初便是为了塞进一张软盘而设计的(当时流行的 3.5 寸软盘容量约为 1.44 MB),这样它既可以作为当时流行的 Debian 系统的急救盘、也可以成为它的安装盘,BusyBox 把原来数十个乃至数百个程序实现的功能塞进了一个可执行文件中,这种高度的集成带来的是体积的极致压缩,因为这样做它便不会受到多个 ELF 文件中冗余文件头的影响,同时多个功能也可以调用同一个库中的代码,进一步压缩了体积。1996 年,初版 BusyBox 诞生了,之后便被广泛应用在各种嵌入式项目和精简发行版中,成为了嵌入式操作系统的事实标准之一,不只是 Linux,FreeBSD 等项目中也不乏 BusyBox 的身影。
设计与使用
BusyBox 单一可执行文件的设计自然带来了诸多好处,但各位读者可能有一个问题:“那么多工具被集成进了同一个程序,我要怎么用呢?”,对于这个问题,BusyBox 提供了两种方案。
第一种也是最简单的一种,自然就是通过参数调用,如下面所示:
/bin/busybox ls
当然,这种调用方式并不常见,更方便也是更常用的一种方法是将各种命令符号链接到 BusyBox 上,这样你就可以用下面的方式调用 BusyBox 了:
/bin/ls
这样调用时,BusyBox 就可以通过 argv[0] 也就是调用的程序名称来判断到底调用的是哪个功能,并使用对应的程序了,这也是目前各大使用 BusyBox 的发行版(如 Alpine Linux)普遍使用的方式。
许可证之争
各种许可证之间的争端似乎是开源世界永恒不变的主题之一,从 Linux 与 FreeBSD 之间的争端,到 Linus 本人拒绝 GPLv3 并怒喷 FSF,这样的争端从来就没有停歇过,其中最为突出的便是 BSD 这种“商业友好许可证”与 GPL 这种“社区友好许可证”之间的争端。
BSD 许可证的支持者们普遍认为 GPL 许可证这种“传染”开源的形式会阻止商业公司在他们的开发中使用自己的项目,进而不利于进一步扩大受众和推广。而 GPL 许可证的拥趸们则常常嘲讽 BSD 许可证的项目是给别人做了嫁衣,例如苹果的 Darwin 内核之于 FreeBSD,商业公司常常利用这些开源项目赚的盆满钵满,而不需要为社区付出任何金钱甚至是代码,这往往阻碍了社区项目的进一步发展。
而 BusyBox 的第一次“出圈”就来自本世纪第一个十年几场关于 GPL 许可证的诉讼事件,2006-2007 年间,BusyBox 项目组针对一系列使用该项目却没有按照许可证要求开源的商业公司展开了大规模诉讼,其中不乏三星、百思买、JVC 等大型企业,在这一系列诉讼中,BusyBox 获得了彻底的胜利,除了部分诉讼以庭外和解的形式结束以外,大部分的诉讼 BusyBox 项目都获得了胜诉,并赢取了可观的赔偿。
然而,并不是所有人都对这场“胜利”感到兴奋。当时的项目维护者 Rob Landley 就对这一系列的诉讼感到非常不满,他曾经在一次采访中说道:“诉讼并没有带来积极的结果,因此我想以‘我认为合适的方式’终结他们”。于是他在之后离开了 BusyBox 项目,并创建了一个使用 BSD 许可证的类似项目——Toybox,如今应用于 AOSP 项目的基础组件。这场关于许可证与软件哲学的斗争,想必在未来依旧会持续下去,不过现如今,在大批商业公司拥抱开源的如今,社区真的还能保持自己的独立性与能动性吗?我们拭目以待。
参考链接:
https://busybox.net/
https://en.wikipedia.org/wiki/BusyBox