新增/proc文件目录
Linux系统上的/proc目录是一种文件系统,即proc文件系统。与其它常见的文件系统不同的是,/proc是一种伪文件系统(也即虚拟文件系统),存储的是当前内核运行状态的一系列特殊文件,用户可以通过这些文件查看有关系统硬件及当前正在运行进程的信息,甚至可以通过更改其中某些文件来改变内核的运行状态。
有时候基于调试方便,可能要新增一个/proc/ 调试接口。这里我随手写一个demo记录下。
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/fs.h>
#include <asm/io.h>
#include <linux/io.h>
#include <linux/uaccess.h>
#include <linux/proc_fs.h>
#include <linux/slab.h>
#include <linux/seq_file.h>
/* 定义一个proc_dir_entry结构体类型变量*/
struct proc_dir_entry *hello_proc = NULL;
struct proc_dir_entry *hello_dir = NULL;
/* 定义一个全局数据,用来保存用户空间返回的数据 */
static char hello_data[20] = {};
static int dbg_proc_show(struct seq_file *m, void *v)
{
seq_printf(m,"hello world!\n");
return 0;
}
static ssize_t hello_proc_open(struct inode *inode, struct file *file)
{
return single_open(file, dbg_proc_show, NULL);
}
/* 如果使用cat节点会调用该函数
*/
static ssize_t hello_proc_read(struct file *fp, char __user *user_buf, size_t count, loff_t *ppos)
{
int ret = 0;
ret = copy_to_user(user_buf,"hello_proc_read",sizeof(hello_proc_read));
if (ret != 0)
{
printk("copy_to_user failed!\r\n");
return -EFAULT;
}
return 0;
}
/*
用户空间使用echo往此节点写入数据
*/
static ssize_t hello_proc_write(struct file *fp, const char __user *user_buf, size_t count, loff_t *ppos)
{
int ret;
ret = copy_from_user(hello_data,user_buf,sizeof(user_buf));
if (ret != 0)
{
printk("copy_from_user failed!\r\n");
return -EFAULT;
}
printk("hello_proc_write:hello_data is %s",hello_data);
return 0;
}
/* 定义一个file_operations结构体变量 */
static const struct file_operations hello_proc_fops = {
.owner = THIS_MODULE,
.open = hello_proc_open, //用户态调用open函数时的回调函数
.read = hello_proc_read, //使用cat时的回调函数
.write = hello_proc_write, //使用echo时的回调函数
};
/* 驱动入口函数 */
static int __init proc_test_init(void)
{
hello_dir = proc_mkdir("hello_dir",NULL);
hello_proc = proc_create("hello_proc", S_IRUGO | S_IWUGO,NULL,&hello_proc_fops);
return 0;
}
/* 驱动出口函数 */
static void __exit proc_test_exit(void)
{
/* 删除此文件 */
if(hello_proc)
remove_proc_entry("hello_proc", NULL);
}
module_init(proc_test_init);
module_exit(proc_test_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("proc filesystem test");
proc_test_init
中我们使用proc_mkdir
和proc_create
创建了/proc/hello_dir/hello_proc
调试文件。然后调用定义了hello_proc_fops
结构体,填充了open,read,write的回调函数。用户空间使用echo命令时会调用到hello_proc_write
。如果使用cat节点会调用hello_proc_read
。如果去读/proc/hello_dir/hello_proc
节点,会读到hello world
。