Chinaunix首页 | 论坛 | 博客
  • 博客访问: 166006
  • 博文数量: 47
  • 博客积分: 1032
  • 博客等级: 少尉
  • 技术积分: 759
  • 用 户 组: 普通用户
  • 注册时间: 2011-01-19 15:47
文章分类
文章存档

2012年(26)

2011年(21)

分类: LINUX

2012-02-07 17:21:34

linux@linux-desktop:~/wuting/module$ cat procfs_example.c
#include
#include
#include
#include
#include
#include

#define MODULE_VERS "1.0"
#define MODULE_NAME "procfs_example"
#define FOOBAR_LEN    8

struct fb_data_t {
        char name[FOOBAR_LEN + 1];
        char value[FOOBAR_LEN + 1];
};
static struct proc_dir_entry *example_dir,*foo_file,\
                    *bar_file,*jiffies_file,*symlink; 
struct fb_data_t foo_data,bar_data;

//A read callback function for jiffies file
static int proc_read_jiffies(char *page,char **stat,\
            off_t off,int count,int *eof,void *data)
{
    int len;
      
    len = sprintf(page,"jiffies = %ld\n",jiffies); //jiffies is used as 
                            //the time counter of in the  Kernal
    return len;
}
//A read callback  function
static int proc_read_foobar (char *page,char **stat,\
                off_t off,int count,int *eof,void *data)
{
    int len;
    struct fb_data_t *fb_data = (struct fb_data_t *) data;
    len = sprintf(page,"%s = '%s'\n",fb_data->name,fb_data->value);
    return len;
}

//A write callback function for foobar_file
 static int proc_write_foobar (struct file *file,const char *buffer,\
             unsigned long count,void *data)
{
    int len;
    struct fb_data_t *fb_data = (struct fb_data_t *)data;
    if(count > FOOBAR_LEN)
      len = FOOBAR_LEN;
    else
      len = count;
    /*For buffer not exist in memory,so must copy it into Kernal first*/
    if(copy_from_user(fb_data->value,buffer,len))
      return -EFAULT;
    fb_data->value[len] = '\0';
    return len;
}

//init the MODULE
 static int __init init_procfs_example(void)
{
    int rv = 0;
    /*create directory*/
    example_dir = proc_mkdir(MODULE_NAME,NULL);
    /*handle the error*/
    if(example_dir == NULL){
        rv = -ENOMEM;
        goto out;
    }
    example_dir->owner = THIS_MODULE;
    /*create jiffies using convenience function*/
    jiffies_file = create_proc_read_entry("jiffies",0444,example_dir,\
                proc_read_jiffies,NULL);
    if(jiffies_file == NULL){
        rv = -ENOMEM;
        goto no_jiffies;
    }
    jiffies_file->owner = THIS_MODULE;
    /*creat foo and bar files using same callback functions*/
    foo_file = create_proc_entry("foo",0644,example_dir);
    if(foo_file == NULL){
        rv = -ENOMEM;
        goto no_foo;
    }
    strcpy(foo_data.name,"foo");
    strcpy(foo_data.value,"foo");
    foo_file->data = &foo_data;
    foo_file->read_proc = proc_read_foobar;
    foo_file->write_proc = proc_write_foobar;
    foo_file->owner = THIS_MODULE;

    bar_file = create_proc_entry("bar",0644,example_dir);
     if(bar_file == NULL){
          rv = -ENOMEM;
          goto no_bar;
    }
     strcpy(bar_data.name,"bar");
     strcpy(bar_data.value,"bar");
     bar_file->data = &bar_data;
     bar_file->read_proc = proc_read_foobar;
     bar_file->write_proc= proc_write_foobar;
     bar_file->owner = THIS_MODULE;

     /*create symlink*/
     symlink = proc_symlink("jiffies_too",example_dir,"jiffies");
     if(symlink == NULL){
         rv = -ENOMEM;
        goto no_symlink;
     }

     symlink->owner = THIS_MODULE;

     printk(KERN_INFO "%s %s initialised\n",MODULE_NAME,MODULE_VERS);
     return 0;


no_symlink:
     remove_proc_entry("symlink",example_dir);
no_bar:
     remove_proc_entry("bar",example_dir);
no_foo:
     remove_proc_entry("foo",example_dir);
no_jiffies:
     remove_proc_entry(MODULE_NAME,NULL);
out:
     return rv;
}

    static void __exit cleanup_procfs_example(void)
{
    remove_proc_entry("jiffies_too",example_dir);
    remove_proc_entry("bar",example_dir);
    remove_proc_entry("foo",example_dir);
    remove_proc_entry("jiffies",example_dir);
    remove_proc_entry(MODULE_NAME,NULL);

    printk(KERN_INFO "%s %s removed\n",MODULE_NAME,MODULE_VERS);

}

module_init(init_procfs_example);
module_exit(cleanup_procfs_example);

Makefile 文件:

linux@linux-desktop:~/wuting/module$ cat Makefile 
TARGET = procfs_example
KERNEL=`uname -r`
KDIR = /usr/src/linux-headers-$(KERNEL)
PWD = `pwd`
obj-m :=$(TARGET).o
default:
    make -C $(KDIR) M=$(PWD) modules
clean:
    make -C $(KDIR) M=$(PWD) clean

注意:makefile中的单引号均为TAB键上的那个上引号。

将编译好的模块插入到内核中:

linux@linux-desktop:~/wuting/module$ sudo insmod procfs_example.ko
[sudo] password for linux: 


由于/proc下包含的信息比较多,因此用了head和 tail命令只显示了一部分信息

linux@linux-desktop:~/wuting/module$ lsmod |head
Module                  Size  Used by
procfs_example          3896  0 
nls_iso8859_1           4992  0 
nls_cp437               6656  0 
vfat                   14464  0 
fat                    54556  1 vfat
usb_storage            73792  0 
libusual               19236  1 usb_storage
rfcomm                 41744  2 
l2cap                  25728  13 rfcomm
linux@linux-desktop:~/wuting/module$ dmesg |tail
[19202.241219]  sdb: unknown partition table
[19202.394482] sd 5:0:0:0: [sdb] Attached SCSI removable disk
[19202.394538] sd 5:0:0:0: Attached scsi generic sg1 type 0
[19220.139084] usb 3-2: USB disconnect, address 3
[26457.279861] eth0: link down
[26458.825926] eth0: link up, 100Mbps, full-duplex, lpa 0x45E1
[27107.094930] eth0: link down
[27108.601438] eth0: link up, 100Mbps, full-duplex, lpa 0x45E1
[48044.732005] procfs_example: module license 'unspecified' taints kernel.
[48044.742141] procfs_example 1.0 initialised

进入到/proc下,看我们建立的目录是否存在
linux@linux-desktop:~/wuting/module$ ls /proc/|grep procfs_example
procfs_example                                  <=   编写的内核模块建立的目录
linux@linux-desktop:~/wuting/module$ cd /proc/procfs_example  <=进入新建的目录
linux@linux-desktop:/proc/procfs_example$ ls
bar  foo  jiffies  jiffies_too
linux@linux-desktop:/proc/procfs_example$ ls -l    <=查看创建的文件
total 0
-rw-r--r-- 1 root root 0 2009-03-18 22:00 bar
-rw-r--r-- 1 root root 0 2009-03-18 22:00 foo
-r--r--r-- 1 root root 0 2009-03-18 22:00 jiffies
lrwxrwxrwx 1 root root 7 2009-03-18 22:00 jiffies_too -> jiffies
linux@linux-desktop:/proc/procfs_example$ cat bar       
bar = 'bar'
linux@linux-desktop:/proc/procfs_example$ cat jiffies
jiffies = 12220488

   jiffies是 jiffies是内核中的一个全局变量,用来记录自系统启动以来产生的节拍数。它自从开机以来就一刻不停的增长着。所以可以用 jiffies/tick_rate 来计算计算运行了多长时间。jiffies定义在文件中:

extern unsigned long volatile jiffies;

可以使用watch cat jiffies   命令查看jiffies的动态变化情况:
阅读(2479) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~