目錄
- 一、什么是 debugfs?
- 二、debugfs 的配置和啟用方式
- 2.1 內核配置選項
- 2.2 掛載 debugfs
- 2.3 Android 系統中的 debugfs
- 三、debugfs 的典型應用場景
- 3.1 調試驅動開發
- 3.2 內核子系統調試
- 3.3 性能分析
- 四、常見 debugfs 子目錄與功能示例
- 4.1 /sys/kernel/debug/tracing - 內核跟蹤核心目錄
- 4.2 /sys/kernel/debug/gpio - GPIO 狀態調試
- 4.3 /sys/kernel/debug/regulator - 電源調節器狀態
- 4.4 /sys/kernel/debug/dma_buf - DMA buffer 分析
- 4.5 /sys/kernel/debug/<自定義驅動名>/
- 五、調試案例:自定義驅動中使用 debugfs
- 六、debugfs 的工作原理和核心機制
- 七、核心 API 總覽
- 八、線上環境下的注意事項與安全性問題
- 8.1 信息泄露風險
- 8.2 系統穩定性風險
- 8.3 Android 安全限制節
- 九、補充:debugfs 與 procfs、sysfs 的區別
一、什么是 debugfs?
debugfs 是 Linux 內核提供的一個專用文件系統,主要用于內核與用戶空間之間的調試信息交換。它為內核開發人員或者驅動開發者提供了一種無需修改內核代碼即可獲取內部狀態的方式。
相比 /proc 和 /sys,debugfs 更偏向臨時調試用途,適合暴露實驗性、不穩定或僅用于開發階段的接口。
特點
:
動態創建、無需重新編譯內核。
文件操作接口簡單,可通過 shell 腳本或 C 語言輕松操作。
開發者常用于調試驅動、查看內部狀態、動態注入參數等。
二、debugfs 的配置和啟用方式
2.1 內核配置選項
要使用 debugfs,首先需要在編譯內核時啟用支持:
CONFIG_DEBUG_FS=y
如果你使用的是 Android 或嵌入式系統,也可在 menuconfig 中啟用:
Kernel hacking --->
[*] Debug Filesystem
此選項默認對主線內核是開啟的,但某些發行版或定制系統可能關閉以減小體積或提高安全性。
2.2 掛載 debugfs
一般系統啟動時不會自動掛載 debugfs,你可以手動掛載:
sudo mount -t debugfs none /sys/kernel/debug
也可以在啟動腳本中加入自動掛載邏輯:
if ! mountpoint -q /sys/kernel/debug; then mount -t debugfs none /sys/kernel/debug
fi
驗證:
ls /sys/kernel/debug/
輸出類似如下則表示掛載成功:
bdi/ clk/ gpio/ tracing/ suspend_stats ...
2.3 Android 系統中的 debugfs
Android 默認處于安全模式,大多數生產環境中是關閉的。可以通過如下方式在開發版系統中開啟:
adb shell
mount -t debugfs debugfs /sys/kernel/debug
部分 Android 內核會禁用 CONFIG_DEBUG_FS,需要通過修改 kernel defconfig 啟用并重新編譯。
三、debugfs 的典型應用場景
debugfs 通常用于以下幾個方面:
3.1 調試驅動開發
我們可以將調試信息、參數、狀態變量通過 debugfs 暴露出來,便于動態查看或調整,而無需反復修改內核代碼、重啟內核。例如:
讀取設備寄存器
控制調試開關(如 loglevel)
查看緩存、狀態統計信息等
3.2 內核子系統調試
很多內核子系統默認就通過 debugfs 暴露接口,例如:
tracing(ftrace)
gpio 狀態查看與操作
regulator 狀態與調節
DMA buf debug 信息
audio 子系統的 debug log(如 asoc)
3.3 性能分析
結合 ftrace(內核函數跟蹤器)可以做函數調用路徑分析、系統延遲檢測、實時調試。
四、常見 debugfs 子目錄與功能示例
4.1 /sys/kernel/debug/tracing - 內核跟蹤核心目錄
這是 ftrace 的主目錄,可以分析函數調用、調度、延遲等。常見文件:
available_tracers:可用的跟蹤器類型
current_tracer:當前啟用的跟蹤器
trace:跟蹤結果輸出
set_ftrace_filter:設置要跟蹤的函數
示例:
# 開啟函數跟蹤
echo function > /sys/kernel/debug/tracing/current_tracer
# 查看 trace 日志
cat /sys/kernel/debug/tracing/trace
4.2 /sys/kernel/debug/gpio - GPIO 狀態調試
查看系統中所有 GPIO 控制器和當前引腳狀態:
cat /sys/kernel/debug/gpio
輸出類似:
gpiochip0: GPIOs 0-31, parent: platform/10012000.gpio, gpio-controller
gpio-4 (sysfs ) out hi
gpio-17 (wifi_power ) out lo
4.3 /sys/kernel/debug/regulator - 電源調節器狀態
可查看/調試 regulator 驅動注冊的電壓、狀態等:
cat /sys/kernel/debug/regulator/ */status
cat /sys/kernel/debug/regulator/ */microvolts
4.4 /sys/kernel/debug/dma_buf - DMA buffer 分析
可用于分析圖形子系統中共享內存的引用情況:
cat /sys/kernel/debug/dma_buf/bufinfo
4.5 /sys/kernel/debug/<自定義驅動名>/
我們可以調用 debugfs_create_*
系列 API 在這里創建自己的調試目錄和接口,支持暴露:
整數、布爾變量
文件接口(read/write)
二進制 blob(例如 buffer dump)
五、調試案例:自定義驅動中使用 debugfs
一個簡單的例子:假如我們正在開發一個字符設備驅動,需要調試內部狀態:
#include <linux/debugfs.h>
static struct dentry *debug_dir;
static u32 debug_val = 0;
static int __init mydrv_init(void)
{debug_dir = debugfs_create_dir("mydrv", NULL);if (!debug_dir)return -ENOMEM;debugfs_create_u32("debug_val", 0644, debug_dir, &debug_val);return 0;
}
static void __exit mydrv_exit(void)
{debugfs_remove_recursive(debug_dir);
}
加載驅動后可直接查看或設置:
cat /sys/kernel/debug/mydrv/debug_val
echo 42 > /sys/kernel/debug/mydrv/debug_val
這比 printk + 重編譯 + 重啟流程更高效,尤其適合頻繁調試場景。
六、debugfs 的工作原理和核心機制
debugfs 實際上是一個虛擬文件系統(Virtual File System, VFS),類似于 /proc 和 /sys,其底層由內核代碼負責維護和注冊。
它的本質是
:
內核將特定結構體變量映射為文件或目錄,通過 file_operations 讓用戶空間可以讀寫這些內核變量或結構體。
關鍵實現機制
:
- debugfs_create_*() 系列 API 用于創建虛擬文件
- 每個文件背后對應一個 file_operations,封裝了 read/write 行為
- 這些文件操作最終在 debugfs 掛載點下暴露給用戶空間
例如,debugfs_create_u32("val", 0644, parent, &var)
就等價于暴露了一個變量 var 到文件系統中,可以直接讀寫。模塊注冊結構圖如下:
七、核心 API 總覽
基本語法格式:
API名稱 | 功能 |
---|---|
debugfs_create_dir(name, parent) | 創建子目錄 |
debugfs create file(name, mode, parent, data, fops) | 創建具備操作函數的文件 |
debugfs_create_u32(name, mode, parent, ptr) | 綁定變量為 u32 文件 |
debugfs_create bool(name, mode, parent, ptr) | 創建布爾值控制項 |
debugfs_remove(entry) | 刪除單個debugfs項 |
debugfs_remove_recursive(entry) | 遞歸刪除整個目錄樹 |
示例:綁定一個只讀的布爾變量
static bool debug_flag = true;
debugfs_create_bool("enable_debug", 0444, parent_dir, &debug_flag);
用戶空間讀取:
cat /sys/kernel/debug/mydrv/enable_debug
雖然 debugfs 極大地方便了開發與調試,但在生產環境下要慎用或禁用,主要原因包括:
八、線上環境下的注意事項與安全性問題
8.1 信息泄露風險
- debugfs 會暴露大量內核內部信息,黑客或惡意程序可借此探測系統結構。
- 某些接口甚至允許直接寫入數據,可能對系統穩定性產生影響。
8.2 系統穩定性風險
- 由于很多 debugfs 文件由開發者編寫,若實現不嚴謹可能導致 panic。
- 示例:越界訪問、沒有加鎖保護、引用了已釋放的結構體等。
8.3 Android 安全限制節
- Android 生產版默認關閉 debugfs
- SELinux 和 seccomp 等機制會阻止其掛載
推薦的安全策略:
- 線上系統關閉 CONFIG_DEBUG_FS,從內核構建階段禁止。
- 或者通過配置掛載權限為只讀,并結合 SELinux 限制訪問。
- 對自定義 debugfs 文件做好訪問控制,嚴格限制 read/write 權限。
九、補充:debugfs 與 procfs、sysfs 的區別
特性 | debugfs | procfs | sysfs |
---|---|---|---|
主要用途 | 調試/開發 | 進程信息 | 內核對象模型 |
是否穩定 | 否(可變) | 是 | 是 |
是否推薦線上啟用 | 否 | 是 | 是 |
是否支持驅動自定義接口 | 支持 | 支持但復雜 | 支持但需 class/device |