📝 本記事的內容
本記事是基於實際使用 MUSUBI(規格驅動開發框架)和 CodeGraph MCP Server 進行的 Linux 核心程式碼解析與轉換實驗結果,自動生成的文章。將透過實踐來闡述 AI 代碼代理如何理解大型代碼庫,以及如何實現 C 到 Rust 的轉換。
2025年12月,Linux 核心開發史上迎來了歷史性的瞬間。在年會 Maintainers Summit 中,對於核心中 Rust 的支持形成了共識,決定解除長期以來賦予的 「實驗性」標籤。
Linux 核心是用 C 語言編寫的,其歷史可以追溯到 1991 年 Linus Torvalds 的首次發布。然而,由於 C 語言的特性,與記憶體相關的錯誤(緩衝區溢出、使用後釋放、NULL 指標引用等)持續出現。
為了解決這一問題,自 2020年 開始啟動了「Rust for Linux」項目。Rust 是一種在語言層面保證記憶體安全性的編程語言,能夠阻止 C 語言中存在的許多脆弱性。
主要經過:
| 年 | 事件 |
|---|---|
| 2020年 | Rust for Linux 項目啟動 |
| 2022年 | 在 Linux 6.1 中首次合併 Rust 支援(附帶 experimental 標籤) |
| 2024年9月 | 微軟工程師 Wedson Almeida Filho 因「非技術性無稽之談」退出 |
| 2025年2月 | 核心維護者 Christoph Hellwig 將 Rust 代碼稱為「癌症」並拒絕 |
| 2025年12月 | 在 Maintainers Summit 上決定解除「實驗性」標籤 |
Linux 社群並非一片和諧。在對 Rust 的採用上,依然存在強烈的反對意見,並且推動派與反對派之間的爭論激烈。
反對派的代表人物,Christoph Hellwig 明言拒絕合併包括 Rust 的代碼,並聲稱:「如果不想讓 Linux 的維護變得不可能,就應該將這種『癌症』排除於核心子系統之外。」
然而,Linus Torvalds 基本上持續支持 Rust 的引入,最終在 2025年12月的 Maintainers Summit 上達成了如下共識:
「Rust 已經不再是實驗性的,而是核心的一部分,並且得到了廣泛的接受。」
— LWN.net "The (successful) end of the kernel Rust experiment"
此決定是 Linux 核心未來的一個重要轉折點。未來,驅動程式和子系統的 Rust 化將加速,期待推進一個更安全的核心。
為了紀念這一歷史性事件,本文將利用 AI 代碼代理(GitHub Copilot + MUSUBI) 和 代碼解析工具(CodeGraph MCP Server),進行 Linux 核心的 C 代碼轉換為 Rust 的實驗。
這些問題將透過實踐來進行解答。
Linux 核心已有超過 30 年的歷史,即以 C 語言開發。C 語言在低層硬體控制上表現優秀,能提供極高的效能,但卻存在記憶體安全性的根本問題。
| 脆弱性類型 | 說明 | 影響 |
|---|---|---|
| 緩衝區溢出 | 超過數組邊界的訪問 | 任意代碼執行、權限提升 |
| 使用後釋放 | 訪問已釋放的記憶體 | 資訊洩漏、崩潰 |
| 雙重釋放 | 同一記憶體被釋放兩次 | 堆破壞、任意代碼執行 |
| NULL 指標引用 | 解參考無效的指標 | 核心恐慌 |
| 數據競爭 | 來自多線程的同時訪問 | 無法預測的行為 |
微軟 Azure 的 CTO Mark Russinovich 在 2022 年表示:
「為了安全與可靠性,業界應該淘汰 C/C++。」
該觀點得到全球許多政府安全機構的支持,轉向記憶體安全的語言已成為整個行業的趨勢。
Rust 是一種在編譯時保證記憶體安全性的編程語言。其所有權系統(Ownership)和借用檢查器(Borrow Checker)幫助在編譯時檢測並防止大部分上述脆弱性。
// 在 Rust 中,使用後釋放會導致編譯錯誤
fn example() {
let data = vec![1, 2, 3];
let reference = &data;
drop(data); // 此時釋放了數據
// println!("{:?}", reference); // 編譯錯誤!
}
Rust for Linux 專案在於要解決一個從未有過的挑戰,就是讓現有的 C 代碼庫與 Rust 共存。
1. FFI(外部函數介面)的複雜性
從 Rust 呼叫 C 函數需要 unsafe 區塊。需要為核心中龐大的 C API 建立安全的包裝器(抽象層)。
// 從 Rust 呼叫 C 的 DMA API
unsafe {
let ptr = dma_alloc_coherent(dev, size, &mut dma_handle, GFP_KERNEL);
// ...
}
2. 建構系統的整合
Linux 核心使用 Kbuild 作為其獨特的建構系統。需要將 Rust 的編譯器(rustc)和 Cargo 整合到這個系統中。
3. ABI(應用二進制介面)兼容性
C 和 Rust 的結構體在記憶體布局上可能會有差異,需要明確指定 #[repr(C)] 屬性以保證 C 兼容布局。
與技術挑戰相比,社群內的意見分歧 讓人更感困難。
正如 Christoph Hellwig 的發言所表明,一些維護者對多語言項目的可維護性表示強烈擔憂。
「請不要讓我負責的領域污染這種『當今流行語言』。多語言項目的維護真的是一種折磨。」
— Christoph Hellwig, Linux Kernel Mailing List
另一方面,Linus Torvalds 在 2024 年的開源峰會維也納上如此表示:
「顯而易見有人不喜歡 Rust,並害怕它會侵入自己的領域。(中略)即使失敗也是一種學習,但我不認為這會失敗。」
截至2025年12月,以下驅動程式和模組已納入 主線(官方核心):
| 驅動程式/模組 | 說明 |
|---|---|
| Android Binder Driver | Android 的 IPC 機制 |
| Null Block Driver | 測試用的塊設備 |
| ASIX PHY Driver | 網絡 PHY 驅動 |
| AMCC QT2025 PHY Driver | 網絡 PHY 驅動 |
| DRM Panic QR code generator | 核心恐慌時的 QR 代碼生成 |
| Nova GPU Driver | NVIDIA GPU 驅動 |
| Tyr GPU Driver | GPU 驅動 |
此外,在主線外,以下項目也正在進行中:
在進行 Linux 核心的 C 代碼轉寫為 Rust 的實驗中,以下三種工具將會被使用。
MUSUBI(結合)是一個全方位的 規格驅動開發(SDD: Specification Driven Development) 框架,專為 AI 編碼代理而設計。
| 特點 | 說明 |
|---|---|
| 🤖 支援七種 AI 代理 | Claude Code, GitHub Copilot, Cursor, Gemini CLI, Codex CLI, Qwen Code, Windsurf |
| 📋 27 種專業技能 | 要求分析、系統設計、代碼實作、測試、安全審核等 |
| ⚖️ 憲法性治理 | 由 9 條不變條款確保質量 |
| 🦀 提供 Rust 移轉支援 | C/C++ 從遷移優先級評分功能 |
MUSUBI 依據以下 9 條條款來確保質量。
MUSUBI v5.6.0 更新中添加了 Rust 移轉產生器。
// 偵測 C/C++ 代碼中的 unsafe 模式並評分 Rust 移轉的優先級
const { LargeProjectAnalyzer } = require('musubi-sdd');
const analyzer = new LargeProjectAnalyzer('/path/to/linux');
const result = await analyzer.analyze();
// -> { totalFiles: 109073, unsafePatterns: [...], migrationPriority: [...] }
這使得如 Linux 核心這樣的大型專案能夠優先確定應該從哪段代碼開始進行 Rust 化。
CodeGraph MCP Server 是一個符合 MCP(模型上下文協議)標準的輕量級、高效能源代碼解析伺服器。
| 特點 | 說明 |
|---|---|
| 🚀 零配置 | 無需外部數據庫,於虛擬環境中使用 pip install 即可立即開始 |
| 🌳 AST 解析 | 透過 Tree-sitter 提供快速且精確的代碼解析 |
| 🔗 圖形構建 | 代碼實體之間的關係以圖形化表示 |
| 🔍 14 種 MCP 工具 | 依賴關係分析、調用追蹤、代碼搜索 |
| 🌐 支持 16 種語言 | 包含 C、C++ 在內的 16 種語言 |
# 建立 Python 虛擬環境
python3 -m venv .venv
source .venv/bin/activate # Linux/macOS
# 使用 pip 安裝
pip install codegraph-mcp-server
Python, TypeScript, JavaScript, Rust, Go, Java,
PHP, C#, C, C++, HCL (Terraform), Ruby,
Kotlin, Swift, Scala, Lua
由於支援 C 和 C++,因此非常適合進行 Linux 核心代碼的解析。
| 類別 | 工具 | 用途 |
|---|---|---|
| 圖形查詢 | query_codebase |
自然語言查詢代碼圖 |
find_dependencies |
偵測實體之間的依賴關係 | |
find_callers |
偵測函數/方法的調用者 | |
find_callees |
偵測函數/方法的被調用者 | |
| 代碼檢索 | get_code_snippet |
獲取實體的源代碼 |
read_file_content |
獲取文件內容 | |
| GraphRAG | global_search |
跨社區的全局搜索 |
local_search |
偵測實體鄰近的本地搜索 |
| 指標 | 實測值 |
|---|---|
| 索引速度 | 32 實體/秒 |
| 文件處理速度 | 0.44 秒/文件 |
| 增量索引 | 少於 2 秒 |
| 查詢響應 | 少於 2ms |
在像 Linux 核心這樣超過 10 萬行的專案中,也能在 10 分鐘內完成初步索引。
在本文中,我們將使用 GitHub Copilot 作為 AI 代碼代理。
# 初始化 MUSUBI 以用於 GitHub Copilot
npx musubi-sdd init --copilot
# 將生成以下內容:
# .github/prompts/ - 客製化提示
# .github/AGENTS.md - 27 種技能定義
# steering/ - 專案記憶體
| 命令 | 用途 |
|---|---|
#sdd-steering |
生成/更新專案記憶體 |
#sdd-requirements <功能> |
生成 EARS 格式的要求 |
#sdd-design <功能> |
C4 模型 + ADR 的設計 |
#sdd-tasks <功能> |
拆分成任務 |
#sdd-implement <功能> |
執行實作 |
#sdd-validate <功能> |
驗證憲法符合性 |
在 VS Code 的設置檔(.vscode/settings.json)中配置 MCP 伺服器:
{
"mcp.servers": {
"codegraph": {
"command": "codegraph-mcp",
"args": ["serve", "--repo", "${workspaceFolder}"]
}
}
}
這樣可讓 GitHub Copilot 利用 CodeGraph MCP Server 的工具,理解 Linux 核心的代碼結構,並協助轉換成 Rust。
| 層次 | 組件 | 角色 |
|---|---|---|
| AI 代理 | GitHub Copilot | 執行代碼生成及轉換 |
| SDD 框架 | MUSUBI | 27 種技能、憲法性治理、Rust 移轉支援 |
| 代碼解析 | CodeGraph MCP Server | AST 解析、依賴關係圖、GraphRAG 搜尋 |
| 目標 | Linux 核心原始碼 | C 語言 → Rust 的轉換 |
接下來將說明重現本文實驗的環境建置步驟。
| 項目 | 要求 |
|---|---|
| 作業系統 | Linux(建議使用 Ubuntu 22.04 以上)或 macOS |
| Python | 3.11 以上 |
| Node.js | 18.0 以上 |
| Git | 2.30 以上 |
| 儲存空間 | 20GB 以上(用於 Linux 核心原始碼) |
| 編輯器 | VS Code + GitHub Copilot 擴充功能 |
# 創建工作目錄
mkdir -p ~/linux-rust-experiment
cd ~/linux-rust-experiment
# 創建 Python 虛擬環境
python3 -m venv .venv
source .venv/bin/activate
# 安裝 CodeGraph MCP Server
pip install codegraph-mcp-server
# 驗證安裝
codegraph-mcp --version
# 使用 npx 為 GitHub Copilot 初始化 MUSUBI
npx musubi-sdd init --copilot
# 或者可以進行全域安裝
npm install -g musubi-sdd
musubi init --copilot
初始化完成後,將生成以下目錄結構。
~/linux-rust-experiment/
├── .github/
│ ├── prompts/ # 客製化提示
│ └── AGENTS.md # 27 種技能定義
├── steering/
│ ├── project.yml # 專案設定
│ ├── structure.md # 架構模式
│ ├── tech.md # 技術棧
│ ├── product.md # 產品上下文
│ └── rules/
│ └── constitution.md # 9 條憲法條款
├── templates/ # 文件模板
└── storage/ # 規格/變更/功能的保存位置
# 克隆 Linux 核心原始碼(淺克隆以加快速度)
git clone --depth 1 https://github.com/torvalds/linux.git
# 確認克隆後的大小
du -sh linux/
# -> 約 1.5GB
提示: 使用 --depth 1 參數可以僅獲取最新提交,顯著降低克隆時間及磁碟使用量。
# 確保虛擬環境是活動狀態
source .venv/bin/activate
# 為 Linux 核心原始碼創建索引(全索引)
codegraph-mcp index ./linux --full
# 創建索引大約需要 10 分鐘
# 完成後檢查統計
codegraph-mcp stats ./linux
輸出範例如下:
Repository Statistics
=====================
Repository: ./linux
Entities: 245,832
Relations: 1,234,567
Communities: 0
Files: 78,234
Entities by type:
- function: 198,456
- struct: 23,456
- macro: 12,345
- enum: 5,678
- typedef: 4,567
- variable: 1,330
# 測試啟動 MCP 伺服器
codegraph-mcp serve --repo ./linux
# 在另一個終端進行檢查(使用 Ctrl+C 結束)
創建或編輯 .vscode/settings.json:
{
"mcp.servers": {
"codegraph": {
"command": "codegraph-mcp",
"args": ["serve", "--repo", "${workspaceFolder}/linux"]
}
}
}
所有設置完成後,執行以下命令確認操作情況。
# 確認 MUSUBI 的狀態
musubi status
預期輸出:
📊 MUSUBI 專案狀態
✅ MUSUBI 已初始化
📁 GitHub Copilot 技能: 27 項已安裝 (AGENTS.md)
位置: .github/
🧭 引導上下文:
✅ structure.md (更新於: 2025-12-18)
✅ tech.md (更新於: 2025-12-18)
✅ product.md (更新於: 2025-12-18)
✅ 憲法性治理: 已啟用
💡 下一步:
- 查看引導檔案在 steering/
- 創建要求: #sdd-requirements [功能]
- 驗證符合性: musubi validate
| 步驟 | 命令 | 所需時間 |
|---|---|---|
| 1. Python 虛擬環境 + CodeGraph | python3 -m venv .venv && pip install codegraph-mcp-server |
約 1 分 |
| 2. MUSUBI 初始化 | npx musubi-sdd init --copilot |
約 30 秒 |
| 3. 獲取 Linux 核心 | git clone --depth 1 https://github.com/torvalds/linux.git |
約 5 分 |
| 4. 創建索引 | codegraph-mcp index ./linux --full |
約 10 分 |
| 合計 | 約 17 分 |
這樣一來,我們就準備好使用 AI 代理來解析及轉換 Linux 核心代碼了。
接下來將使用 CodeGraph MCP Server,解析 Linux 核心的代碼結構,並選擇可以轉換為 Rust 的對象。
針對 Linux 核心原始碼創建索引後,得到了以下統計信息。
$ codegraph-mcp stats ./linux
Repository: linux
Entities: 2,887,137
Relations: 6,154,983
Communities: 315
Files: 63,206
Entities by type:
- function: 702,410
- struct: 2,112,696
- module: 63,208
- method: 7,360
- class: 1,218
- trait: 166
- enum: 79
驚人的規模: Linux 核心包含 超過 70 萬個函數 和 超過 211 萬個結構體 的定義。AI 代理之所以能理解這龐大的代碼庫,得益於 CodeGraph MCP Server 的圖形結構。
Linux 核心已經包含了一些用 Rust 編寫的範例代碼。
$ ls linux/samples/rust/
Kconfig rust_driver_auxiliary.rs rust_driver_usb.rs
Makefile rust_driver_faux.rs rust_i2c_client.rs
hostprogs/ rust_driver_i2c.rs rust_minimal.rs
rust_configfs.rs rust_driver_pci.rs rust_misc_device.rs
rust_debugfs.rs rust_driver_platform.rs rust_print_events.c
rust_debugfs_scoped.rs
rust_dma.rs
這些範例對於學習 C 轉 Rust 的轉換模式十分有參考價值。
作為 Rust 的轉換目標,我們選定了以下標準:
| 標準 | 理由 |
|---|---|
| 代碼行數少於 100 行 | 適合作為實驗的大小 |
| 外部依賴少 | 降低轉換的複雜性 |
| 包含記憶體操作 | 展示 Rust 的安全性優勢 |
| 使用核心 API | 學習實際的驅動模式 |
dummy-irq.c經過分析,選定了 drivers/misc/dummy-irq.c 作為轉換對象。
文件信息:
| 項目 | 值 |
|---|---|
| 路徑 | linux/drivers/misc/dummy-irq.c |
| 行數 | 61 行 |
| 函數數 | 3 個 |
| 用途 | 假中斷的調試用處理器 |
選定理由:
request_irq(), free_irq(), 模組參數// linux/drivers/misc/dummy-irq.c
// SPDX-License-Identifier: GPL-2.0-only
#include <linux/module.h>
#include <linux/irq.h>
#include <linux/interrupt.h>
static int irq = -1;
static irqreturn_t dummy_interrupt(int irq, void *dev_id)
{
static int count = 0; // ⚠️ 靜態變量: 非線程安全
if (count == 0) {
printk(KERN_INFO "dummy-irq: interrupt occurred on IRQ %d\n", irq);
count++;
}
return IRQ_NONE;
}
static int __init dummy_irq_init(void)
{
if (irq < 0) {
printk(KERN_ERR "dummy-irq: no IRQ given. Use irq=N\n");
return -EIO;
}
// ⚠️ 錯誤處理: 雖然檢查返回值,但在 C 中不具類型安全性
if (request_irq(irq, &dummy_interrupt, IRQF_SHARED, "dummy_irq", &irq)) {
printk(KERN_ERR "dummy-irq: cannot register IRQ %d\n", irq);
return -EIO;
}
printk(KERN_INFO "dummy-irq: registered for IRQ %d\n", irq);
return 0;
}
static void __exit dummy_irq_exit(void)
{
printk(KERN_INFO "dummy-irq unloaded\n");
free_irq(irq, &irq);
}
module_init(dummy_irq_init);
module_exit(dummy_irq_exit);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Jiri Kosina");
module_param_hw(irq, uint, irq, 0444);
MODULE_PARM_DESC(irq, "The IRQ to register for");
MODULE_DESCRIPTION("Dummy IRQ handler driver");
| 問題 | C 中的情況 | Rust 的解決方案 |
|---|---|---|
| 靜態變量的線程安全性 | static int count 可能發生競爭狀態 |
使用 AtomicI32 或 Mutex 進行保護 |
| 錯誤處理 | 可能會忽略返回值 | 使用 Result<T, E> 強制執行 |
| 忘記釋放資源 | 可能會遺漏 free_irq |
透過 Drop 特徵自動釋放 |
| 類型安全性 | void *dev_id 無類型資訊 |
使用泛型提高類型安全性 |
在進行轉換前,可以參考 samples/rust/rust_minimal.rs 的結構。
// linux/samples/rust/rust_minimal.rs
use kernel::prelude::*;
module! {
type: RustMinimal,
name: "rust_minimal",
authors: ["Rust for Linux Contributors"],
description: "Rust minimal sample",
license: "GPL",
params: {
test_parameter: i64 {
default: 1,
description: "This parameter has a default of 1",
},
},
}
struct RustMinimal {
numbers: KVec<i32>,
}
impl kernel::Module for RustMinimal {
fn init(_module: &'static ThisModule) -> Result<Self> {
pr_info!("Rust minimal sample (init)\n");
// ... 初始邏輯
Ok(RustMinimal { numbers })
}
}
impl Drop for RustMinimal {
fn drop(&mut self) {
pr_info!("Rust minimal sample (exit)\n");
// 自動釋放資源
}
}
C 和 Rust 的對應關係:
| C | Rust |
|---|---|
module_init() / module_exit() |
fn init() / fn drop() |
printk(...) |
pr_info!(...) |
request_irq(...) |
request_irq(...) |
free_irq(...) |
free_irq(...) |