proc fs是内核和用户侧之间的一种交互方式,比如一些cpu信息,我们可以通过/proc/cpuinfo来查看,flahs分区信息可以通过/proc/partions等等,但是由于proc问及系统缺乏统一的管理,十分凌乱,内核开发者不推荐使用,改用sysfs,替代proc fs。但是proc fs作为驱动开发对用户提供信息还是十分方便的。具体使用见代码。
#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/proc_fs.h>
#include <linux/seq_file.h>
#include <linux/fs.h>
#include <linux/uaccess.h>
#include <linux/kernel.h>
char *name="null";
module_param_named(name, name, charp, S_IRUGO | S_IWUSR);
MODULE_PARM_DESC(name, "name");
int name_show(struct seq_file *seq_filp, void *data)
{
seq_printf(seq_filp, "%s\r\n", name);
return 0;
}
int proc_name_open(struct inode *p_node, struct file *flip)
{
return single_open(flip, name_show, NULL);
}
static struct file_operations proc_name_fops = {
.owner = THIS_MODULE,
.open = proc_name_open,
.release = single_release,
.read = seq_read,
.llseek = seq_lseek,
};
static struct proc_dir_entry *p_dir = NULL;
static struct proc_dir_entry *p_name = NULL;
static __init int my_name_init(void)
{
p_dir = proc_mkdir("family", NULL);
if (p_dir == NULL)
{
printk("my_name_init: creat family dir failed!!!\n");
return -EINVAL;
}
p_name = proc_create("name", S_IRUGO, p_dir, &proc_name_fops);
if (p_name == NULL)
{
printk("my_name_init: creat name node failed!!!\n");
proc_remove(p_dir);
return -EINVAL;
}
printk("Hello %s!!!\n", name);
return 0;
}
static __exit void my_name_exit(void)
{
proc_remove(p_name);
proc_remove(p_dir);
printk("%s ByeBye!!!\n", name);
}
module_init(my_name_init);
module_exit(my_name_exit);
MODULE_VERSION("0.01");
MODULE_AUTHOR("zfj.");
MODULE_DESCRIPTION("my name driver");
MODULE_LICENSE("GPL");
生成/proc/family/name节点
使用seq_read()seq_write()接口,我们只需要提供一个open()函数,然后使用single_open()提供一个show()函数,这成一个固定的模板,有固定的宏可以使用。这样做的好处不用考虑缓冲的操作,缓冲超过一页的情况等等。
文件include/linux/seq_file.h中,有时候我们看到sys文件系统下的节点文件,也是使用相同的方法使用宏构建的,非常方便。
#define DEFINE_SHOW_ATTRIBUTE(__name) \
static int __name ## _open(struct inode *inode, struct file *file) \
{ \
return single_open(file, __name ## _show, inode->i_private); \
} \
\
static const struct file_operations __name ## _fops = { \
.owner = THIS_MODULE, \
.open = __name ## _open, \
.read = seq_read, \
.llseek = seq_lseek, \
.release = single_release, \
}