91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Linux內核里的DebugFS有什么用

發布時間:2021-12-24 14:16:25 來源:億速云 閱讀:200 作者:iii 欄目:系統運維

本篇內容主要講解“Linux內核里的DebugFS有什么用”,感興趣的朋友不妨來看看。本文介紹的方法操作簡單快捷,實用性強。下面就讓小編來帶大家學習“Linux內核里的DebugFS有什么用”吧!

DebugFS,顧名思義,是一種用于內核調試的虛擬文件系統,內核開發者通過debugfs和用戶空間交換數據。類似的虛擬文件系統還有procfs和sysfs等,這幾種虛擬文件系統都并不實際存儲在硬盤上,而是Linux內核運行起來后才建立起來。

通常情況下,最常用的內核調試手段是printk。但printk并不是所有情況都好用,比如打印的數據可能過多,我們真正關心的數據在大量的輸出里不是那么一目了然;或者我們在調試時可能需要修改某些內核變量,這種情況下printk就無能為力,而如果為了修改某個值重新編譯內核或者驅動又過于低效,此時就需要一個臨時的文件系統可以把我們需要關心的數據映射到用戶空間。在過去,procfs可以實現這個目的,到了2.6時代,新引入的sysfs也同樣可以實現,但不論是procfs或是sysfs,用它們來實現某些debug的需求,似乎偏離了它們創建的本意。比如procfs,其目的是反映進程的狀態信息;而sysfs主要用于Linux設備模型。不論是procfs或是sysfs的接口應該保持相對穩定,因為用戶態程序很可能會依賴它們。當然,如果我們只是臨時借用procfs或者sysfs來作debug之用,在代碼發布之前將相關調試代碼刪除也無不可。但如果相關的調試借口要在相當長的一段時間內存在于內核之中,就不太適合放在procfs和sysfs里了。故此,debugfs應運而生。

默認情況下,debugfs會被掛載在目錄/sys/kernel/debug之下,如果您的發行版里沒有自動掛載,可以用如下命令手動完成:

# mount -t debugfs none /your/debugfs/dir

Linux內核為debugfs提供了非常簡潔的API,本文接下來將以一個實作為例來介紹,sample code可以從這里下載。

這個實作會在debugfs中建立如下的目錄結構:

Linux內核里的DebugFS有什么用

其中,a對應模塊中的一個u8類型的變量,b和subdir下面的c都是對應模塊里的一個字符數組,只是它們的實現方式不同。

在module_init里,我們首先要建立根目錄mydebug:

my_debugfs_root = debugfs_create_dir("mydebug", NULL);

***個參數是目錄的名稱,第二個參數用來指定這個目錄的上級目錄,如果是NULL,則表示是放在debugfs的根目錄里。

子目錄也是用debugfs_create_dir來實現:

sub_dir = debugfs_create_dir("subdir", my_debugfs_root);

建立文件a的代碼非常簡單:

debugfs_create_u8("a", 0644, my_debugfs_root, &a);

這表示文件名為“a”,文件屬性是0644,父目錄是上面建立的“mydebug”,對應的變量是模塊中的a。

Linux內核還提供了其他一些創建debugfs文件的API,請參考本文的附錄。

b是一個32-bytes的字符數組,在debugfs里,數組可以用blob wrapper來實現。

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);

這里需要注意的是,blob  wrapper定義的數據只能是只讀的。在本例中,雖然我們把文件b的權限設定為0644,但實際這個文件還是只讀的,如果試圖改寫這個文件,系統將提示出錯。

如果需要對內核數組進行寫的動作,blob  wrapper就無法滿足要求,我們只能通過自己定義文件操作來實現。在這個實作里,可以參考文件c的實現。c和b在模塊里對應著同一塊字符數組,不同的是,b是只讀的,而c通過自定義的文件操作同時實現了讀和寫。

static int c_open(struct inode *inode, struct file *filp) {     filp->private_data = inode->i_private;     return 0; }   static ssize_t c_read(struct file *filp, char __user *buffer,         size_t count, loff_t *ppos) {     if (*ppos >= 32)         return 0;     if (*ppos + count > 32)         count = 32 - *ppos;       if (copy_to_user(buffer, hello + *ppos, count))         return -EFAULT;       *ppos += count;       return count; }   static ssize_t c_write(struct file *filp, const char __user *buffer,         size_t count, loff_t *ppos) {     if (*ppos >= 32)         return 0;     if (*ppos + count > 32)         count = 32 - *ppos;       if (copy_from_user(hello + *ppos, buffer, count))         return -EFAULT;       *ppos += count;       return count; }   struct file_operations c_fops = {     .owner = THIS_MODULE,     .open = c_open,     .read = c_read,     .write = c_write, };     debugfs_create_file("c", 0644, sub_dir, NULL, &c_fops);

注:代碼里,c_open其實并沒有任何用處,因為c_read和c_write直接引用了全局變量hello。這里,我們也可以換一種寫法,在read/write函數里用filp->private_data來引用字符數組hello。

到這里,三個文件和子目錄已經創建完畢。在module_exit中,我們要記得釋放創建的數據。

debugfs_remove_recursive(my_debugfs_root);

debugfs_remove_recursive可以幫我們逐步移除每個分配 

到此,相信大家對“Linux內核里的DebugFS有什么用”有了更深的了解,不妨來實際操作一番吧!這里是億速云網站,更多相關內容可以進入相關頻道進行查詢,關注我們,繼續學習!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

德州市| 新沂市| 邓州市| 晋中市| 饶平县| 丹寨县| 乌兰察布市| 固安县| 伊宁县| 剑川县| 上蔡县| 宣恩县| 饶河县| 班玛县| 瑞金市| 琼中| 和平县| 芮城县| 离岛区| 新野县| 噶尔县| 桐城市| 松潘县| 宁城县| 怀远县| 乡城县| 尼玛县| 玉田县| 巩义市| 汝州市| 东丰县| 克什克腾旗| 中方县| 宁南县| 迁西县| 乌鲁木齐市| 黔东| 会宁县| 香港| 赤水市| 鱼台县|