本文是一个小程序,目的是打印一个进程的vm_area_struct结构体变量,进一步加深对mm_struct和vm_area_struct结构体的理解。
那我们首先来理解一下吧。
mm_struct主要是用来描述一个进程的虚拟内存,它的结构体定义如下:
- struct mm_struct {
- int count;
- pgd_t * pgd;
- unsigned long context;
- unsigned long start_code, end_code, start_data, end_data;
- unsigned long start_brk, brk, start_stack, start_mmap;
- unsigned long arg_start, arg_end, env_start, env_end;
- unsigned long rss, total_vm, locked_vm;
- unsigned long def_flags;
- struct vm_area_struct * mmap;
- struct vm_area_struct * mmap_avl;
- struct semaphore mmap_sem;
- };
我们可以看到,这个结构体当中有许多的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的程序。
- #include <linux/init.h>
- #include <linux/kernel.h>
- #include <linux/module.h>
- #include <linux/sched.h>
- #include <linux/mm.h>
-
- MODULE_LICENSE("Dual BSD/GPL");
- MODULE_AUTHOR("Sunny");
-
- static int __init print_mm_init(void)
- {
- struct mm_struct *mymm = (&init_task)->mm;
- struct vm_area_struct *pos = NULL;
-
- printk("current process:%s %d\n", current->comm, current->pid);
- for(pos = mymm->mmap; pos; pos = pos->vm_next) {
- printk("0x%lx-0x%lx\t", pos->vm_start, pos->vm_end);
- if(pos->vm_flags & VM_READ) {
- printk("r");
- } else {
- printk("-");
- }
- if(pos->vm_flags & VM_WRITE) {
- printk("w");
- } else {
- printk("-");
- }
- if(pos->vm_flags & VM_EXEC) {
- printk("x");
- } else {
- printk("-");
- }
-
- printk("\n");
- }
- return 0;
- }
-
- static void __exit print_mm_exit(void)
- {
- printk(KERN_ALERT"Goodbye,world\n");
- }
-
- module_init(print_mm_init);
- module_exit(print_mm_exit);
这个小程序可以作一下变化,比如把current的这个符号换成&init_task这个进程,并且打印这个,可以仔细观察结果的~~
相关热门文章
给主人留下些什么吧!~~
评论热议