procfs是比较老的一种用户态与内核态的数据交换方式,内核的很多数据都是通过这种方式出口给用户的,内核的很多参数也是通过这种方式来让用户方便设置的。
struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode, struct proc_dir_entry *parent)
该函数用于创建一个正常的proc条目,参数name给出要建立的proc条目的名称,参数mode给出了建立的该proc条目的访问权限,参数parent指定建立的proc条目所在的目录。如果要在/proc下建立proc条目,parent应当为NULL。
/* * Remove a /proc entry and free it if it's not currently in use. */ void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
该函数用于删除上面函数创建的proc条目,参数name给出要删除的proc条目的名称,参数parent指定建立的proc条目所在的目录。
struct proc_dir_entry { …… read_proc_t *read_proc; /* 读接口 */ write_proc_t *write_proc; /* 写接口 */…… };
procfs读写信息实例:
/********************************************** * Author: [email protected] * File name: proc_sample.c * Description: create a file "proc_example" in the /proc, * which allows both input and output. * Date: 2011-12-12 *********************************************/ #include <linux/kernel.h> /* We're doing kernel work */ #include <linux/module.h> /* Specifically, a module */ #include <linux/proc_fs.h> /* Necessary because we use proc fs */ #include <asm/uaccess.h> /* for get_user and put_user */ #define MSG_LEN 10 #define PROC_NAME "sample" char chflag[MSG_LEN] = "sample"; static struct proc_dir_entry *sample; /** * proc_read_data() * @page - buffer to write the data in * @start - where the actual data has been written in page * @offset - same meaning as the read system call * @count - same meaning as the read system call * @eof - set if no more data needs to be returned * @data - pointer to our soft state */ static int proc_read_rwdata(char *page, char **stat, off_t off, int count, int *eof, void *data) { int len; len = sprintf(page,"%s\n", chflag); return len; } static int proc_write_rwdata(struct file *file, const char __user *buf, unsigned long count, void *data) { if (count > MSG_LEN) count = MSG_LEN; if (copy_from_user(&chflag, buf, count)) return -EFAULT; return count; } /* * 模块初始化 */ static int __init sample_init(void) { int ret = 0; /* * create_proc_entry(name, mode,parent) * 在parent对应的目录下创建name文件 * 返回目录对应的proc_dir_dentry */ sample = create_proc_entry(PROC_NAME, 0644, NULL); if (NULL == sample) { ret = -ENOMEM; goto sample_err; } sample->read_proc = &proc_read_rwdata, sample->write_proc = &proc_write_rwdata, printk(KERN_INFO "Create sample\n"); return ret; sample_err: return ret; } /* * 模块清理 */ static void __exit sample_exit(void) { remove_proc_entry(PROC_NAME, NULL); printk(KERN_INFO "Remove /proc/proc_sample\n"); } module_init(sample_init); module_exit(sample_exit); MODULE_LICENSE("GPL"); MODULE_AUTHOR("lewiyon <[email protected]>");