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

时间:2023-01-08 16:28:23
3、使用seq_file接口的例子

    本例通过/proc/seq_file_test文件输出Linux内核的十个随机数,并与printk打印的信息进行比较。

    (1)、例子源代码 

[cpp] view plaincopyprint?
  1. #include <linux/module.h>   
  2. #include <linux/types.h>   
  3. #include <linux/kernel.h>  
  4. #include <linux/init.h>   
  5. #include <linux/random.h>  
  6. #include <linux/slab.h>   
  7. #include <linux/proc_fs.h>  
  8. #include <linux/seq_file.h>   
  9. #include <linux/list.h>   
  10.   
  11. struct mylist_random {  
  12.     struct list_head list;  
  13.     char info[50];  
  14. };  
  15.   
  16. static LIST_HEAD(test_list);  
  17.   
  18. static void *seq_start(struct seq_file *m, loff_t *pos)  
  19. {  
  20.     return seq_list_start(&test_list, *pos);;     
  21. }  
  22.   
  23. static void seq_stop(struct seq_file *m, void *v)  
  24. {  
  25.     /* No cleanup needed in this example */  
  26. }  
  27.   
  28. static void *seq_next(struct seq_file *m, void *v, loff_t *pos)  
  29. {  
  30.     return seq_list_next(v, &test_list, pos);  
  31. }  
  32.   
  33. static int seq_show(struct seq_file *m, void *v)  
  34. {  
  35.     const struct mylist_random *p = list_entry(v, struct mylist_random, list);  
  36.       
  37.     seq_printf(m, "%s", p->info);  
  38.           
  39.     return 0;  
  40. }  
  41.   
  42. static const struct seq_operations seq_test_ops = {  
  43.     .start  = seq_start,  
  44.     .next   = seq_next,  
  45.     .stop   = seq_stop,  
  46.     .show   = seq_show,  
  47. };  
  48.   
  49. static int seq_test_open(struct inode *inode, struct file *file)  
  50. {  
  51.     return seq_open(file, &seq_test_ops);  
  52. }  
  53.   
  54. static const struct file_operations seq_test_fops = {  
  55.     .owner      = THIS_MODULE,  
  56.     .open       = seq_test_open,  
  57.     .read       = seq_read,  
  58.     .llseek     = seq_lseek,  
  59.     .release    = seq_release,  
  60. };  
  61.   
  62. static int __init seq_test_init(void)  
  63. {  
  64.     int i, count;  
  65.     struct mylist_random *mylist_node;  
  66.     struct proc_dir_entry *p;  
  67.   
  68.     p = proc_create("seq_file_test", S_IRUGO, NULL, &seq_test_fops);  
  69.     if (!p)  
  70.     goto out;  
  71.   
  72.     for(i = 0; i < 10; i++) {  
  73.     mylist_node = kmalloc(sizeof(struct mylist_random), GFP_ATOMIC);  
  74.     if (!mylist_node)  
  75.         return -ENOMEM;  
  76.     memset(mylist_node, 0, sizeof(struct mylist_random));  
  77.     get_random_bytes(&count, sizeof(int));  
  78.     sprintf(mylist_node->info, "random number %d: %d\n", i, count);  
  79.     printk("%s", mylist_node->info);  
  80.     list_add_tail(&mylist_node->list, &test_list);  
  81.     }  
  82.       
  83.     return 0;  
  84. out:  
  85.     remove_proc_entry("seq_file_test", NULL);  
  86.     return -EFAULT;  
  87. }  
  88.   
  89. static void __exit seq_test_exit(void)  
  90. {  
  91.     struct list_head *p, *q;  
  92.     struct mylist_random *mylist_node;  
  93.   
  94.     list_for_each_safe(p, q, &test_list) {  
  95.     mylist_node = list_entry(p, struct mylist_random, list);  
  96.     list_del(p);  
  97.     kfree(mylist_node);  
  98.     }  
  99.   
  100.     remove_proc_entry("seq_file_test", NULL);  
  101. }  
  102.   
  103. module_init(seq_test_init);  
  104. module_exit(seq_test_exit);  
  105.   
  106. MODULE_AUTHOR("Richard Tang <tanglinux@gmail.com>");  
  107. MODULE_LICENSE("GPL");  

    (2)、编译、执行

[cpp] view plaincopyprint?
  1. //获得Ubuntu 11.04正在运行的内核版本   
  2. $ cat /proc/version  
  3. Linux version 2.6.38-13-generic (buildd@palmer) (gcc version 4.5.2 (Ubuntu/Linaro 4.5.2-8ubuntu4) ) #54-Ubuntu SMP Tue Jan 3 13:44:52 UTC 2012  
  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 += seq_file_test.o  
  16.   
  17. //编译,并把编译好的模块seq_file_test.ko加载到内核中  
  18. $ make  
  19. $ sudo insmod seq_file_test.ko  
  20.   
  21. //测试并比较采用以下两种不同方式输出的随机数   
  22. $ cat /proc/seq_file_test  
  23. random number 0: -1742888248  
  24. random number 1: 764069878  
  25. random number 2: -2023358059  
  26. random number 3: 663883285  
  27. random number 4: -1811369789  
  28. random number 5: -568958269  
  29. random number 6: 606443186  
  30. random number 7: -2108607843  
  31. random number 8: 762957660  
  32. random number 9: -2142996661  
  33.   
  34. $ dmesg | tail -10  
  35. [ 2186.806122] random number 0: -1742888248  
  36. [ 2186.806436] random number 1: 764069878  
  37. [ 2186.806448] random number 2: -2023358059  
  38. [ 2186.806454] random number 3: 663883285  
  39. [ 2186.806464] random number 4: -1811369789  
  40. [ 2186.806470] random number 5: -568958269  
  41. [ 2186.806488] random number 6: 606443186  
  42. [ 2186.806493] random number 7: -2108607843  
  43. [ 2186.806503] random number 8: 762957660  
  44. [ 2186.806509] random number 9: -2142996661