linux内存管理之用户态内存管理以及mmap

分配一个新的线性区

do_mmap
    =>ret = do_mmap_pgoff(file, addr, len, prot, flag, offset >> PAGE_SHIFT);
        =>len = PAGE_ALIGN(len);
        =>addr = get_unmapped_area(file, addr, len, pgoff, flags);//找到一个空闲的线性区
            =>get_area = current->mm->get_unmapped_area;
            =>addr = get_area(file, addr, len, pgoff, flags);//mm->get_unmapped_area = arch_get_unmapped_area;
                =>addr = PAGE_ALIGN(addr);
                =>vma = find_vma(mm, addr);
                    =>注意,vma && vma->vm_end > addr 的优先级是 > 更高,可以理解成 (vma && (vma->vm_end > addr))
                    =>通过红黑树查找
                full_search://for循环的含义:探测找到空闲并且满足大小的空间,用于后续分配新的vma
                    for (vma = find_vma(mm, addr); ; vma = vma->vm_next)
                        if (!vma || addr + len <= vma->vm_start)//到vma链表尾部或者在链表找到合适的空位置,参考文章《内存学习3 vma研究》http://mp.blog.csdn.net/mdeditor/index/79157302
                            mm->free_area_cache = addr + len;
                            return addr;
                        addr = vma->vm_end;//这个addr不合适,挪一个位置继续探测
        =>error = security_file_mmap(file, reqprot, prot, flags, addr, 0);
            =>security_ops->file_mmap (file, reqprot, prot, flags, addr, addr_only);        
        =>mmap_region(file, addr, len, flags, vm_flags, pgoff, accountable);
            =>vma = find_vma_prepare(mm, addr, &prev, &rb_link, &rb_parent);
            =>vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);//真正分配vma的地方
            vma->vm_mm = mm;
            vma->vm_start = addr;
            vma->vm_end = addr + len;
            vma->vm_flags = vm_flags;
            vma->vm_page_prot = protection_map[vm_flags &
                        (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
            vma->vm_pgoff = pgoff;
            =>if (file)
                vma->vm_file = file;
                get_file(file);
                error = file->f_op->mmap(file, vma);
            =>addr = vma->vm_start;
            pgoff = vma->vm_pgoff;
            vm_flags = vma->vm_flags;
            =>vma_link(mm, vma, prev, rb_link, rb_parent);//将新的vma加入链表和红黑树里面,里面很复杂,可以牵出一头牛
            =>if (vm_flags & VM_LOCKED)//如果不锁存的话届时缺页中断分配页框和刷新页表
                mm->locked_vm += len >> PAGE_SHIFT;
                make_pages_present(addr, addr + len);//分配页框和刷新页表
                    =>vma = find_vma(current->mm, addr);
                    =>ret = get_user_pages(current, current->mm, addr, len, write, 0, NULL, NULL);

分配了线性区之后只是空头支票,没有干货,当访问内存的时候的时候要走入缺页中断
另外一个与分配线性区类似的是malloc,调用do_brk

do_brk
    =>if (security_vm_enough_memory(len >> PAGE_SHIFT)) //len >> PAGE_SHIFT 把len转换成pages作为参数,
        =>security_ops->vm_enough_memory(current->mm, pages);
            =>selinux_vm_enough_memory
                =>__vm_enough_memory//判断物理内存是否够用,是否能申请下len大小的空间,这个函数貌似很有用,后续好好研究一下
    =>vma = kmem_cache_zalloc(vm_area_cachep, GFP_KERNEL);
    =>vma->vm_mm = mm;
    vma->vm_start = addr;
    vma->vm_end = addr + len;
    vma->vm_pgoff = pgoff;
    vma->vm_flags = flags;
    vma->vm_page_prot = protection_map[flags & (VM_READ|VM_WRITE|VM_EXEC|VM_SHARED)];
    =>vma_link(mm, vma, prev, rb_link, rb_parent);
    =>make_pages_present(addr, addr + len);

参考文章
linux底层内存管理–用户空间的分级分配系统以及懒惰的含义
http://blog.csdn.net/liuyuanqing2010/article/details/6680443

linux内存管理之sys_brk实现分析 和 Linux内核分析之缺页中断
http://blog.csdn.net/sadamoo/article/category/1334891

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值