天天看點

嵌入式linux之/proc檔案系統(介紹加執行個體驗證)

文章目錄

    • /proc檔案系統介紹
    • /proc檔案系統特點
    • 核心描述
      • 建立proc檔案
      • 建立目錄
      • 删除目錄/檔案
      • 讀寫
      • 實作流程
    • mini6410下的執行個體代碼
      • 在/proc下先建立目錄後建立檔案

/proc檔案系統介紹

/proc檔案系統是一種特殊的、由軟體建立的檔案系統,核心使用它向外界導出資訊。/proc下面的每一個檔案都綁定于一個核心函數,使用者讀取其中的檔案時,該函數動态地生成檔案的“”内容“”

比如:通過/proc/meminfo,查詢目前記憶體的使用情況。

嵌入式linux之/proc檔案系統(介紹加執行個體驗證)

簡言之: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 <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闆子上的運作效果

嵌入式linux之/proc檔案系統(介紹加執行個體驗證)

在/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開發闆上驗證如下:

嵌入式linux之/proc檔案系統(介紹加執行個體驗證)