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的动态变化情况:
阅读(2498) | 评论(0) | 转发(0) |