上期文章中,筆者向各位介紹了 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