Chinaunix首页 | 论坛 | 博客
  • 博客访问: 1906263
  • 博文数量: 217
  • 博客积分: 4362
  • 博客等级: 上校
  • 技术积分: 4180
  • 用 户 组: 普通用户
  • 注册时间: 2009-09-20 09:31
文章分类

全部博文(217)

文章存档

2017年(1)

2015年(2)

2014年(2)

2013年(6)

2012年(42)

2011年(119)

2010年(28)

2009年(17)

分类: LINUX

2011-10-17 21:26:54

本文是一个小程序,目的是打印一个进程的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这个进程,并且打印这个,可以仔细观察结果的~~
阅读(3198) | 评论(0) | 转发(1) |
给主人留下些什么吧!~~