1、proc_dir_entry数据结构:
struct proc_dir_entry {
unsigned int low_ino;
unsigned short namelen;
const char *name;
mode_t mode;
nlink_t nlink;
uid_t uid;
gid_t gid;
loff_t size;
const struct inode_operations *proc_iops;
/*
* NULL ->proc_fops means "PDE is going away RSN" or
* "PDE is just created". In either case, e.g. ->read_proc won't be
* called because it's too late or too early, respectively.
*
* If you're allocating ->proc_fops dynamically, save a pointer
* somewhere.
*/
const struct file_operations *proc_fops;
struct module *owner;
struct proc_dir_entry *next, *parent, *subdir;
void *data;
read_proc_t *read_proc;
write_proc_t *write_proc;
atomic_t count; /* use count */
int pde_users; /* number of callers into module in progress */
spinlock_t pde_unload_lock; /* proc_fops checks and pde_users bumps */
struct completion *pde_unload_completion;
struct list_head pde_openers; /* who did ->open, but not ->release */
};
2、创建函数:
struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,struct proc_dir_entry *parent);
name: 要创建的文件名称;
mode: 该文件的保护掩码;
parent: 确定文件所在目录,如果置NULL,则位置为/proc下。
create_proc_entry的返回值是一个proc_dir_entry指针(或者为NULL,说明在create时发生了错误)
3、读proc(read_proc函数):
int mod_read(char *page, char **start, off_t off,
int count, int *eof, void *data);
page:数据写入到的位置(在内核空间中);
count:可写入的最大字符数;
start和off:返回多页数据时使用(通常一页是4kb);
data:表示指向私有数据的指针;
eof:文件结束参数。
4、写proc(write_proc函数):
int mod_write (struct file *filp, const char __user *buff,
unsigned long len, void *data);
filp:实际上是一个打开文件结构(可以忽略这个参数)。
buff:用户空间要写入的数据。缓冲区地址实际上是一个用户空间的缓冲区,不能直接读取它。
len :定义了在 buff 中有多少数据要被写入。
data :参数是一个指向私有数据的指针。
5.删除
void remove_proc_entry(const char *name, struct proc_dir_entry *parent);
name: 要删除的文件名称;
parent: 确定文件所在目录,如果置NULL,则位置为/proc下。
6. 实现一个proc文件
实例:
- procfile.c:
-
- #include
- #include
- #include
- #include
- #include
- #include
-
- #define MAX_COOKIE_LENGTH PAGE_SIZE
-
- static struct proc_dir_entry *proc_entry;
- static char *cookie_pot;
- static int cookie_index;
- static int next_procfile;
-
- int
- procfile_write( struct file *filp, const char __user *buff,
- unsigned long len, void *data )
- {
- int space_available = (MAX_COOKIE_LENGTH-cookie_index) + 1;
- if (len > space_available)
- {
- printk(KERN_INFO "profile: space is full!/n");
- return -ENOSPC;
- }
- if (copy_from_user( &cookie_pot[cookie_index], buff, len ))
- {
- return -EFAULT;
- }
- cookie_index += len;
- cookie_pot[cookie_index-1] = 0;
- return len;
- }
-
- int
- procfile_read(char *page, char **start, off_t off,
- int count, int *eof, void *data)
- {
- int len;
- if (off > 0)
- {
- printk(KERN_INFO "off > 0/n");
- *eof = 1;
- return 0;
- }
-
- if (next_procfile >= cookie_index)
- {
- next_procfile = 0;
- }
- len = sprintf(page, "%s/n", &cookie_pot[next_procfile]);
- next_procfile += len;
- return len;
- }
-
- static int __init procfile_module_init(void)
- {
- int ret = 0;
- cookie_pot = (char *)vmalloc( MAX_COOKIE_LENGTH );
- if (!cookie_pot)
- {
- ret = -ENOMEM;
- }
- else
- {
- memset( cookie_pot, 0, MAX_COOKIE_LENGTH );
- proc_entry = create_proc_entry( "profile", 0644, NULL );
- if (proc_entry == NULL)
- {
- ret = -ENOMEM;
- vfree(cookie_pot);
- printk(KERN_INFO "profile: Couldn't create proc entry/n");
- }
- else
- {
- cookie_index = 0;
- next_procfile = 0;
- proc_entry->read_proc = procfile_read;
- proc_entry->write_proc = procfile_write;
- proc_entry->owner = THIS_MODULE;
- printk(KERN_INFO "profile: Module loaded./n");
- }
- }
- return ret;
- }
-
- static void __exit cleanup_procfile_module(void)
- {
- remove_proc_entry("profile", &proc_root);
- vfree(cookie_pot);
- printk(KERN_INFO "profile: Module unloaded./n");
- }
-
- module_init( procfile_module_init );
- module_exit( cleanup_procfile_module );
- MODULE_LICENSE("GPL");
-
-
Makefile:
- obj-m := proc_hello.o proc_fortune.o procfile.o
- #KDIR := /lib/modules/$(shell uname -r)/build
- #PWD := $(shell pwd)
-
- PWD := $(shell pwd)
- KVER := /usr/src/linux-2.6.18.8
- KDIR := $(KVER)
-
- default:
- $(MAKE) -C $(KDIR) M=$(PWD) modules
- clean:
- $(RM) *.o *.mod.c *.ko *.symvers
进行编译:
- [root@fly procstudy]# make
- make -C /usr/src/linux-2.6.18.8 M=/home/liuxl/procstudy modules
- make[1]: Entering directory `/usr/src/linux-2.6.18.8'
- CC [M] /home/liuxl/procstudy/procfile.o
- Building modules, stage 2.
- MODPOST
- LD [M] /home/liuxl/procstudy/procfile.ko
- make[1]: Leaving directory `/usr/src/linux-2.6.18.8'
运行:
- [root@fly procstudy]# insmode procfile.o
- -bash: insmode: command not found
- [root@fly procstudy]# insmod procfile.ko
- [root@fly procstudy]# dmesg | tail -1
- profile: Module loaded.
- [root@fly procstudy]# echo "liuxl procfile successful /n" > /proc/profile
- [root@fly procstudy]# cat /proc/profile
- liuxl procfile successful /n
转自:
http://blog.csdn.net/ast_224/article/details/3715328
阅读(585) | 评论(0) | 转发(0) |