内核模块编程——打印一个进程的vm_area_struct

来源:互联网 发布:java 英文日期转换 编辑:程序博客网 时间:2024/06/05 00:11
本文是一个小程序,目的是打印一个进程的vm_area_struct结构体变量,进一步加深对mm_struct和vm_area_struct结构体的理解。
那我们首先来理解一下吧。
mm_struct主要是用来描述一个进程的虚拟内存,它的结构体定义如下:
  1. struct mm_struct { 
  2.   int count; 
  3.   pgd_t * pgd; 
  4.   unsigned long context; 
  5.   unsigned long start_code, end_code, start_data, end_data; 
  6.   unsigned long start_brk, brk, start_stack, start_mmap; 
  7.   unsigned long arg_start, arg_end, env_start, env_end; 
  8.   unsigned long rss, total_vm, locked_vm; 
  9.   unsigned long def_flags; 
  10.   struct vm_area_struct * mmap; 
  11.   struct vm_area_struct * mmap_avl; 
  12.   struct semaphore mmap_sem; 
  13. };
我们可以看到,这个结构体当中有许多的unsigned long类型的变量,这些变量的目的主要是用来记录地址的,比如start_code:代码段的开始地址,end_code:代码段的结束地址,等等。

这个结构体当中还有一个比较关键的地方就是vm_area_struct结构体变量,关于虚拟内存管理的最基本的管理单元就是vm_area_struct了,它描述的是一段连续的、具有相同访问属性的虚存空间,该虚存空间的大小为物理内存页面的整数倍。

小结:一个进程的虚拟地址空间主要由两个数据结构来描述,一个是高层次的mm_struct,一个是较高层次的vm_area_struct。mm_struct描述了一个进程的整个虚拟地址空间,vm_area_struct描述了虚拟地址空间的一个区。每一个进程只有一个mm_struct。

下面的这个内核模块程序是用来打印当前进程的mm_struct和vm_area_struct的程序。

  1. #include <linux/init.h>
  2. #include <linux/kernel.h>
  3. #include <linux/module.h>
  4. #include <linux/sched.h>
  5. #include <linux/mm.h>

  6. MODULE_LICENSE("Dual BSD/GPL");
  7. MODULE_AUTHOR("Sunny");

  8. static int __init print_mm_init(void)
  9. {
  10.     struct mm_struct *mymm = (&init_task)->mm;
  11.     struct vm_area_struct *pos = NULL;

  12.     printk("current process:%s %d\n", current->comm, current->pid);
  13.     for(pos = mymm->mmap; pos; pos = pos->vm_next) {
  14.         printk("0x%lx-0x%lx\t", pos->vm_start, pos->vm_end);
  15.         if(pos->vm_flags & VM_READ) {
  16.             printk("r");
  17.         } else {
  18.             printk("-");
  19.         }
  20.         if(pos->vm_flags & VM_WRITE) {
  21.             printk("w");
  22.         } else {
  23.             printk("-");
  24.         }
  25.         if(pos->vm_flags & VM_EXEC) {
  26.             printk("x");
  27.         } else {
  28.             printk("-");
  29.         }

  30.         printk("\n");
  31.     }
  32.     return 0;
  33. }

  34. static void __exit print_mm_exit(void)
  35. {
  36.     printk(KERN_ALERT"Goodbye,world\n");
  37. }

  38. module_init(print_mm_init);
  39. module_exit(print_mm_exit);
这个小程序可以作一下变化,比如把current的这个符号换成&init_task这个进程,并且打印这个,可以仔细观察结果的~~
<script>window._bd_share_config={"common":{"bdSnsKey":{},"bdText":"","bdMini":"2","bdMiniList":false,"bdPic":"","bdStyle":"0","bdSize":"16"},"share":{}};with(document)0[(getElementsByTagName('head')[0]||body).appendChild(createElement('script')).src='http://bdimg.share.baidu.com/static/api/js/share.js?v=89860593.js?cdnversion='+~(-new Date()/36e5)];</script>
阅读(1290) | 评论(0) | 转发(1) |
0

上一篇:vim的一个配置文件

下一篇:云计算项目中遇到erlang的几个小问题

相关热门文章
  • linux 常见服务端口
  • xmanager 2.0 for linux配置
  • 【ROOTFS搭建】busybox的httpd...
  • openwrt中luci学习笔记
  • 什么是shell
  • linux dhcp peizhi roc
  • 关于Unix文件的软链接
  • 求教这个命令什么意思,我是新...
  • sed -e "/grep/d" 是什么意思...
  • 谁能够帮我解决LINUX 2.6 10...
给主人留下些什么吧!~~