文章目录
-
- /proc文件系统介绍
- /proc文件系统特点
- 内核描述
-
- 创建proc文件
- 创建目录
- 删除目录/文件
- 读写
- 实现流程
- mini6410下的实例代码
-
- 在/proc下先创建目录后创建文件
/proc文件系统介绍
/proc文件系统是一种特殊的、由软件创建的文件系统,内核使用它向外界导出信息。/proc下面的每一个文件都绑定于一个内核函数,用户读取其中的文件时,该函数动态地生成文件的“”内容“”
比如:通过/proc/meminfo,查询当前内存的使用情况。
简言之:proc文件系统时一种在用户态检查内核状态的机制。
/proc文件下的常见子目录
子目录/文件名 | 内容描述 |
---|---|
apm | 高级电源管理信息 |
bus | 总线以及总线上的设备 |
devices | 可用的设备信息 |
driver | 已经启用的驱动程序 |
interrupts | 中断信息 |
ioports | 端口使用信息 |
version | 内核版本 |
/proc文件系统特点
-
每个文件都规定了严格的权限
(可读?可写?哪个用户可读?哪个用户可写?)
- 可以用文本编辑程序读取(more命令,cat命令,vi程序等)
- 不仅可以有文件,还可以有子目录
- 可以自己编写程序添加一个/proc目录下的问价
- 文件的内容都是动态创建的,并不存在与磁盘上。
内核描述
proc内核描述:
struct proc_dir_entry
{
.......
read_proc_t *read_proc;
write_proc_t *write_proc;
.......
}
创建proc文件
struct proc_dir_entry create_proc_entry(const char *name,mode_t mode,struct proc_dir_entry parent)
**功能:**创建proc文件
参数:
- name:要创建的文件名
- mode:要创建的文件的属性 默认0755
- parent:这个文件的父目录
创建目录
*struct proc_dir_entry * proc_mkdir(const char *name,struct proc_dir_entry parent)
功能:创建proc目录
参数:
- name:要创建的目录名
- parent:这个目录的父目录
删除目录/文件
void remove_proc_entry(const char *name,struct proc_dir_entry *parent)
功能:删除proc目录或文件
参数:
- name:要删除的文件或目录名
- parent:所在的父目录
读写
为了能让用户读写添加的proc问价,需要挂接上读写回调函数:
read_proc
write_proc
(1)读操作
*int read_func(char *buffer,char **stat,off_t off,int count,int *peof,void data)
参数:
- buffer:把要返回给用户的信息写在buffer里,最大不超过PAGE_SIZE
- stat:一般不使用
- off:偏移量
- count:用户要读取的字节数
- peof:读到文件尾时,需要把*peof置1
- data:一般不使用
(2)写操作
*int write_func(struct file *file,const char *buffer,unsigned long count,void data)
参数:
- file:该proc文件对应的file结构,一般忽略
- buffer:待写的数据所在位置
- count:待写数据的大小
- data:一般不使用
实现流程
实现一个proc文件的流程:
- 调用create_proc_entry创建一个struct proc_dir_entry。
- 对创建的struct proc_dir_entry进行赋值:read_proc,mode,owner,size,write_proc等。
mini6410下的实例代码
(1)proc.c
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#define procfs_name "proctest"
struct proc_dir_entry *Our_Proc_File;
int procfile_read(char *buffer,
char **buffer_location,
off_t offset,int buffer_length,int *eof,void *data)
{
int ret;
ret = sprintf(buffer,"HelloWorld\n");
return ret;
}
int proc_init()
{
Our_Proc_File = create_proc_entry(procfs_name,0644,NULL);
if(Our_Proc_File == NULL)
{
remove_proc_entry(procfs_name,NULL);
printk(KERN_ALERT "Error:Counld not initialize /proc/%s\n",procfs_name);
return -ENOMEM;
}
Our_Proc_File->read_proc = procfile_read;
Our_Proc_File->owner = THIS_MODULE;
Our_Proc_File->mode = S_IFREG | S_IRUGO;
Our_Proc_File->uid = 0;
Our_Proc_File->gid = 0;
Our_Proc_File->size = 37;
printk("/proc/%s created\n",procfs_name);
return 0;
}
void proc_exit()
{
remove_proc_entry(procfs_name,NULL);
printk(KERN_INFO "/proc/%s removed\n",procfs_name);
}
module_init(proc_init);
module_exit(proc_exit);
(2) Makefile
ifneq ($(KERNELRELEASE),)
obj-m := proc.o
else
KDIR := /home/zhangbin/mini6410/linux-2.6.38
all:
make -C $(KDIR) M=$(PWD) ARCH=arm CROSS_COMPILE=arm-linux-
clean:
rm -f *.ko *.o *.mod.c *.symvers
endif
(3)在mini6410板子上的运行效果
在/proc下先创建目录后创建文件
(1)proc1.c
#include <linux/module.h>
#include <linux/init.h>
#include <linux/proc_fs.h>
#include <asm/uaccess.h>
static char msg[255];
struct proc_dir_entry *pfile;
static char *mydir;
static int myproc_read(char *page,char **start,off_t off,int count,int *eof,void *data){
int len = strlen(msg);
if(off >= len)
return 0;
if(count > len - off)
count = len - off;
memcpy(page+off,msg+off,count);
return off + count;
}
static int myproc_write(struct file *file,const char __user *buffer,unsigned long count,void *data)
{
unsigned long count2 = count;
if(count2 >= sizeof(msg))
count2 = sizeof(msg) - 1;
if(copy_from_user(msg,buffer,count2))
return -EFAULT;
msg[count2] = '\0';
return count;
}
static int __init myproc_init(void)
{
mydir = proc_mkdir("mydir",NULL);
if(!mydir)
{
printk(KERN_ERR "can't create /proc/mydir\n");
return -1;
}
pfile = create_proc_entry("pool",0666,mydir);
if(!pfile)
{
printk(KERN_ERR "can't create /proc/mydir/pool\n");
remove_proc_entry("mydir",NULL);
return -1;
}
pfile->read_proc = myproc_read;
pfile->write_proc = myproc_write;
return 0;
}
static void __exit myproc_exit()
{
remove_proc_entry("pool",mydir);
remove_proc_entry("mydir",NULL);
}
module_init(myproc_init);
module_exit(myproc_exit);
(2)Makefile
ifneq ($(KERNELRELEASE),)
obj-m := proc1.o
else
KDIR := /home/zhangbin/mini6410/linux-2.6.38
all:
make -C $(KDIR) M=$(PWD) ARCH=arm CROSS_COMPILE=arm-linux-
clean:
rm -f *.ko *.o *.mod.c *.symvers
endif
(3)在mini6410开发板上验证如下: