现在的位置: 首页 > 综合 > 正文

通过proc文件系统输出必要的Linux内核信息(中)

2014年05月16日 ⁄ 综合 ⁄ 共 4917字 ⁄ 字号 评论关闭

2、使用旧式proc接口的例子

    本示例比较简单,先通过kmalloc函数分配一段TANGLINUX_LEN大小的内存,然后通过tanglinux_read和tanglinux_write函数来实现对这段内存的读写操作。

    (1)、例子源代码 

  1. #include <linux/module.h>
      
  2. #include <linux/kernel.h>   
  3. #include <linux/uaccess.h>
      
  4. #include <linux/proc_fs.h>   
  5. #include <linux/slab.h>
      
  6. #include <linux/string.h>   
  7.   
  8. #define TANGLINUX_LEN 10   
  9.   
  10. static char *buf;  
  11.   
  12. static int proc_output(char *page)  
  13. {  
  14.     char *p = page;  
  15.   
  16.     p += sprintf(p, "%s", buf);  
  17.   
  18.     return p - page;  
  19. }  
  20.   
  21. static int tanglinux_read(char *page, char **start, off_t off,  
  22.               int count, int *eof, void *data)  
  23. {  
  24.     int len;  
  25.   
  26.     len = proc_output(page);  
  27.     if (len <= off + count)  
  28.         *eof = 1;  
  29.     *start = page + off;  
  30.     len -= off;  
  31.     if (len > count)  
  32.         len = count;  
  33.     if (len < 0)  
  34.         len = 0;  
  35.       
  36.     return len;  
  37. }  
  38.   
  39. static int tanglinux_write(struct file *file, const char __user *buffer,  
  40.                unsigned long count, void *data)  
  41. {  
  42.     int ret;  
  43.   
  44.     if (count > TANGLINUX_LEN) {  
  45.         printk("proc_test: buf is full!\n");  
  46.         return -ENOSPC;  
  47.     }  
  48.   
  49.     ret = copy_from_user(buf, buffer, count);  
  50.     if (ret)  
  51.         return -EFAULT;  
  52.       
  53.     return count;  
  54. }  
  55.   
  56. static int __init tanglinux_init(void)  
  57. {  
  58.     static struct proc_dir_entry *entry = NULL ;  
  59.   
  60.     buf = kmalloc(TANGLINUX_LEN, GFP_KERNEL);  
  61.     if (!buf)  
  62.         return -ENOMEM;  
  63.     memset(buf, 0, TANGLINUX_LEN);  
  64.           
  65.     entry = create_proc_entry("proc_test", S_IWUGO, NULL);  
  66.     if (!entry)  
  67.     {  
  68.         printk("proc_test: Couldn't create proc entry\n");  
  69.           
  70.         return -EFAULT;  
  71.     }  
  72.     entry->read_proc  = tanglinux_read;  
  73.     entry->write_proc = tanglinux_write;  
  74.   
  75.     return 0;  
  76. }  
  77.   
  78. static void __exit tanglinux_exit(void)  
  79. {  
  80.     remove_proc_entry("proc_test", NULL);  
  81.     kfree(buf);  
  82. }  
  83.   
  84. module_init(tanglinux_init);  
  85. module_exit(tanglinux_exit);  
  86.   
  87. MODULE_AUTHOR("Richard Tang <tanglinux@gmail.com>");  
  88. MODULE_LICENSE("GPL");  

    简要说明例子中主要函数的用法: 

  1. /* linux-2.6.38.8/include/linux/proc_fs.h */  
  2. extern struct proc_dir_entry *create_proc_entry(const char *name, mode_t mode,  
  3.                         struct proc_dir_entry *parent);  
  4. extern void remove_proc_entry(const char *name, struct proc_dir_entry *parent);  

    create_proc_entry函数用于在parent(当parent为NULL时即为在/proc目录下)目录下创建名为name的proc条目,参数mode用于设置此条目的访问权限以及文件类型(例子中设置proc_test的访问权限为所有用户可写,但只有拥有超级用户权限时才可以读)。

    remove_proc_entry函数用于删除parent(当parent为NULL时即为在/proc目录下)目录下名为name的proc条目。

    (2)、编译、加载和测试 

  1. //获得Ubuntu 11.04正在运行的内核版本   
  2. $ cat /proc/version  
  3. Linux version 2.6.38-13-generic (buildd@roseapple) (gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4) ) #53-Ubuntu SMP Mon Nov 28 19:23:39 UTC 2011  
  4.   
  5. //根据上面获得的信息,在Makefile中指定Ubuntu 11.04的内核源码目录为/usr/src/linux-headers-2.6.38-13-generic/
      
  6. # Makefile   
  7. KERN_DIR = /usr/src/linux-headers-2.6.38-13-generic/  
  8.   
  9. all:  
  10.     make -C $(KERN_DIR) M=`pwd` modules  
  11.   
  12. clean:  
  13.     make -C $(KERN_DIR) M=`pwd` modules clean  
  14.   
  15. obj-m += tanglinux.o  
  16.   
  17. //编译,并把编译好的模块tanglinux.ko加载到内核中
      
  18. $ make  
  19. $ sudo insmod tanglinux.ko  
  20.   
  21. //测试   
  22. $ sudo cat /proc/proc_test  
  23. $ echo "hello" > /proc/proc_test  
  24. $ sudo cat /proc/proc_test  
  25. hello  
  26. $ echo "hello world" > /proc/proc_test //输入超过10个字符的字符串时会出错
      
  27. bash: echo: write error: No space left on device  
  28. //通过dmesg命令可以查看到例子中printk函数打印的错误信息
      
  29. $ dmesg | tail -1  
  30. [  427.791649] proc_test: buf is full!  

抱歉!评论已关闭.