日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > linux >内容正文

linux

Linux内核空间-用户空间通信之debugfs

發布時間:2025/3/17 linux 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 Linux内核空间-用户空间通信之debugfs 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

一、debugfs文件系統簡介

debugfs虛擬文件系統是一種內核空間與用戶空間的接口,基于libfs庫實現,專用于開發人員調試,便于向用戶空間導出內核空間數據(當然,反方向也可以)。debugfs在linux內核版本2.6.10引入,作者是Greg Kroah-Hartman。 與procfs和sysfs不同,前者主要提供進程信息(當然后來又加入設備、內存、網絡等信息,比較雜亂),后者主要提供設備信息,且有一個文件提供一個值的“規則”,是Linux通用設備模型的影射。debugfs沒有類似的限制,開發者可以放入任何信息。

二、debugfs的使用

說明:函數接口請參見:http://docs.huihoo.com/doxygen/linux/kernel/3.7/fs_2debugfs_2file_8c.html#ad5e6fa7f4a3de8d751a7fff4d99e59f3

1. 掛載debugfs文件系統

要使用debugfs,需要在內核編譯配置中配置CONFIG_DEBUG_FS選項,一般的發行版都會默認編譯進了內核,并且將其自動掛載默認的目錄(/sys/kernel/debug),可通過以下命令查看: 也可手動掛載到其它位置: $ mkdir /debugfs $ mount -t debugfs none /debugfs

2. 利用debugfs導出基本數據類型的變量

debugfs可以將內核中基本整數類型的變量導出為單個文件,在用戶空間中可以直接對其讀寫(如使用cat、echo命令),只要權限允許即可。支持的類型有:u8, u16, u32, u64, size_t和 bool。其中bool類型在內核中要定義為u32類型,在用戶空間中對應的文件內容則顯示為Y或N。示例代碼如下: static struct dentry *root_d = debugfs_create_dir("exam_debugfs", NULL); //在debugfs根目錄下創建新目錄exam_debugfs,然會新建目錄的目錄項指針 static u8 var8; debugfs_create_u8("var-u8", 0664, root_d, &var8); //在exam_debugfs中創建變量var8對應的文件,名為var-u8,權限為0664 static u32 varbool; debugfs_create_bool("var-bool", 0664, root_d, &varbool); //bool變量

3. 利用debugfs導出數據塊(只讀)

debugfs提供的debugfs_create_blob函數可導出數據塊,示例代碼如下: char buf[] = "Hello debugfs!\n"; b.data = buf; b.size = strlen(buf) + 1; debugfs_create_blob("blob", 0644, root_d, &b); // blob is readonly, even if 0644 沒錯,debugfs提供的debugfs_blob_wrapper結構所導出的數據塊只能讀取,不能修改。

4. 利用debugfs導出u32數組(只讀)

debugfs提供的debugfs_create_u32_array函數可導出內核中u32類型的數組。示例代碼如下: u32 arr[] = {1,2,3,4,5}; debugfs_create_u32_array("array", 0664, root_d, arr, sizeof(arr)/sizeof(u32));

5. 實現可讀寫數據塊的導出

實現并不難,只需實現struct file_operations的open、write、read方法即可。然后調用debugfs提供的debugfs_create_file即可。該方法的原型如下: struct dentry* debugfs_create_file ( const char * name,umode_t mode,struct dentry * parent,void * data, // 傳入的data指針會被賦值給新建文件對應inode的i_private字段const struct file_operations * fops ) 下面,仿照struct?debugfs_blob_wrapper的實現,實現struct my_blob_wrapper和my_blob_wrapper_ops,提供可讀寫的“blob”: /** 自定義可讀寫blob **/ struct my_blob_wrapper{void *data;unsigned long size; // data緩沖區長度 }; static int my_blob_wrapper_open(struct inode *inode, struct file *filp) {filp->private_data = inode->i_private; // inode->i_private被設置為debugfs_create_file傳入的data參數return 0; } static ssize_t my_blob_wrapper_read(struct file *filp, char __user *user_buf, size_t count, loff_t *ppos) {struct my_blob_wrapper *blob = filp->private_data;return simple_read_from_buffer(user_buf, count, ppos,blob->data, blob->size);//此函數有libfs提供,與下面邏輯等價 // if (*ppos >= blob->size) { // return 0; // } // if (*ppos + count > blob->size) { // count = blob->size - *ppos; // } // if (copy_to_user(user_buf, blob->data + *ppos, count) != 0) { // return -EFAULT; // } // *ppos += count; // return count; } static ssize_t my_blob_wrapper_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *ppos) {struct my_blob_wrapper *blob = filp->private_data;return simple_write_to_buffer(blob->data, blob->size, ppos,user_buf, count);//此函數由libfs提供,與下面邏輯等價 // if (*ppos >= blob->size) { // return 0; // } // if (*ppos + count > blob->size) { // count = blob->size - *ppos; // } // if (copy_from_user(blob->data + *ppos, user_buf, count) != 0) { // return -EFAULT; // } // *ppos += count; // return count; } static struct file_operations my_blob_wrapper_ops = {.owner = THIS_MODULE,.open = my_blob_wrapper_open,.read = my_blob_wrapper_read,.write = my_blob_wrapper_write,.llseek = default_llseek,//VFS提供 }; struct dentry *my_create_blob(const char *name, umode_t mode,struct dentry *parent,struct my_blob_wrapper *blob) {return debugfs_create_file(name, mode, parent, blob, &my_blob_wrapper_ops); } /* done */

6. 注意:

① 在debugfs中創建的文件和目錄在模塊退出時,并不會自動刪除,可調用debugfs_remove_recursive刪除整個目錄,或調用debugfs_remove刪除單個文件。 ② u32_array在用戶空間文件中顯示為空格隔開的元素 ③?debugfs_create_x{8,16,32,64}與debugfs_create_u{8,16,32,64}的不同在于前者顯示為16進制,后者顯示為10進制

三、debugfs示例完整代碼

#include <linux/module.h> #include <linux/debugfs.h> #include <linux/fs.h> // for libfs #include <asm-generic/uaccess.h>/** 自定義可讀寫blob **/ struct my_blob_wrapper{void *data;unsigned long size; }; static int my_blob_wrapper_open(struct inode *inode, struct file *filp) {filp->private_data = inode->i_private;return 0; } static ssize_t my_blob_wrapper_read(struct file *filp, char __user *user_buf, size_t count, loff_t *ppos) {struct my_blob_wrapper *blob = filp->private_data;return simple_read_from_buffer(user_buf, count, ppos, blob->data, blob->size); // from libfs } static ssize_t my_blob_wrapper_write(struct file *filp, const char __user *user_buf, size_t count, loff_t *ppos) {struct my_blob_wrapper *blob = filp->private_data;return simple_write_to_buffer(blob->data, blob->size, ppos, user_buf, count); } static struct file_operations my_blob_wrapper_ops = {.owner = THIS_MODULE,.open = my_blob_wrapper_open,.read = my_blob_wrapper_read,.write = my_blob_wrapper_write,.llseek = default_llseek, // from vfs }; /* 接口函數 */ struct dentry *my_create_blob(const char *name, umode_t mode,struct dentry *parent,struct my_blob_wrapper *blob) {return debugfs_create_file(name, mode, parent, blob, &my_blob_wrapper_ops); } /** my_clob implementation end **/static struct dentry *root_d; static u8 var8; static u16 var16; static u32 var32; static u32 varbool; static char buf[] = "Hello debugfs!\n"; static struct debugfs_blob_wrapper b; static struct my_blob_wrapper b2; static u32 arr[] = {1,2,3,4,5};int __init mod_init(void) {printk(KERN_INFO "exam_debugfs: initialing...\n");root_d = debugfs_create_dir("exam_debugfs", NULL);if (!root_d) {printk(KERN_INFO "exam_debugfs: error create root dir\n");return 1;}/* u{8,16,32}, bool */debugfs_create_u8("var-u8", 0664, root_d, &var8);debugfs_create_u16("var-u16", 0664, root_d, &var16);debugfs_create_u32("var-u32", 0664, root_d, &var32);debugfs_create_bool("var-bool", 0664, root_d, &varbool);/* u32_array */debugfs_create_u32_array("array", 0664, root_d, arr, sizeof(arr)/sizeof(u32));/* blob_wrapper */b.data = buf;b.size = strlen(buf) + 1;debugfs_create_blob("blob", 0644, root_d, &b); // blob is readonly, even if 0644/* my_blob_wrapper */b2.data = buf;b2.size = strlen(buf) + 1;my_create_blob("myblob", 0644, root_d, &b2);return 0; } void __exit mod_exit(void) {debugfs_remove_recursive(root_d);printk(KERN_INFO "exam_debugfs: exiting...\n"); }module_init(mod_init); module_exit(mod_exit);MODULE_LICENSE("GPL"); MODULE_DESCRIPTION("a demo for debugfs"); MODULE_AUTHOR("rsljdkt");

四、補充:debugfs bool的實現

static ssize_t read_file_bool(struct file *file, char __user *user_buf,size_t count, loff_t *ppos) {char buf[3];u32 *val = file->private_data;if (*val)buf[0] = 'Y';elsebuf[0] = 'N';buf[1] = '\n';buf[2] = 0x00;return simple_read_from_buffer(user_buf, count, ppos, buf, 2); }static ssize_t write_file_bool(struct file *file, const char __user *user_buf,size_t count, loff_t *ppos) {char buf[32];size_t buf_size;bool bv;u32 *val = file->private_data;buf_size = min(count, (sizeof(buf)-1));if (copy_from_user(buf, user_buf, buf_size))return -EFAULT;if (strtobool(buf, &bv) == 0)*val = bv;return count; }

參考: Debugfs? http://en.wikipedia.org/wiki/Debugfs
Function Documentation? http://docs.huihoo.com/doxygen/linux/kernel/3.7/fs_2debugfs_2file_8c.html#ad5e6fa7f4a3de8d751a7fff4d99e59f3
Linux內核里的DebugFS? http://www.cnblogs.com/wwang/archive/2011/01/17/1937609.html
header file:? http://lxr.free-electrons.com/source/include/linux/debugfs.h

?

新人創作打卡挑戰賽發博客就能抽獎!定制產品紅包拿不停!

總結

以上是生活随笔為你收集整理的Linux内核空间-用户空间通信之debugfs的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。