Linux 原始碼樹將與架構無關的子系統、架構移植、公開使用者空間介面、產生的建置狀態、工具與測試分開。目錄名稱是導覽輔助,而非執行模型:Kconfig 選取設定,Kbuild 選取物件,而所選物件決定哪些內容會進入特定核心映像。
頂層子系統邊界 #
主要原始碼目錄如下:
| 路徑 | 職責 |
|---|---|
arch/ | 架構移植、開機程式碼、MMU 與中斷進入,以及低階 ABI 支援。 |
block/、fs/、mm/、net/ | 區塊層;VFS 與檔案系統實作;虛擬與實體記憶體管理;以及網路堆疊。 |
kernel/、init/、ipc/、security/ | 核心排程、鎖定、訊號、追蹤與其他核心功能;早期初始化;IPC;以及 Linux Security Module 基礎結構。 |
drivers/、sound/、virt/ | 裝置驅動程式、聲音子系統與 KVM 等虛擬化支援。驅動程式不一定公開 struct file_operations;子系統特定的匯流排與回呼也很常見。 |
crypto/、lib/、io_uring/、rust/ | 共用密碼編譯與函式庫支援、非同步 I/O,以及 Rust 核心支援。 |
include/、Documentation/、scripts/ | 標頭、維護中的文件,以及 Kbuild/Kconfig 加上產生與維護工具。 |
tools/、samples/、usr/ | perf 等使用者空間工具、範例程式,以及內建 initramfs 產生。 |
其他頂層內容,例如 certs/ 與 LICENSES/,支援簽署、授權或建置原則。原始碼檢出內容會隨時間變更,因此請檢查其中的頂層 README、MAINTAINERS 與 Documentation/,不要假設每個版本都包含相同目錄。
Kbuild 彙總與最終連結 #
Kbuild 讀取 Makefile 或 Kbuild 檔案,並評估 obj-$(CONFIG_FOO) 項目。y 選取內建物件,m 選取可載入模組,未設定的符號則兩者皆不選。當建置向下進入所選目錄時,會將 obj-y 物件組合成精簡的 built-in.a 封存。這些封存與其他所選物件之後會連結至 vmlinux;模組則遵循分開的連結路徑。
順序很重要,因為 Kbuild 文件 定義封存與最終連結行為,包括初始化順序。因此,目錄不會只因為具有 built-in.a 就成為自足的「模組」:設定與父 Makefile 控制是否造訪該目錄,以及其物件是否進入最終映像。
透過設定與建置規則追蹤功能:
git grep -n 'CONFIG_FOO'
git grep -n 'obj-$(CONFIG_FOO)'在根據符號搜尋得出結論前,請閱讀周圍的 Kconfig 與 Makefile 項目,因為條件編譯、產生的標頭、架構覆寫與連結順序可能選取另一個實作。
標頭系列與使用者空間 ABI #
核心私有、使用者空間可見、架構特定與產生的標頭分開保存:
| 路徑 | 用途 |
|---|---|
include/ | 與架構無關的核心內部標頭。 |
include/uapi/ | 與架構無關的使用者空間 ABI 標頭。 |
arch/<arch>/include/ | 架構特定的核心內部標頭。 |
arch/<arch>/include/uapi/ | 架構特定的使用者空間 ABI 標頭。 |
include/generated/ 與 arch/<arch>/include/generated/ | 建置產生的標頭。 |
make headers_install 會匯出經過清理的 UAPI 標頭集合。應用程式應使用作業系統或工具鏈提供的已安裝標頭,而不是核心檢出中的任意內部標頭;task_struct 等結構不是穩定的使用者空間介面。標頭安裝文件 定義受支援的匯出操作。
產生狀態與輸出樹 #
設定會寫入 .config,並在編譯前產生標頭。Kbuild 可以將產生的檔案與物件放在分開的輸出目錄:
make O="$PWD/out" defconfig
make O="$PWD/out" -j"$(nproc)"樹外建置會使產生的狀態離開檢出,但來源樹與輸出樹仍透過設定、產生的標頭與相依性中繼資料耦合。移動或部分複製輸出目錄後,請重新設定,不要依賴增量建置的舊相依性狀態。
尋找程式碼與準備索引 #
MAINTAINERS 記錄子系統所有權與偏好的修補程式路由資訊。請遵循受影響子系統的流程與文件,而不要將整棵樹視為由單一中央擁有的程式;維護者手冊 彙整子系統特定的指引。
先從宣告與子系統文件開始尋找實作,接著搜尋定義:
git grep -n 'SYSCALL_DEFINE.*openat'
git grep -n 'struct file_operations'編輯器索引受益於刻意排除,因為 tools/、產生的輸出與建置成品可能遮蔽核心空間結果。例如:
{
"C_Cpp.default.includePath": ["${workspaceFolder}/include"],
"search.exclude": {
"**/tools/**": true,
"**/include/generated/**": true,
"**/out/**": true
}
}調查使用者空間工具或產生的介面時,不要盲目排除路徑。排除是索引選擇,而 Kconfig 與 Kbuild 路徑仍是核心建置內容的證據。
評論
在 GitHub 上閱讀或評論(發表評論需要登入)