Chinaunix首页 | 论坛 | 博客
  • 博客访问: 356090
  • 博文数量: 135
  • 博客积分: 425
  • 博客等级: 下士
  • 技术积分: 599
  • 用 户 组: 普通用户
  • 注册时间: 2012-10-19 21:10
文章分类
文章存档

2014年(3)

2013年(79)

2012年(53)

分类: LINUX

2012-11-20 23:37:55

1proc_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、读procread_proc函数):
int mod_read(char *page, char **start, off_t off,
                          int count, int *eof, void *data);
page:数据写入到的位置(在内核空间中);

count:可写入的最大字符数;
startoff:返回多页数据时使用(通常一页是4kb);

data:表示指向私有数据的指针;
eof:文件结束参数。

4、写procwrite_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文件
实例:

  1. procfile.c:
  2. #include 
  3. #include 
  4. #include 
  5. #include 
  6. #include 
  7. #include 
  8. #define MAX_COOKIE_LENGTH       PAGE_SIZE
  9. static struct proc_dir_entry *proc_entry;
  10. static char *cookie_pot;  // Space for procfile strings
  11. static int cookie_index;  // Index to write next procfile
  12. static int next_procfile;  // Index to read next procfile
  13. int
  14. procfile_write( struct file *filp, const char __user *buff,
  15.                         unsigned long len, void *data )
  16. {
  17.   int space_available = (MAX_COOKIE_LENGTH-cookie_index) + 1;
  18.   if (len > space_available)
  19.   {
  20.     printk(KERN_INFO "profile: space is full!/n");
  21.     return -ENOSPC;
  22.   }
  23.   if (copy_from_user( &cookie_pot[cookie_index], buff, len ))
  24.   {
  25.     return -EFAULT;
  26.   }
  27.   cookie_index += len;
  28.   cookie_pot[cookie_index-1] = 0;
  29.   return len;
  30. }
  31. int
  32. procfile_read(char *page, char **start, off_t off,
  33.                           int count, int *eof, void *data)
  34. {
  35.   int len;
  36.   if (off > 0)
  37.   {
  38.       printk(KERN_INFO "off > 0/n");
  39.     *eof = 1;
  40.     return 0;
  41.   }
  42.   if (next_procfile >= cookie_index)
  43.   {
  44.       next_procfile = 0;
  45.   }
  46.   len = sprintf(page, "%s/n", &cookie_pot[next_procfile]);
  47.   next_procfile += len;
  48.   return len;
  49. }
  50. static int __init procfile_module_init(void)
  51. {
  52.   int ret = 0;
  53.   cookie_pot = (char *)vmalloc( MAX_COOKIE_LENGTH );
  54.   if (!cookie_pot)
  55.   {
  56.     ret = -ENOMEM;
  57.   }
  58.   else
  59.   {
  60.     memset( cookie_pot, 0, MAX_COOKIE_LENGTH );
  61.     proc_entry = create_proc_entry( "profile", 0644, NULL );
  62.     if (proc_entry == NULL)
  63.     {
  64.       ret = -ENOMEM;
  65.       vfree(cookie_pot);
  66.       printk(KERN_INFO "profile: Couldn't create proc entry/n");
  67.     }
  68.     else
  69.     {
  70.       cookie_index = 0;
  71.       next_procfile = 0;
  72.       proc_entry->read_proc = procfile_read;
  73.       proc_entry->write_proc = procfile_write;
  74.       proc_entry->owner = THIS_MODULE;
  75.       printk(KERN_INFO "profile: Module loaded./n");
  76.     }
  77.   }
  78.   return ret;
  79. }
  80. static void __exit cleanup_procfile_module(void)
  81. {
  82.   remove_proc_entry("profile", &proc_root);
  83.   vfree(cookie_pot);
  84.   printk(KERN_INFO "profile: Module unloaded./n");
  85. }
  86. module_init( procfile_module_init );
  87. module_exit( cleanup_procfile_module );
  88. MODULE_LICENSE("GPL");


Makefile:

  1. obj-m := proc_hello.o proc_fortune.o procfile.o
  2. #KDIR := /lib/modules/$(shell uname -r)/build
  3. #PWD := $(shell pwd)
  4. PWD  := $(shell pwd)
  5. KVER := /usr/src/linux-2.6.18.8
  6. KDIR := $(KVER)
  7. default:
  8.     $(MAKE) -C $(KDIR) M=$(PWD) modules
  9. clean:
  10.     $(RM) *.o *.mod.c *.ko *.symvers


进行编译:

  1. [root@fly procstudy]# make
  2. make -C /usr/src/linux-2.6.18.8 M=/home/liuxl/procstudy modules
  3. make[1]: Entering directory `/usr/src/linux-2.6.18.8'
  4.   CC [M]  /home/liuxl/procstudy/procfile.o
  5.   Building modules, stage 2.
  6.   MODPOST
  7.   LD [M]  /home/liuxl/procstudy/procfile.ko
  8. make[1]: Leaving directory `/usr/src/linux-2.6.18.8'


运行:
  1. [root@fly procstudy]# insmode procfile.o
  2. -bash: insmode: command not found
  3. [root@fly procstudy]# insmod procfile.ko
  4. [root@fly procstudy]# dmesg | tail -1
  5. profile: Module loaded.
  6. [root@fly procstudy]# echo "liuxl procfile successful /n" > /proc/profile
  7. [root@fly procstudy]# cat /proc/profile
  8. liuxl procfile successful /n

转自:http://blog.csdn.net/ast_224/article/details/3715328
 
阅读(478) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~