我們選擇 panda 配置並沒有特別的原因——任何其他配置也同樣適用。核心程式碼是用 C 語言編寫的,它源自 Linux 核心。因此,我們的方法也適用於通用 Linux 核心的任何配置。
現在我們都知道 C/C++ 是一門複雜的語言,因此我們預料到分析會很困難。但這種困難僅僅是指解析器。有了 Clang 解析器,我們信心十足,並且很高興沒有遇到任何問題。我們的目標是檢查 panda 配置中所有的 C/C++ 原始檔,並理解它們之間的相互關係。為此,有必要弄清楚哪些檔案被包含或排除在 panda 構建之外。然後,還有如何處理所有檔案的編譯、包含和連結問題。這些都需要花費精力。最終的結果顯示了 Linux 核心的耦合程度有多高。
首先,我們必須承認 Linux 核心是編寫得很好的。進入核心的內容受到嚴格控制。考慮到它在全球 IT 基礎設施中的重要性,這正是人們所期望的。我們還應該記住,當今使用的許多模組化機制都源於 Unix。裝置驅動程式插入作業系統的概念由 Unix 推廣,並已在今天司空見慣。應用程式管道也是 Unix 的創舉。然而,Linux 核心本身的模組化卻很差。
部分問題在於,當 Unix/Linux 核心被開發時,程式語言對模組化的支援很差。例如,C 語言沒有介面的概念,因此自然不支援依賴倒置(儘管這是可以實現的)。而且,Linux 沒有真正的模組化機制來驗證或強制執行模組化。
在應用了分割槽演算法之後,一些事情變得顯而易見。這個分割槽演算法根據依賴關係對子系統進行重新排序,揭示了哪些是“底層”,哪些是“高層”。在理想的實現中,高層的開發人員只需要理解底層的 API,而底層的開發人員只有在介面受到影響時才需要擔心高層。在一個耦合的系統中,開發人員需要同時理解兩個層次,這使得理解變更所帶來的影響變得相當困難。事實上,在 Android 核心中,幾乎所有的層次都是耦合的,開發人員有時可能需要理解數千個檔案才能對自己的更改有信心。
這也意味著分解的初衷已經喪失。例如,'arch.arm' 與 'kernel' 緊密耦合,以至於開發人員很難在不理解另一個的情況下理解其中一個。注意,即便是 'drivers' 也與系統的其餘部分耦合。我曾嘗試為驅動程式的基礎層建立一個獨立的層次,甚至移動了一些基礎驅動程式,如 'char' 和 'tty',但耦合依然存在。遺憾的是,即使是一些較新的驅動程式也與核心耦合。
所有這些都表明,除非重點關注架構的定義和驗證,否則即使是管理得最好的軟體系統也會隨著時間的推移而經歷架構腐蝕。
附件:[分析 Android 核心.png]