Linux之debugfs介紹

Linuxdebugfs介紹

Debugfs是一種用於內核調試的虛擬文件系統,在內核源碼中經常可以看到它的使用,今天我來大概介紹一下它的使用。

如果你對debugfs不熟悉,那麼也許你會對sysfs比較熟悉,對於調試方面,其實兩個文件系統還是挺類似的,但是sysfs的引入內核主要是用於驅動模型的。所以我們在平時調試的時候應該儘量避免使用sysfs,而使用debugfs

好了,下面我們來介紹一些debugfs的使用,要使用debugfs首先我們要設置一下配置選項CONFIG_DEBUG_FS,可以在config文件中設置CONFIG_DEBUG_FS=y,也可以通過menuconfig來設置,如圖:

  1. Kernelhacking --->  
  2.   
  3.             [*]Debug Filesystem  

驅動中使用debugfs需要包含頭文件<linux/debugfs.h>,爲了在用戶態下使用debugfs,必須把它mount到一個目錄下,我們可以把它放在mnt目錄下。

使用如下命令:

  1. <span xmlns="http://www.w3.org/1999/xhtml" style="">mount-t debugfs none /mnt</span>  

然後進入/mnt後就可以看到我們在系統中創建的這些文件。

下面我們開始說一下如何在驅動中使用debugfs.

首先我們需要創建一個自己的目錄,利用如下函數:

  1. <span xmlns="http://www.w3.org/1999/xhtml" style="">struct dentry *debugfs_create_dir(const char *name, struct dentry *parent);</span>  

name就是創建的目錄的名字,parent是該目錄的父目錄,如果是NULL的話,則所創建的目錄就在debugfs的根目錄,具體使用如下:

  1. static struct dentry *binder_debugfs_dir_entry_root;  
  2. binder_debugfs_dir_entry_rootdebugfs_create_dir("binder", NULL);  

這樣就會在debugfs的根目錄下創建一個binder的目錄,有了目錄還需要有可供讀寫的文件吧,下邊就是另一個重要的函數,文件的創建:

  1. struct dentry *debugfs_create_file(const char *name, mode_t mode,  
  2. struct dentry *parent, void *data,  
  3. const struct file_operations *fops)  

如其函數名,這個函數的作用就是在parent這個目錄下創建一個名爲name的文件,mode是這個文件讀寫權限,data是傳入的參數,fops就比較重要了,爲我們的文件提供實際的讀寫操作。

binder驅動中創建瞭如下文件

  1. debugfs_create_file("state",  
  2. S_IRUGO,  
  3. binder_debugfs_dir_entry_root,  
  4. NULL,  
  5. &binder_state_fops);  
  6.   
  7. debugfs_create_file("stats",  
  8. S_IRUGO,  
  9. binder_debugfs_dir_entry_root,  
  10. NULL,  
  11. &binder_stats_fops);  
  12.   
  13. debugfs_create_file("transactions",  
  14. S_IRUGO,  
  15. binder_debugfs_dir_entry_root,  
  16. NULL,  
  17. &binder_transactions_fops);  
  18.   
  19. debugfs_create_file("transaction_log",  
  20. S_IRUGO,  
  21. binder_debugfs_dir_entry_root,  
  22. &binder_transaction_log,  
  23. &binder_transaction_log_fops);  
  24.   
  25. debugfs_create_file("failed_transaction_log",  
  26. S_IRUGO,  
  27. binder_debugfs_dir_entry_root,  
  28. &binder_transaction_log_failed,  
  29. &binder_transaction_log_fops);  

如上圖所示,在binder目錄下創建了proc/state/stats/transactions/transaction_log/failed_transaction_log這些文件。

binder中這些文件的fops全部用一個宏來完成了

  1. #define BINDER_DEBUG_ENTRY(name) \  
  2. static int binder_##name##_open(struct inode *inode, struct file *file) \  
  3. {\  
  4. return single_open(file, binder_##name##_show, inode->i_private); \  
  5. }\  
  6. \  
  7. static const struct file_operations binder_##name##_fops = { \  
  8. .ownerTHIS_MODULE, \  
  9. .openbinder_##name##_open, \  
  10. .readseq_read, \  
  11. .llseekseq_lseek, \  
  12. .releasesingle_release, \  
  13. }  

可以看到binder沒有實現write操作。read則全部使用seq_file的操作,seq_file2.4.15以後版本的內核中出現的新功能,使得內核輸出大文件信息。這邊我們就不去將seq了,我們放在另外的一篇文章裏面去講。

debugfs除了實現這個文件對函數的功能,還提供了一些API用來針對變量的操作:

  1. struct dentry *debugfs_create_u8(const char *name, mode_t mode, struct dentry *parent, u8 *value);  
  2. struct dentry *debugfs_create_u16(const char *name, mode_t mode, structdentry *parent, u16 *value);  
  3. struct dentry *debugfs_create_u32(const char *name, mode_t mode, structdentry *parent, u32 *value);  
  4. struct dentry *debugfs_create_bool(const char *name, mode_t mode, structdentry *parent, u32 *value);  

這樣就可以在用戶態去調試內核變量value了。

當內核卸載時,debugfs並不會自動的去清除我們創建的這些文件,對於創建的每一個文件我們都需要調用如下函數接口去清除:

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章