使用debugfs
在前面,我们学习到了sysctl这一基于sysfs和seq_file这一基于procfs文件系统进行交互数据的方式,其中procfs主要是针对进程属性,而sysfs是针对内核模型的,为了保证其稳健,我们很少拿来作为调试时数据交换使用,显然printk也满足不了,那么debugfs就应运而生了.
一般发行版系统会将debugfs挂载在/sys/kernel/debug这一目录下,在/etc/mtab有相关内容,如果没有,也可手动执行如下命令:
一般发行版系统会将debugfs挂载在/sys/kernel/debug这一目录下,在/etc/mtab有相关内容,如果没有,也可手动执行如下命令:
mount -t debufgs none /the/debugfs/dir
在include/linux/debugfs.h文件里有debugfs用到的如下函数:
static inline struct dentry *debugfs_create_dir(const char *name, struct dentry *parent); static inline struct dentry *debugfs_create_file(const char *name, umode_t mode, struct dentry *parent, void *data, const struct file_operations *fops); static inline void debugfs_remove(struct dentry *dentry) ; static inline void debugfs_remove_recursive(struct dentry *dentry) ;
很像前面procfs时的相关函数吧,这就不作解释了,还会用到如下函数:
static inline struct dentry *debugfs_create_u8(const char *name, umode_t mode, struct dentry *parent, u8 *value) ; static inline struct dentry *debugfs_create_u16(const char *name, umode_t mode, struct dentry *parent, u16 *value); static inline struct dentry *debugfs_create_u32(const char *name, umode_t mode, struct dentry *parent, u32 *value) ; static inline struct dentry *debugfs_create_u64(const char *name, umode_t mode, struct dentry *parent, u64 *value) ;
这些都是单值文件,还有将上面函数名中的u8、u16、u32、u64替换为x8、x16、x32、x64的函数,这些表示后面的value用16进制数表示。还有size_t、atomic_t、bool等类型的函数,以及跟数组相关的BLOB文件:
static inline struct dentry *debugfs_create_blob(const char *name, umode_t mode, struct dentry *parent, struct debugfs_blob_wrapper *blob) ;
还有更多的相关函数请在debugfs.h了解,上面函数中debugfs_blog_wrapper结构体定义如下:
struct debugfs_blob_wrapper { void *data; unsigned long size; };
至此,我们了解了相关函数说明,接下来上实例吧:
/* This module will create debugfs example module, the directory tree will be created,like: /sys/kernel/debug (The debugfs mount node) |_slam_debug | |_slam | |_array |_array |_u8 */ #include <linux/module.h> #include <linux/debugfs.h> #include <asm/uaccess.h> MODULE_LICENSE("GPL"); #define MAX_SLAM_SIZE 32 static struct dentry * slam_debug_dir, * slam_dir; static u8 u8_var; static char array[32] = "Hello xinu!\n"; static struct debugfs_blob_wrapper bw; static int slam_open(struct inode *inode, struct file *filp) { filp->private_data = inode->i_private; return 0; } static ssize_t slam_read(struct file *filp, char __user *buf, size_t count, loff_t *ppos) { if(*ppos >= MAX_SLAM_SIZE) return 0; if(*ppos + count > MAX_SLAM_SIZE) count = MAX_SLAM_SIZE - *ppos; if(copy_to_user(buf, array + *ppos, count)) return -EFAULT; *ppos += count; return count; } static ssize_t slam_write(struct file *filp, const char __user *buf, size_t count, loff_t *ppos) { if(*ppos >= MAX_SLAM_SIZE) return 0; if(*ppos + count > MAX_SLAM_SIZE) count = MAX_SLAM_SIZE - *ppos; if(copy_from_user(array + *ppos, buf, count)) return -EFAULT; *ppos += count; return count; } static struct file_operations slam_array_fops = { .owner = THIS_MODULE, .open = slam_open, .read = slam_read, .write = slam_write, }; static int __init debugfs_example_init(void) { slam_debug_dir = debugfs_create_dir("slam_debug", NULL); bw.data = (void *)array; bw.size = strlen(array) + 1; debugfs_create_blob("array", 0644, slam_debug_dir, &bw); slam_dir = debugfs_create_dir("slam", slam_debug_dir); debugfs_create_u8("u8", 0644, slam_debug_dir, &u8_var); debugfs_create_file("array", 0644, slam_dir, NULL, &slam_array_fops); return 0; } static void __exit debugfs_example_exit(void) { debugfs_remove_recursive(slam_debug_dir); } module_init(debugfs_example_init); module_exit(debugfs_example_exit);
相应的Makefile内容如下:
obj-m += debugfs_example.o CUR_PATH:=$(shell pwd) LINUX_KERNEL_PATH:=/home/xinu/linux-3.13.6 all: make -C $(LINUX_KERNEL_PATH) M=$(CUR_PATH) modules clean: make -C $(LINUX_KERNEL_PATH) M=$(CUR_PATH) clean
相应的源码文件目录树如下:
/home/xinu/xinu/linux_kernel_driver_l1/debugfs_example/
├── debugfs_example.c
└── Makefile
编译加载KO后,在/sys/kernel/debug目录下就会生成相应的目录和文件节点,相关目录树在源码里有说明。至此,我们对Debugfs也进行了了解。
参考网址:
http://www.embeddedlinux.org.cn/html/yingjianqudong/201304/17-2553.html
http://www.cnblogs.com/wwang/archive/2011/01/17/1937609.html
https://www.ibm.com/developerworks/cn/linux/l-kerns-usrs2/
/home/xinu/xinu/linux_kernel_driver_l1/debugfs_example/
├── debugfs_example.c
└── Makefile
编译加载KO后,在/sys/kernel/debug目录下就会生成相应的目录和文件节点,相关目录树在源码里有说明。至此,我们对Debugfs也进行了了解。
参考网址:
http://www.embeddedlinux.org.cn/html/yingjianqudong/201304/17-2553.html
http://www.cnblogs.com/wwang/archive/2011/01/17/1937609.html
https://www.ibm.com/developerworks/cn/linux/l-kerns-usrs2/
评论
发表评论