Linux驱动开发笔记8 proc文件操作
一、proc文件系统简介
linux系统对/proc的使用很频繁,现代Linux发行版中的很多工具都是通过/proc来获取它们所需要的信息,例如:ps、top等,有些设备驱动程序也通过/proc导出信息。我们自己的驱动程序当然也可以这么做。因为/proc文件系统是动态的,所以驱动程序模块可以在任何时候添加或删除其中的入口项。这些/proc文件不仅可以用于读出数据,也可以用于写入数据。不过,大多数时候,/proc入口项是只读文件信欣 。proc符号主义文件系统是一个虚拟的文件系统,内核使用它来输出一些信息,每一个在/proc下的文件都绑定一个内核函数,操作这个文件就是在调用这个函数,该文件系统下的文件是动态生成的,当某个进程读取proc文件时,内核会分配一个页大小的内存,驱动程序可以向这个内存中写入要返回用户态的数据。
一、proc文件系统操作
1.读取只读文件接口
当读取proc文件时会调用这个函数
int(*read_proc)(char *page, char **start, off_t off, int count, int*eof, void *data);
page内核分配的那段内存空间的指针
start用来记录要返回用户态的数据写到了内存页的哪个位置,比如第一次读了五个,就可以把*start设置为5,下次读得时候就从5这个偏移量开始读
off start==NULL的时候这个值就无效了
count用户态要读取的字节数
eof当内核态没有要返回用户态的数据时要设置这个值
复调
data内核态在创建proc文件时保存的一个数据,在调用读取函数时传到这里这个函数必须返回放到缓存当中的字节数
2.创建只读proc文件接口
staticinline struct proc_dir_entry *create_proc_read_entry(constchar *name, mode_t mode, struct proc_dir_entry *ba, read_proc_t*read_proc, void * data)
name要创建的proc文件的名字
mode文件的权限
易企秀怎么制作ba该文件的父目录,如果为NULL则默认创建到/proc下
read_proc这个是传入实现读取这个文件的函数
data这个data的值就是当调用读取函数时候传入读取函数的data的值这个函数如果返回NULL代表创建失败
3.删除proc文件接口
void remove_proc_entry(const char *name, struct proc_dir_entry *parent)
name要删除的文件的名字
parent该文件所在的父目录
4.创建读写proc文件接口
staticinline struct proc_dir_entry *create_proc_entry(constchar *name, mode_t mode, struct proc_dir_entry *parent)
name要创建的文件的名字
mode文件的权限
parent要创建的文件的父目录,如果为NULL则代表在/proc下创建
在该函数的返回值中初始化这个文件的读和写函数
例如:file->read_proc= my_read
file->write_proc= my_write
5.读取proc文件接口
当读取proc文件时会调用这个函数
int(*read_proc)(char *page, char **start, off_t off, int count, int*eof, void *data);
page内核分配的那个内存空间的指针
start用来记录要返回用户态的数据写到了内存页的哪个位置比如第一次读了五个,就可以把*start设置为5,下次读得时候就从5这个偏移量开始读
offstart==NULL的时候这个值就无效了
count用户态要读取的字节数
eof当内核态没有要返回用户态的数据时要设置这个值
data内核态在创建proc文件时保存的一个数据,在调用读取函数是传到这里这个函数必须返回放到缓存当中的字节数
6.写proc肿组词语文件接口
int(*write_proc)(struct file *file, const char __ur *buffer, unsignedlong count, void *data);
7.创建proc目录
struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry*parent)
name目录的名字
parent父目录,如果为NULL则在/proc目录下创建
巍然不动8.删除proc目录
同3
近写程序需要内核得到用户态的参数,比较幸福的是虽然ioctrl 生活小常识用不了,可以用proc实现,proc文件系统提供了一种内核和用户态交互的方法。
proc文件系统的详细接口看<linux/proc_fs.h>
主要需要关注的是这几个函数:
struct proc_dir_entry *proc_mkdir(const char *name, struct proc_dir_entry *parent)
struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode, struct proc_dir
_entry *parent);
void remove_proc_entry(const char *name, struct proc_dir_entry *parent);
函数 proc_mkdir用于在proc文件系统下创建文件夹, proc_mkdir的第一个参数是要创建的目录的名字,第二个参数是指向父目录结构的指针。需要注意一下几点:
1. 创建过程没有对于名字的检查,完全可以调用proc_mkdir 创建出一堆同样名字的文件(检查一下会死啊!)
2. 其实名字可以包含路径,例如“乙脑传播途径dev/new_proc”, 如果存在dev目录,函数会在dev目录下创建new_proc目录。
3. 如果第二个参数是NULL,会在根目录也就是/proc/目录下创建目录
函数的返回值就是 新创建目录对应的proc_dir_entry, 保存这个就可以用来在此目录下创建文件啦,其实,即使不保存,利用上面介绍的第二点性质也可以在目录下创建文件,而
且删除目录只用知道路径就可以了~
函数create_proc_entry用来创建文件,mode 参数如果为NULL的话默认的文件访问权限是 755,其他的参数与proc_mkdir 类似
函数remove_proc_entry用来删除创建的目录或者文件,有意思的是,这个函数只需要知道名字和父目录就可以删除了。
说了这么多,怎么交换数据尼?
需要了解下proc_dir_entry 的结构了
struct proc_dir_entry {
unsigned int low_ino;
unsigned short namelen;
const char *name;
mode_t mode;
nlink_t nlink;
uid_t uid;
gid_t gid;
loff_t size;
struct inode_operations * proc_iops;
const struct file_operations * proc_fops;
get_info_t *get_info;
struct module *owner;
struct proc_dir_entry *next, *parent, *subdir;
void *data;
read_proc_t *read_proc;
write_proc_t *write_proc;
atomic_t count; /* u count */
int deleted; /* delete flag */
void *t;
};
其他的参数可以忽略,这里需要注意的是两个成员变量:
read_proc 和 write_proc