總所周知,Linux 內核以 GNU 通用公共許可證第二版(GPL V2)的授權使用協議下發行。GNU 通用公共許可證是一種 「Copyleft」 形式的「版權」,保障任何人都能夠對 Linux 內核以及其衍生產品的使用、修改和重新發布的權力,前題是不能修改發布條款。什麼意思呢,任何 Linux 內核的衍生產品(Derived Work)必須遵循 GPL 協議進行發布。然而問題的核心在於什麼是 Linux 內核的衍生產品,其中有幾個致命問題,業界爭論了十年有多。
1、使用 Linux 內核的頭文件定義,進行系統調用的程序是否會被定性為衍生產品?
2、鏈接使用了其他 GPL 的類庫的程序是否會被定性為衍生產品?
3、Linux 內核動態載入的模塊 LKM(Loadable Kernel Modules)是否會被定性為衍生產品,以 LKM 形式開發的 Linux 驅動程序是不是衍生產品?
If a library is released under the GPL (not the LGPL), does that mean that any software which uses it has to be under the GPL or a GPL-compatible license? (#IfLibraryIsGPL)
Yes, because the software as it is actually run includes the library。
然而,在移動互聯網蓬勃發展的今天,一個 Linux 的發布版本,Android 在各種智能嵌入式設備上面大放異彩。據說,Android 之父 Andy Rubin 極度厭惡 GPL(James Bottomley,Linux SCSI 子系統的維護者說其人「Working from an extreme dislike of the GPL」),然而 Android 向世人展示了採用 GPL 授權代碼的手機也能獲得巨大的市場成功。
Android:把 GPL 局限在內核空間
下圖是 Openfoundry 繪製的 Android 的授權許可證結構,可以看到在 Android 多層軟體棧中,僅僅最核心的 Linux 內核使用了 GNU 通用公共許可證,在這個層次上,Google 對 Linux 內核的所有修改必須反饋回 Linux 主版本樹(Android 的內核將在 Linux 3.3 版本進行回歸,兩個版本的 Linux 內核進行融合)。
Android 的 Bionic Libc 的類庫,採用 BSD 的許可證授權。在 2008 年 Google IO大會上,一份著名的 PPT:「 Android Anatomy And Physiology 」講到 Android 使用 Bionic Libc 類庫替換Linux常用的 Gnu glibc ,其中一個主要原因是 「 We want to keep GPL out of user-space 」。(這其實有點難理解,畢竟 Gnu glibc 採用的是 LGPL 而非 GPL,並基於上文 GPL 第一點的討論,使用系統調用的程序不再被視為 Linux 內核的衍生產品,並不需要遵循 GPL,有興趣者請看下文用戶空間驅動部分的分析) 。Bionic Libc 充滿著非議,Bionic Libc 拷貝內核頭文件的行為,並在源碼中聲明的版權信息均遭到了 「 侵犯 Linux 內核 GPL 約束 」 的質疑。這是 Bionic 頭文件的版權信息,許多人認為是非法的:
「This header was automatically generated from a Linux kernel header of the same name, to make information necessary for userspace to call into the kernel available to libc. It contains only constants, structures, and macros generated from the original header, and thus, contains no copyrightable information。」
We should also design more 「bright line」 systems which make the question of GPL compliance clear. The kernel』s user-space ABI is one such system; developers know that user-space code is not considered to be derived from the kernel. Making the boundary easy to understand helps to make the GPL less scary。
Linux 是單內核操作系統(Macrokernel),這種操作系統的一大特點是驅動存活在內核,優點是驅動與系統內核共生在相同的地址空間,運作的效率比較高,缺點是當驅動有問題的時候,容易危及內核的工作安全。用戶區間驅動的思路是將驅動的主要業務邏輯剝離出來放到用戶空間的主驅動模塊中,內核中的驅動是個 「影子」驅動,只有透傳控制命令和數據的功能。
Android 的 HAL 相當於上圖中的主驅動,其在內核中的驅動相當於上圖中的影子驅動。規避 GPL 的硬體廠家把需要保護的商業機密以及知識產權相關的邏輯放在 HAL 層,以二進位包的方式發布,不需要公開源代碼。
這種機制看上去很美,然而,同樣面臨著巨大的爭議。HAL 類庫與內核驅動之間通過普通的系統調用能夠完成么?如果不是普通的系統調用,用戶空間的驅動就違反了上文中的第一條,用戶空間的驅動不能獲得 GPL 例外的豁免。Edward J. Naughton 2011 年 3 月撰文認為,普通的系統調用應被理解為 gnu glibc 向外暴露的系統調用介面,而 Android 通過 Bionic libc 類庫暴露了更多的介面,包括原來在內核空間才能使用的介面,其目的是為了讓用戶空間的驅動能夠充分的利用內核和硬體資源。如果情況果真如此,Bionic libc類庫是 Google 的後門,這也可能 Android 拋棄使用 gnu glibc 重寫 Bionic libc 的其中一個主要原因。Edward J. Naughton 說:
Some of the calls exposed by Bionic are ordinarily not available to userspace because they』re excluded by the use of the #ifdef __KERNEL__ … #endif guards. If Google can define any call to the kernel from userspace as a 「normal system call」 (even those system calls ostensibly guarded by kernel matainers) simply by including it in its new C library, then a 「normal system call」 becomes whatever Google (or Oracle or Microsoft) wants it to be。
Bionic 暴露了原來在用戶空間不能使用的函數調用,這些調用原本在代碼中被 __KERNEL__ 的宏定義保護其運行在內核狀態。如果Google 只要將在 Bionic 添加暴露的介面就可以自由的暴露 Linux 系統調用(這些系統調用明顯應該由 Linux 內核社區維護),那麼難免被其他人效仿。
總結
總得說來,Android 為 GPL 下的 Linux 如何與商業社會並存與共贏提供了一個成功的範本,嘗試為 Linux 生態系統上的各種角色劃清彼此的作用範圍,梳理了各方在版權上的權利和義務,目前看來獲得了驚人的商業成功。然而,這種工作模式也面臨著巨大的版權爭議,理論上存在一種可能,一旦版權模式被否決,將面臨被全盤否定的災難。