免费注册 查看新帖 |

Chinaunix

  平台 论坛 博客 文库
最近访问板块 发新帖
查看: 1577 | 回复: 0
打印 上一主题 下一主题

使用proc函数的实例 [复制链接]

论坛徽章:
0
跳转到指定楼层
1 [收藏(0)] [报告]
发表于 2008-10-12 16:34 |只看该作者 |倒序浏览
这个例子使用了内核模块,在/proc目录下创建一个名叫procfs_example的目录,并且在该目录下创建三个普通文件和一个软连接。一个文件名
叫foo,只读,内容为foo = 'foo';一个文件名叫bar只读,内容为bar =
'bar';一个叫jiffies,只读,它会动态地显示jiffies的值。软连接名叫jiffies_too,它是对文件jiffies的软连接。
以下是实验内容:
lzel@lzel-desktop:~/works/proc$ ls
Makefile  procfs_example.c
lzel@lzel-desktop:~/works/proc$ [color="#f00000"]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;
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);
        return len;
}
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;
}
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;
    if (copy_from_user(fb_data->value,buffer,len))
        return -EFAULT;
    fb_data->value[len] = '\n';
    return len;
}
static int __init init_procfs_example (void)
{
    int rv = 0;
   
    example_dir = proc_mkdir (MODULE_NAME,NULL);
    if (example_dir == NULL)
    {
        rv = -ENOMEM;
        goto out;
    }
    example_dir->owner = THIS_MODULE;
    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;
    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;
   
    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("bar",example_dir);
    no_bar:
        remove_proc_entry ("foo",example_dir);
    no_foo:
        remove_proc_entry ("jiffies",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);
MODULE_LICENSE("Dual BSD/GPL");
MODULE_AUTHOR("lzel");
MODULE_DESCRIPTION("procfs examples");
lzel@lzel-desktop:~/works/proc$[color="#f00000"] [color="#f00000"]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
lzel@lzel-desktop:~/works/proc$ sudo make
[sudo] password for lzel:
make -C /usr/src/linux-headers-`uname -r` M=`pwd` modules
make[1]: 正在进入目录 `/usr/src/linux-headers-2.6.24-21-generic'
  CC [M]  /home/lzel/works/proc/procfs_example.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/lzel/works/proc/procfs_example.mod.o
  LD [M]  /home/lzel/works/proc/procfs_example.ko
make[1]:正在离开目录 `/usr/src/linux-headers-2.6.24-21-generic'
lzel@lzel-desktop:~/works/proc$ ls
procfs_example.c   procfs_example.ko     procfs_example.mod.o  procfs_example.o
Makefile  Module.symvers   procfs_example.mod.c        
lzel@lzel-desktop:~/works/proc$ sudo insmod procfs_example.ko
lzel@lzel-desktop:~/works/proc$ lsmod |head
Module                  Size  Used by
procfs_example          4024  0
ipv6                  267780  10
af_packet              23812  2
rfcomm                 41744  2
l2cap                  25728  13 rfcomm
bluetooth              61156  4 rfcomm,l2cap
ppdev                  10372  0
cpufreq_conservative     8712  0
cpufreq_ondemand        9740  0
lzel@lzel-desktop:~/works/proc$ dmesg |tail
[   72.183969] Bluetooth: RFCOMM socket layer initialized
[   72.184566] Bluetooth: RFCOMM TTY layer initialized
[   72.184593] Bluetooth: RFCOMM ver 1.8
[   75.149946] NET: Registered protocol family 17
[   83.211043] NET: Registered protocol family 10
[   83.222138] lo: Disabled Privacy Extensions
[   94.443153] eth1: no IPv6 routers present
[ 4620.210470] procfs_example 1.0 initialised //初始化完成
lzel@lzel-desktop:~/works/proc$
现在到/proc中去看看,是不是如我们所设想的一样呢。
lzel@lzel-desktop:~/works/proc$ ls /proc/|grep procfs_example
procfs_example //果然有procfs_example目录,这样就让我们进入到这个目录去验证其他的文件
lzel@lzel-desktop:~/works/proc$ cd /proc/procfs_example/
lzel@lzel-desktop:/proc/procfs_example$ ll //确实有三个普通文件和一个软连接
总用量 0
-rw-r--r-- 1 root root 0 2008-10-11 20:23 bar
-rw-r--r-- 1 root root 0 2008-10-11 20:23 foo
-r--r--r-- 1 root root 0 2008-10-11 20:23 jiffies
lrwxrwxrwx 1 root root 7 2008-10-11 20:23 jiffies_too -> jiffies
lzel@lzel-desktop:/proc/procfs_example$ cat bar //查看bar
bar = 'bar'
lzel@lzel-desktop:/proc/procfs_example$ cat foo //查看foo
foo = 'foo'
lzel@lzel-desktop:/proc/procfs_example$ cat jiffies //查看jiffies
jiffies = 1153731
lzel@lzel-desktop:/proc/procfs_example$ cat jiffies_too //查看软连接
jiffies = 1158238
lzel@lzel-desktop:/proc/procfs_example$

心的读者也许看到了,两个jiffies的值是不同的。因为
jiffies是内核中的一个全局变量,用来记录自系统启动以来产生的节拍数。它自从开机以来就一刻不停的增长着。所以可以用
jiffies/tick_rate 来计算计算运行了多长时间。jiffies定义在文件中:
                        
                           
                                
                                    
                                    extern unsigned long volatile jiffies;
我们可以用一下命令动态地查看jiffies的变化情况:
lzel@lzel-desktop:/proc/procfs_example$ watch cat jiffies
或者
lzel@lzel-desktop:/proc/procfs_example$ watch cat jiffies_too
两者一样。
               
               
               

本文来自ChinaUnix博客,如果查看原文请点:http://blog.chinaunix.net/u2/73569/showart_1287015.html
您需要登录后才可以回帖 登录 | 注册

本版积分规则 发表回复

  

北京盛拓优讯信息技术有限公司. 版权所有 京ICP备16024965号-6 北京市公安局海淀分局网监中心备案编号:11010802020122 niuxiaotong@pcpop.com 17352615567
未成年举报专区
中国互联网协会会员  联系我们:huangweiwei@itpub.net
感谢所有关心和支持过ChinaUnix的朋友们 转载本站内容请注明原作者名及出处

清除 Cookies - ChinaUnix - Archiver - WAP - TOP