嵌入式linux之/proc文件系统(介绍加实例验证)

2019-07-13 02:27发布

文章目录

/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) 参数
  1. file:该proc文件对应的file结构,一般忽略
  2. buffer:待写的数据所在位置
  3. count:待写数据的大小
  4. data:一般不使用

实现流程

实现一个proc文件的流程:
  1. 调用create_proc_entry创建一个struct proc_dir_entry。
  2. 对创建的struct proc_dir_entry进行赋值:read_proc,mode,owner,size,write_proc等。

mini6410下的实例代码

(1)proc.c #include #include #include #include #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 "); 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 ",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 ",procfs_name); return 0; } void proc_exit() { remove_proc_entry(procfs_name,NULL); printk(KERN_INFO "/proc/%s removed ",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 #include #include #include 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] = '