本文是一个小程序,目的是打印一个进程的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这个进程,并且打印这个,可以仔细观察结果的~~
阅读(3160) | 评论(0) | 转发(1) |