proc文件系统

晨曦之光 发布于 2012/04/13 11:20
阅读 183
收藏 0

今天是端午节,本来想些点东西,可最近压力太大了,连msn 的blog都没有时间写,学习的时候,可以坐在那里一天不站起来,可以熬几个通宵,可是代码隔上四五天不写,就会颓废掉,再写的话感觉要找上好半天,甚至都不想学,马上要考试了,总共八门,我都没有怎么看~~~

晚上一起出去吃饭,世界杯让瑾璠疯掉了,三句话不离狗字,让老徐NC了,各种的无奈...想想我还是好点的,写点东西吧,这个时候了,凌晨了,最近学到了Linux内核,今天下午刚好看到了proc文件系统,散文写不下去了,就写个程序来纪念下我们的端午节好了!不过,说到这里,不尽又想起了前日的圣战,只能一句话,脑残到处有,中国特别多!   SJ,端午是你们韩国的,孔子是你们韩国的,李白是你们韩国的,东北是你们韩国的,美洲是韩国人首先发现的,你妹的,连自己祖宗都不知道是谁,是不是过几天要说,亚里士多德他祖母是韩国的,希特勒在韩国上的幼儿园,就连奥特曼也是韩国的~~

 

 

proc文件系统,在/prco下有很多文件,proc文件系统是一种在用户态检测内核状态的机制。通过它我们可以看到系统的一些信息,如内存,进程,模块等!我们也可以通过它来配置一下内核,如devices记录一些设备的嬉戏,ioports记录一些系统的端口使用情况,bus记录了总线以及总线上的设备,

特点:
proc文件系统对每一个文件都规定了严格的权限,这些文件的内容是动态创建的,并不存在于磁盘下,例如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目录的话,
函数struct proc_dir_entry *proc_mkdir(const char *name,struct proc_dir_entry *parent)、
name是文件或目录名字,mode是文件属性,默认是755,parent是要创建的文件或者目录的父目录,
如果为空,表示在/proc目录下创建,如果不是空,例如是devices,就是说在/proc/devices下创建文件或目录

如果要删除目录或文件
函数void remove_proc_entry(const char *name,stuct proc_dir_entry *parent)
参数含义同上

当我们的用户去访问/proc下某一个文件时候,该文件所对应的proc_dir_entry里面的read_proc将会被调用
当我们去写文件时候,该文件所对应的proc_dir_entry里面的write_proc将会被调用
我们在创建proc文件后,应该对返回的struct proc_dir_entry里面的read_proc和write_proc文件进行赋值
他们会被赋给一个函数指针,当我们读改文件时候read_proc所指向的函数会被调用,当我们写文件的时候,
write_proc所指向的函数将会被调用,函数功能当然由我们来实现
由此可见,proc文件只有当我们读的时候,他里面才有内容,我们不读的时候,他里面是没有内容的
并且当我们cat file时候,打印的信息是read_proc指向的函数的第一个参数buffer的内容

 

一晚上的心血,支持开源

#include<linux/module.h>
#include<linux/init.h>
#include<linux/kernel.h>
#include<linux/proc_fs.h>
#include<asm/uaccess.h>   /*jiffies定时器*/

MODULE_LICENSE("GPL");
MODULE_AUTHOR("XIE SI YUAN");
MODULE_DESCRIPTION("2010.6.15 proc file system");

char msg[100];   //read  write buffer
struct proc_dir_entry *my_proc_dir;  //proc 路径
struct proc_dir_entry *my_proc_file;   //proc 文件

//buffer是读取的文件保存缓冲区,stat一般不用,off是偏移量,就是从文件的那个位置开始读取的,peof是当文件到达结尾时候置为1,data一般不用
static int read_proc_file(char *buffer,char **stat,off_t off,int count,int *peof,void *data)
{
  int len=strlen(msg);
  if(off>len)  //偏移量大于文件源的大小,读取预溢出
  return -1;
  if(count>len-off)
   count=len-off;  //文件中从off开始的位置到结尾,大小小于count个字节,紧紧读取最后的数据
  //注意:buffer的大小是在cat文件时候系统带有的大小,所以这里不用kmalloc了,刚开始还迷糊了半天
  //memcpy吧msg+off开始的地址,大小为count的内存复制到buffer+off指向的空间
  memcpy(buffer+off,msg+off,count);
 return 0;
}
//写操作对应的函数,file是proc文件对应的结构,一般不用,ch是要写入的数据的buffer,count是要写入的数据的大小,data一般不用
static int write_proc_file(struct file *file, const char __user *buffer, unsigned long count, void *data)
{
 unsigned long count1=count;
  if(count1>strlen(msg))
   count1=strlen(msg)-1;
  //copy_from_user函数的目的是从用户空间拷贝数据到内核空间,失败返回没有被拷贝的字节数,成功返回0.函数原型在[arch/i386/lib/usercopy.c]
 if(!copy_from_user(msg,buffer,count1))
  {
   printk("<0>write failed!/n");
   return -1;
  }
  msg[count1]='/0';
 return 0;
}
static int __init proc_init(void)
{
  my_proc_dir=proc_mkdir("xsy_dir",NULL);  //第二个参数是父目录,NULL表示是/proc  返回值是创建的路径的指针
  if(!my_proc_dir)   //失败返回0
 {
   printk("<0>/proc/xsy_dir make failed!/n");
   return -1;
  }
 my_proc_file=create_proc_entry("xsy_file",0755,my_proc_dir);  //默认是0755  返回的是文件的指针
  if(!my_proc_file)
 {
   printk("<0>/proc/xsy_dir/xsy_file make failed!/n");
   //失败后把先前注册的路径注销
   remove_proc_entry("xsy_dir",NULL);
   return -1;
  }
 //填写创建的proc file的proc_dir_entry,包括usr,size,group and so on ,这里只注册*read_proc和*write_proc,供后面使用
 my_proc_file->read_proc=read_proc_file;
  my_proc_file->write_proc=write_proc_file;
  return 0;
}

static void __exit proc_exit(void)
{
  remove_proc_entry("xsy_file",my_proc_dir);  //先卸载文件
  remove_proc_entry("xsy_dir",NULL);  //后卸载路径
 printk("<0>proc_file removed!/n");
}
module_init(proc_init);   //注册模块  insmod
moudle_exit(proc_exit);  //卸载 rmmod

make文件

加载模块前

加载模块后,多了xsy_dir路径

 


原文链接:http://blog.csdn.net/xie376450483/article/details/5673175
加载中
返回顶部
顶部