Chinaunix首页 | 论坛 | 博客
  • 博客访问: 723812
  • 博文数量: 251
  • 博客积分: 10367
  • 博客等级: 上将
  • 技术积分: 2750
  • 用 户 组: 普通用户
  • 注册时间: 2007-05-10 14:43
文章分类

全部博文(251)

文章存档

2009年(2)

2008年(86)

2007年(163)

分类: LINUX

2007-08-23 23:41:03


本篇主要实现了在scull模块中加入了在/proc 文件夹下创建scull_seq,并补充相应函数。


关于/proc 文件系统

/proc文件系统是一个特殊的软件创建的文件系统, 内核用来输出消息到外界. /proc 下的每个文件都绑到一个内核函数上, 当文件被读的时候即时产生文件内容. 我们已经见到一些这样的文件起作用; 例如, /proc/modules, 常常返回当前已加载的模块列表.

/proc 在 Linux 系统中非常多地应用. 很多现代 Linux 发布中的工具, 例如 ps, top, 以及 uptime, 从 /proc 中获取它们的信息. 一些设备驱动也通过 /proc 输出信息, 你的也可以这样做. /proc 文件系统是动态的, 因此你的模块可以在任何时候添加或去除条目.

完全特性的 /proc 条目可能是复杂的野兽; 另外, 它们可写也可读, 但是, 大部分时间, /proc 条目是只读的文件. 本节只涉及简单的只读情况. 那些感兴趣于实现更复杂的东西的人可以从这里获取基本知识; 接下来可参考内核源码来获知完整的信息.

在/proc文件夹下有许多以数字命名的文件夹,是系统中执行的程序的ID,也叫进程ID。/proc   目录是虚拟的,可以通过它了解当前系统运行的情况。

在我们继续之前, 我们应当提及在 /proc 下添加文件是不鼓励的. /proc 文件系统在内核开发者看作是有点无法控制的混乱, 它已经远离它的本来目的了(是提供关于系统中运行的进程的信息). 建议新代码中使信息可获取的方法是利用 sysfs. 如同建议的, 使用 sysfs 需要对 Linux 设备模型的理解, 然而, 我们直到 14 章才接触它. 同时, /proc 下的文件稍稍容易创建, 并且它们完全适合调试目的, 所以我们在这里包含它们.

具休添加代码如下:
在scull.h中

int scull_read_procem(char *buf,char **start,off_t offset,                                   int count,int *eof,void *data);
static void *scull_seq_start(struct seq_file *s,loff_t *pos);
static void *scull_seq_next(struct seq_file *s,void *v,loff_t *pos);
static void *scull_seq_stop(struct seq_file *sfile,void *v);
static int scull_seq_show(struct seq_file *s,void *v);
static int scull_proc_open(struct inode *inode,struct file *file);


在scull.c中

     #include<linux/proc_fs.h>
     #include<linux/seq_file.h>
     static struct seq_operations scull_seq_ops ={
     48 .start = scull_seq_start,
     49 .next = scull_seq_next,
     50 .stop = scull_seq_stop, /*It's NULL. */
     51 .show = scull_seq_show
     52 };
     53
     54 static struct file_operations scull_proc_ops = {
     55 .owner = THIS_MODULE,
     56 .open = scull_proc_open,
     57 .read = seq_read,
     58 .llseek = seq_lseek,
     59 .release = seq_release
     60 };
     struct proc_dir_entry *entry;
   在static int scull_init_module(void)函数中加入:
    107entry = create_proc_entry("scullseq",0,NULL);
    108 if(entry)
    109    entry->proc_fops = &scull_proc_ops;
    110 else
    111    printk(KERN_ALERT "Can'
t creat a proc entry\n");

   当然在void scull_cleanup_module(void)中要加入

    133if(entry)
    134   remove_proc_entry("scullseq", NULL);

  int scull_read_procem(char *buf,char **start,off_t offset,                                int count,int *eof,void *data)
    318 {
    319 int i,j,len = 0;
    320 int limit = count - 80;/*Don't print more than this */
    321
    322 for(i = 0; i < scull_nr_devs && len <= limit ;i ++){
    323 struct scull_dev *d = &scull_devices[i];
    324 struct scull_qset *qs = d->data;
    325 if(down_interruptible(&d->sem))
    326 return -ERESTARTSYS;
    327 len += sprintf(buf+len,"
\nDevice %i:qset %i , q %i,sz %li\n",i,d->qset,d->quantum,d->size);
    328 for(; qs && len <= limit; qs = qs->next){ /*scan the list */
    329 len += sprintf(buf + len,"
item at %p,qset at %p\n",qs,qs->data);
    330 if(qs->data && !qs->next){
    331 for(j = 0; j < d->qset ; j ++){
    332 if(qs->data[j])
    333 len += sprintf(buf +len ,"
%4i:%ip\n",j,qs->data[j]);
    334 }
    335 }
    336 }
    337 up(&scull_devices[i].sem);
    338 }
    339 *eof = 1;
    340 return len;
    341 }
    342
    343 static void *scull_seq_start(struct seq_file *s,loff_t *pos)
    344 {
    345 if(*pos >= scull_nr_devs)
    346 return NULL; /*No moer to read */
    347 return scull_devices + *pos;
    348 }
 static void *scull_seq_next(struct seq_file *s,void *v,loff_t *pos)
    351 {
    352 (*pos)++;
    353 if(*pos >= scull_nr_devs)
    354 return NULL;
    355
    356 return scull_devices + *pos;
    357 }
    358
    359 static void *scull_seq_stop(struct seq_file *sfile,void *v)
    360 {
    361 return NULL;
    362 }
    363
    364 static int scull_seq_show(struct seq_file *s,void *v)
    365 {
    366 struct scull_dev *dev = (struct scull_dev *)v;
    367 struct scull_qset *d;
    368 int i;
    369
    370 if(down_interruptible(&dev->sem))
    371 return -ERESTARTSYS;
    372 seq_printf(s,"
\nDevice %i:qset %i, q %i ,sz %li\n",(int)(dev - scull_devices),dev->qset,dev->quantum,dev->size);
    373 for(d = dev->data; d; d = d->next){
    374 seq_printf(s,"
item at %p,qset at %p\n",d,d->data);
    375 if(d->data && !d->next)/*dump only the last item */
    376 for(i - 0;i < dev->qset ; i++){
    377 if(d->data[i])
    378     seq_printf(s,"  %4i:%8p\n",i,d->data[i]);

             }
    381   }
    382     up(&dev->sem);
    383
    384     return 0;
    385 }
    386
    387 static int scull_proc_open(struct inode *inode,struct file *file)
    388 {
    389     return  seq_open(file,&scull_seq_ops);
    390 }


其他不变。
阅读(1137) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~