您的位置:首页 > 运维架构 > Linux

Linux嵌入式 -- 内核 - proc文件系统

2013-08-11 17:54 375 查看
1. 什么是proc文件系统?

实例:通过 /proc/meminfo,查询当前内存使用情况。

结论:proc文件系统是一种在用户态检查内核状态的机制。

2.Proc文件分类



特点

每个文件都规定了严格的权限可读?可写?哪个用户可读?哪个用户可写?

可以用文本编辑程序读取(more命令,cat命令,vi程序等等)

不仅可以有文件,还可以有子目录。

可以自己编写内核程序添加一个/proc目录下的文件。

文件的内容都是动态创建的,并不存在于磁盘上,存在内存中。

3. 功能函数

内核描述

struct proc_dir_entry{

{

。。 。。。。。。。。。。。。。。。。。

read_proc_t *read_proc;

write_proc_t *write_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

读操作

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:一般不使用

写操作

int write_func (struct file*file,const char *buffer,unsigned long count,void*data) //提供用户的写操作

参数:

file :该proc文件对应的file结构,一般忽略。

buffer :待写的数据所在的位置

count :待写数据的大小

data :一般不使用

4. 实现流程

实现一个proc文件的流程:

(1)调用create_proc_entry创建一个struct proc_dir_entry。

(2)对创建的struct proc_dir_entry进行赋值:read_proc,mode,owner,size,write_proc 等等。

5.实例一

#include<linux/kernel.h>
#include<linux/init.h>
#include<linux/proc_fs.h>
#define procfs_name "proctest"  // /proc目录下创建的文件名

struct proc_dir_entry *Our_Proc_File;  //结构体,create_proc_entry返回一个指针给他

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: Could not init /proc/%s\n", procfs_name);
return -ENOMEM;
}
Our_Proc_File->read_proc = procfile_read;  //回调函数
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);


5. 实例二 (由1修改为 能够 echo xxx > /proc/proctest)

#include<linux/kernel.h>
#include<linux/init.h>
#include<linux/proc_fs.h>
#include<linux/uaccess.h>
#define procfs_name "proctest"

struct proc_dir_entry *Our_Proc_File;
static char msg[255];  //输入保存数组

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");

int len = strlen(msg);
if(offset >= len)
return 0;
if(buffer_length > len-offset)
buffer_length = len - offset;
memcpy(buffer+offset, msg+offset, buffer_length);
return offset+buffer_length;
}

int procfile_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;
}

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: Could not init /proc/%s\n", procfs_name);
return -ENOMEM;
}
Our_Proc_File->read_proc = procfile_read;
Our_Proc_File->write_proc = procfile_write;
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);


echo xxxx > /proc/proctest

cat /proc/proctest

makefile

ifneq ($(KERNELRELEASE),)

obj-m :=proc.o

else

KDIR := /lib/modules/3.5.0-17-generic/build
all:
make -C $(KDIR) M=$(PWD) modules
clean:
rm -f *.ok *.o *.mod.o *.mod.c *.symvers
endif
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: