linux内核 DebugFS
點擊打開鏈接
一、簡介
DebugFS,顧名思義,是一種用于內核調試的虛擬文件系統,內核開發者通過debugfs和用戶空間交換數據。類似的虛擬文件系統還有procfs和sysfs等,這幾種虛擬文件系統都并不實際存儲在硬盤上,而是Linux內核運行起來后才建立起來。
通常情況下,最常用的內核調試手段是printk。我們在調試時可能需要修改某些內核變量,這種情況下printk就無能為力,而如果為了修改某個值重新編譯內核或者驅動又過于低效,此時就需要一個臨時的文件系統可以把我們需要關心的數據映射到用戶空間。不論是procfs或是sysfs,用它們來實現某些debug的需求,似乎偏離了它們創建的本意。比如procfs,其目的是反映進程的狀態信息;而sysfs主要用于Linux設備模型。不論是procfs或是sysfs的接口應該保持相對穩定,因為用戶態程序很可能會依賴它們。當然,如果我們只是臨時借用procfs或者sysfs來作debug之用,在代碼發布之前將相關調試代碼刪除也無不可。但如果相關的調試借口要在相當長的一段時間內存在于內核之中,就不太適合放在procfs和sysfs里了。故此,debugfs應運而生。
默認情況下,debugfs會被掛載在目錄/sys/kernel/debug之下,如果你的發行版里沒有自行掛載,可以用下面命令手動完成:
mount -t debugfs none /sys/kernel/debug
二、打開debugfs選項
要使用debugfs,首先我們要設置一下配置選項CONFIG_DEBUG_FS,可以在config文件中設置CONFIG_DEBUG_FS=y,也可以通過menuconfig來設置
Kernelhacking --->
????????????????????????? [*]Debug Filesystem
并且驅動中使用debugfs需要包含頭文件<linux/debugfs.h>,為了在用戶態下使用debugfs,必須把它mount到一個目錄下
三、Llinux內核為debugfs提供了非常簡潔的API:
debugfs
|--mydebug
?? |--subdir
????? c
?? a
?? b
1、創建和撤銷目錄及文件
第一個參數是目錄的名稱,第二個參數是指定這個目錄的上級目錄,如果是NULL,表示放在debugfs的根目錄下
my_debugfs_root = debugfs_create_dir("mydebug", NULL);
sub_dir = debugfs_create_dir("subdir", my_debugfs_root);
debugfs
|--mydebug
?? |--subdir
2)structdentry *debugfs_create_file(constchar*name, mode_t mode,structdentry *parent,void*data,conststructfile_operations *fops);
文件c通過自定義的文件操作實現讀寫
debugfs
|--mydebug
?? |--subdir
????? c
[cpp]?view plaincopy
3)voiddebugfs_remove(structdentry *dentry);4)voiddebugfs_remove_recursive(structdentry *dentry);
在module_exit中,我們要釋放創建的數據
debugfs_remove_recursive(my_debugfs_root);
這個函數可以幫我們逐步移除每個分配的dentry,如果你想要一個個手動移除,也可以直接調用debugfs_remove
2、創建單值文件
1)structdentry *debugfs_create_u8(constchar*name, mode_t mode,structdentry *parent, u8 *value);
debugfs_create_u8("a", 0644, my_debugfs_root, &a);
debugfs
|--mydebug
?? |--subdir
?? a
創建的文件名是a,對應內核中的變量名為a,文件屬性為0644,可以對文件讀寫,相當于是對內核變量讀寫。
2)structdentry *debugfs_create_u16(constchar*name, mode_t mode,structdentry *parent, u16 *value);3)structdentry *debugfs_create_u32(constchar*name, mode_t mode,structdentry *parent, u32 *value);4)structdentry *debugfs_create_u64(constchar*name, mode_t mode,structdentry *parent, u64 *value);其中,后綴為x8、x16、x32的這三個函數是指debugfs中的數據用十六進制表示。?5)structdentry *debugfs_create_x8(constchar*name, mode_t mode,structdentry *parent, u8 *value);6)structdentry *debugfs_create_x16(constchar*name, mode_t mode,structdentry *parent, u16 *value);7)structdentry *debugfs_create_x32(constchar*name, mode_t mode,structdentry *parent, u32 *value);8)structdentry *debugfs_create_size_t(constchar*name, mode_t mode,structdentry *parent,size_t*value);9)structdentry *debugfs_create_bool(constchar*name, mode_t mode,structdentry *parent, u32 *value);
3、創建BLOB文件
structdebugfs_blob_wrapper {????void*data;????unsignedlongsize;};structdentry *debugfs_create_blob(constchar*name, mode_t mode,structdentry *parent,structdebugfs_blob_wrapper *blob);
char hello[32] = "hello world!\n";
struct debugfs_blob_wrapper b;
b.data = (void *)hello;
b.size = strlen(hello) + 1;
debugfs_create_blob("b", 0644, my_debugfs_root, &b);
debugfs
|--mydebug
?? |--subdir
?? b
需要注意的是blob wrapper定義的數據只能是只讀的,在本例中我們將文件b的權限設定為0644,但實際這個文件還是只讀的,
如果試圖改寫這個文件,系統將提示出錯。
因此,如果我們要對內核數組進行讀寫動作,blob wrapper就無法滿足要求,我們只能自己定義文件操作來實現。
4、其他
structdentry *debugfs_rename(structdentry *old_dir,structdentry *old_dentry,structdentry *new_dir,constchar*new_name);structdentry *debugfs_create_symlink(constchar*name,structdentry *parent,constchar*target);
以上部分轉自:http://www.cnblogs.com/wwang/archive/2011/01/17/1937609.html
三、實例
這個實例雖然簡單,但是融合了如何在debugfs目錄下創建文件,并給出了文件的操作方法;
也說明了如何創建變量文件,并且用戶空間讀寫這個變量文件相當于是在讀寫內核空間的這個文件對應的變量
[cpp]?view plaincopy
dbgfs_demon/
|--data
|--tracing_on
函數的操作邏輯是,如果tracing_on的值為Y,那么可以從文件data中讀出有用的調試信息,
如果為N,那么讀data操作將不會返回任何數據。
另外還有一個網上找到的debugfs的小例子:http://download.csdn.net/detail/luckywang1103/9369310
總結
以上是生活随笔為你收集整理的linux内核 DebugFS的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: Android recovery支持ad
- 下一篇: linux和android调试概要