让虚拟内存管理触手可及(一)-VMA显身

一个程序编译、连接后形成的地址空间就在虚拟地址空间,在内核中,用mm_struct结构描述,为了有效的管理整个虚拟空间,又把此空间分为一个个区间叫做VMA(virtual memory Area),用vma_area_struct结构描述。VMA是虚存管理的基本单位,其组织方式有链表和红黑树。如何编写代码查看自己的进程到底有哪些虚拟区? (以下程序均来自intel OTC的nanhai.zou)

static void mtest_dump_vma_list(void)
{
    struct mm_struct *mm = current->mm;
    struct vm_area_struct *vma;
    printk("The current process is %s/n",current->comm);
    printk("mtest_dump_vma_list/n");
    down_read(&mm->mmap_sem);
    for (vma = mm->mmap;vma; vma = vma->vm_next) {
        printk("VMA 0x%lx-0x%lx ",
            vma->vm_start, vma->vm_end);
        if (vma->vm_flags & VM_WRITE)
            printk("WRITE ");
        if (vma->vm_flags & VM_READ)
            printk("READ ");
        if (vma->vm_flags & VM_EXEC)
            printk("EXEC ");
        printk("/n");
    }
    up_read(&mm->mmap_sem);
}

此代码片段比较简单,注意为什么要加down_read()和up_read()?
  
如果知道某个虚地址,比如,0x8049000, 又如何找到这个地址所在VMA是哪个?

static void  mtest_find_vma(unsigned long addr)
{
    struct vm_area_struct *vma;
    struct mm_struct *mm = current->mm;

    printk("mtest_find_vma/n");

    down_read(&mm->mmap_sem);
    vma = find_vma(mm, addr);
    if (vma && addr >= vma->vm_start) {
        printk("found vma 0x%lx-0x%lx flag %lx for addr 0x%lx/n",
            vma->vm_start, vma->vm_end, vma->vm_flags, addr);
    } else {
        printk("no vma found for %lx/n", addr);
    }
    up_read(&mm->mmap_sem);
}

 

 

内核分配打印出地址信息

 

#include <linux/module.h>
#include <linux/init.h>
#include <linux/slab.h>
#include <linux/mm.h>
#include <linux/vmalloc.h>

unsigned long pagemem;
unsigned char *kmallocmem;
unsigned char *vmallocmem;

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Chen Li-Jun, WANG Cong");

static int __init init_mmshow(void)
{
 pagemem = __get_free_page(GFP_KERNEL);
 if(!pagemem)
  goto fail3;
 printk(KERN_INFO "pagemem=0x%lx/n", pagemem);
 kmallocmem = kmalloc(100, GFP_KERNEL);
 if(!kmallocmem)
  goto fail2;
 printk(KERN_INFO "kmallocmem=0x%p/n", kmallocmem);
 vmallocmem = vmalloc(1000000);
 if(!vmallocmem)
  goto fail1;
 printk(KERN_INFO "vmallocmem=0x%p/n", vmallocmem);
 return 0;
fail1:
 kfree(kmallocmem);
fail2:
 free_page(pagemem);
fail3:
 return -1;
}

static void __exit cleanup_mmshow(void)
{
 vfree(vmallocmem);
 kfree(kmallocmem);
 free_page(pagemem);
}

module_init(init_mmshow);
module_exit(cleanup_mmshow);

 

运行结果:

 The current process is insmod.old
mtest_dump_vma_list
VMA 0x8048000-0x805f000 READ EXEC
VMA 0x805f000-0x8060000 WRITE READ
VMA 0x8060000-0x8078000 WRITE READ EXEC
VMA 0x40000000-0x40015000 READ EXEC
VMA 0x40015000-0x40016000 WRITE READ
VMA 0x40016000-0x40017000 WRITE READ
VMA 0x42000000-0x4212e000 READ EXEC
VMA 0x4212e000-0x42131000 WRITE READ
VMA 0x42131000-0x42133000 WRITE READ
VMA 0xbfff3000-0xc0000000 WRITE READ EXEC
hello world init over
pagemem=0xcda75000
kmallocmem=0xdce51600
vmallocmem=0xe0902000

 

 

 

 

 

 

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值