`
tomhibolu
  • 浏览: 1431131 次
文章分类
社区版块
存档分类
最新评论

kernel hacker修炼之道之内存管理-线性区

 
阅读更多

浅析linux内核内存管理之线性区

作者:李万鹏


线性区的基础部分已经在《Linux进程地址空间》博文中讲解。本博文主要介绍线性区的处理:线性区的分配和释放。



首先介绍几个底层的函数


查找给定地址的最邻近区


mm_struct的mmap_cache字段指向最后一个使用的线性区对象,由于程序访问的局部性,这个线性区很可能被再次访问,所以将vma设置成mmap_cache字段。如果vma && vma->vm_end > addr && vma->vm_start <= addr则直接返回指向线性区的指针,也就是说找到了一个线性区,并且给定的地址在这个线性区内,否则遍历红黑树进行查找。注意的这里的rb_entry()的原型为:

从头节点开始遍历,找第一个vma_tmp->vm_end > addr的,注意找到的线性区不应的完全包含这个线性地址,即vma->vm_end > addr && vma->vm_start <= addr。但是这个线性区是addr右端第一个线性区。


查找一个与给定的地址区间相重叠的线性区


注意这里是说与一个给定的地址区间相重叠,start_addr~end_addr,有的人会不注意,以为是两个线性区想重叠,两个线性区是不会重叠的(即使特殊性况下重叠,原来的那个会被删除,新的覆盖原来的那个地址区间如果)。所以start_addr < vma_end,end_addr > vma_end,这样找到了重叠的线性区。


查找一个空闲的地址区间


可以看到这里如果设置了MAP_FIXED标志就直接返回了。否则根据现行地址区间的类型由函数arch_get_unmapped_area()或arch_get_unmapped_area_topdown()实现get_unmapped_area()。下面来分析arch_get_unmapped_area()的实现过程:



首先检查addr+len不能大于TASK_SIZE,如果addr存在,进行4KB对齐。如果这个地址区间不与某个线性区重叠就返回,否则在线性区的链表中进行查找。mm->free_area_cache被初始化用户地址空间的三分之一(通常是1G)。这三分之一是为预定义起始线性地址的线性区而保留的。查找到addr + len > TASK_SIZE的时候做一下标记,start_addr = addr = TASK_UNMAPPED_BASE,然后再次重三分之一的地方开始搜索,如果再次addr + len > TASK_SIZE,返回-ENOMEM。如果vma == NULL或 addr + len <= vma->vm_start,也就是addr ~ addr+len没有包含在某个线性区内则返回。


向内存描述符链表中插入一个线性区


找到一个线性区vma->start < __vma->vm_end && vma->end < __vma->vm_start,然后调用vma_link将其添加到进程描述符链表和红-黑树中。


split_vma()函数



split_vma()主要功能就是把与线性地址区间交叉的线性区分成两个小线性区。首先检查mm->map_count,即线性区的数量不能大于系统规定的最大数量。为新的线性区分配描述符,与原来的线性区很多成员相同,所以用vma来初始化new的相关字段。如果new_below为1,说明线性地址区间的末尾与线性区重叠,将new->vm_end与vma->vm_start都设为addr;如果new_below为0,说明线性地址区间的前部分与线性区重叠,将new->vm_start与vma->vm_end都设为addr。调用vma_adjust()把线性区描述符链接到线性区链表mm->mmap和红-黑树mm->mm_rb。此外,函数还要根据线性区vma的最新大小对红-黑树进行调整。



下面来介绍线性区的分配和释放


分配线性地址区间


do_mmap()函数就是一个前端,分配线性区的任务委托给do_mmap_pgoff():



首先调用get_unmapped_area()找到一个空闲的线性区(并不一定就是空闲,对get_unmapped_area分析的代码可以看到如果设置了MAP_FIXED标志就直接返回了),在munmap_back标号处进行检查,看这个找到的“空闲的线性区”是否与某个线性区重叠,如果如上边所说,是因为设置了MAP_FIXED标志就直接返回的,则调用do_munmap()对之前那个线性区进行释放,如果成功释放再次执行到munmap_back标号处,如果没有重叠的线性区此时向下执行了。如果新区间是私有的(没有设置VM_SHARED),且映射的不是磁盘上的一个文件,那么,调用vma_merge()查看前一个线性区是否可以以这样的方式进行扩展来包含新的线性区。如果可以扩展直接跳到out标号处,增加整个线性区的大小。否则分配vma描述符,设置相应字段,并将描述符添加到描述符链表和红-黑树。检查是否设置了VM_LOCKED标志,如果设置了就是这个线性区对应的物理页现在必须分配而不是等到访问的时候才分配,这是个特例要记住。设置VM_LOCKED的目的就是为了页框在内存中,访问比较快,避免了访问的时候通过page fault分配页框了,比较慢。所以此时调用make_pages_present函数,make_pages_present又调用get_user_pages函数,如果页框不在内存中就要通过page fault分配页框,并设置页表项。

释放线性地址区间



将mpnt指向要释放的地址区间后面的线性区。如果线性地址区间前部分与mpnt指向的线性区重叠,就将线性区拆成两个部分,后一部分作为一个线性区在线性地址空间内。如果线性地址区间后半部分与mpnt指向的线性区重叠,就将线性区拆成两个部分,前一部分作为一个线性区在线性地址空间内。这样就分三种情况了:

  • 线性地址区间前部分与mpnt指向的线性区重叠,后面不重叠
  • 线性地址区间后部分与mpnt指向的线性区重叠,前面不重叠
  • 线性地址区间在一个线性区的中间把这个线性区分成了三段,中间那段是要被释放的

调用detach_vmas_to_be_unmapped函数从进程的线性地址空间中删除位于线性地址区间中的线性区。调用unmap_region函数清除与线性地址区间对应的页表项并释放相应的页框。


分享到:
评论

相关推荐

    Linux常见驱动源码分析(kernel hacker修炼之道全集)--李万鹏

    Linux常见驱动源码分析(kernel hacker修炼之道)--李万鹏 李万鹏 IBM Linux Technology Center kernel team 驱动资料清单内容如下: Linux设备模型(中)之上层容器.pdf Linux设备模型(上)之底层模型.pdf Linux...

    常见驱动源码分析(kernel hacker修炼之道)-李万鹏

    这本书是“Linux kernel hacker修炼之道”的一部分,通过深入剖析各种常见的驱动源码,帮助读者提升在Linux系统中的驱动开发能力。 在Linux操作系统中,驱动程序是连接硬件与内核的桥梁,它们负责管理和控制硬件...

    常见驱动源码分析(kernel hacker修炼之道)

    《常见驱动源码分析(kernel hacker修炼之道)》这本书或课程很可能深入探讨了如何理解和编写这些驱动,旨在帮助开发者提升对Linux内核和驱动编程的理解。在这个过程中,我们将会涉及到几个关键的知识点: 1. **Linux...

    linux kernel修炼之道

    如果刚刚对linux的kernel有兴趣,想了解点什么的话,请先看看此书吧,她风趣幽默的介绍了linux的发展趣事,让你开心快乐之余慢慢领会linux的魅力,让你了解学习掌握kernel的方法。其中的很多建议经过我的实践和摸索...

    Linux内核驱动笔记

    内存管理负责分配、回收内存资源,管理虚拟内存和物理内存的映射关系,并实现内存保护机制。 Linux内核支持多种文件系统,例如ext2、fat、isofs等。虚拟文件系统(VFS)是Linux内核中的一个重要概念,它为不同文件...

    hacker成长之道

    有关hacker 的文章和资料分享给大家

    processhacker-2.39-bin

    ProcessHacker是一款强大的系统信息工具,它提供了进程管理、服务管理、硬件监控、内存查看等多种功能,深受系统...通过下载并使用"processhacker-2.39-bin"压缩包,你将能够亲身体验这些功能并提升你的系统管理技能。

    x64_processhacker_源码

    Process Hacker是一款开源、免费且功能强大的系统信息工具,它允许用户查看并管理正在运行的进程、服务、线程以及内存等系统资源。 【描述】"Process Hacker 1.1 PH1" 提示我们这是Process Hacker的早期版本,版本...

    进程黑客(Process Hacker)Processhacker-3.0.4132

    Process Hacker是一款针对高级用户的安全分析工具,它可以帮助研究人员检测和解决软件或进程在特定操作系统环境下遇到的问题。除此之外,它还可以检测恶意进程,并告知我们这些恶意进程想要实现的功能。 Process ...

    The-Hacker-Playbook-3-Translation-master.zip

    渗透测试教程资料

    processhacker-2.39-bin.rar

    Process Hacker是一款强大的系统进程管理工具,并且还可以显示CPU、GPU、IO、内存等相关使用信息。 官网地址:https://processhacker.sourceforge.io/ git地址:https://github.com/processhacker/processhacker

    Algorithm-HackerRank-Solutions-In-Scala.zip

    《Scala语言解构HackerRank算法挑战》 在编程领域,算法是不可或缺的一部分,它为计算机程序提供了高效、系统地解决问题的方法。Scala是一种多范式编程语言,融合了面向对象和函数式编程的特点,因其强大的表达能力...

    processhacker-2.23-setup

    Process Hacker是一款功能丰富的系统程序,比windows自带的任务管理器功能更强大。用户只要借助该程序就可以方便,快捷地查看相关进程的速度,内存,及模块等等,除此,还可以对相关的进程进行管理工作。

    Resource Hacker - 版本 3.4.0

    Resource Hacker 可以被用来: 1. 查看 Win32 可执行和相关文件的资源 (*.exe, *.dll, *.cpl, *.ocx),在已编译和反编译的格式下都可以。 2. 提取 (保存) 资源到文件 (*.res) 格式,作为二进制,或作为反编过的译...

    Hacker 2012.

    Hacker 2012 - Final Transfer Readme =-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=-=- Thank you for downloading Hacker 2012! Registration ------------------------------------ If you like the game, ...

    processhacker-2.39-src.rar

    Process Hacker是一款强大的系统进程管理工具,开源,并且还可以显示CPU、GPU、IO、内存等相关使用信息。 官网地址:https://processhacker.sourceforge.io/ git地址:...

    进程浏览器和内存编辑器Process Hacker

    Process Hacker 2是一种开源工具,用于监视系统进程、服务、网络连接等信息,并且还可以进行系统调试和修改。它可以帮助用户更好地了解系统运行情况,识别系统中的问题和优化系统性能。 使用Process Hacker 2可以...

Global site tag (gtag.js) - Google Analytics