在分析虚拟内存管理前要先看下linux内核内存的具体分配我開始就是困在这个地方。对内核内存的分类不是非常清晰。我摘录当中的一段:

内核内存地址

===========================================================================================================

在linux的内存管理中,用户使用0~3GB的地址空间。而内核仅仅是用了3GB~4GB区间的地址空间。共1GB。非连
续空间的物理映射就位于3GB~4GB之间。例如以下图示

0GB                                                          3GB                   4GB
而关于内核空间中这1GB是怎样分配的呢,详细请看下图:

一般会把内核空间中大于896M的空间称作内核空间中的高端内存。内核能够用三种不同的机制将页框映射到高端
内存:永久内核映射、暂时内核映射和非连续内存分配。本文中将要谈论的是非连续内存分配。
       从上图能够知道,在物理内存的末尾和非连续内存区之间插入了一个大小为8MB的区间,这是一个安全区,
目的是“捕获”对非连续区的非法訪问。出于相同的理由。在其他非连续区间也插入了大小为4KB的安全区。而每一个
非连续区的大小都是4KB的倍数。例如以下图:

非连续内存的线性地址空间是从VMALLOC_START~VMALLOC_END,共128MB大小。

当内核须要用vmalloc类的函数
进行非连续内存分配时,就会申请一个vm_struct结构来描写叙述相应的vmalloc区,若分配多个vmalloc的内存区,那
么相邻两个vmalloc区之间的间隔大小至少为4KB,即至少是一个页框大小PAGE——SIZE。如上图。

===============================================================================================================

这里强调下:上面的图示表示的不过虚拟地址,而实际的物理地址是分DMA和常规地址及高端地址的;

linux内核内存大概的就是上面的图示了。当中8MB说是为了安全。防止越界訪问(看了非常多书,都这么说),就是这8MB虚拟地址不做不论什么映射(这样不过虚拟地址。没有实际的物理地址浪费)

由上面的图示能够知道,前面896MB(其它架构能够能不是以896MB切割的)就是我们说的内核逻辑地址(记住是内核逻辑地址。假设就说逻辑地址的话应该是指x86架构中虚拟地址中不包含段地址部分,也就是段内偏移部分);这部分内存地址已经在系统初始化的时候和物理页做好了映射,并且是一一映射,我们一般使用的时候就是用该部分的内存地址(kmalloc函数使用就是该部分)。这段内存是很高效的,由于不须要做其它的映射和改动页表就能够直接使用。本blog是分析下虚拟内存地址的映射,主要是vmalloc函数和ioremap函数;

vmalloc函数

vmalloc函数是驱动模块常常使用的内存分配函数。该函数返回的虚拟地址连续的(事实上这也有疑问。由于上面vmalloc的虚拟地址区有4k切割地址,假设vmalloc分配的虚拟地址非常大。那么中间是否有4kb的切割地址?),可是不保证所映射的物理地址也是连续的。

它主要对上面的vmalloc_start到vmalloc_end这段内存操作,返回的虚拟地址就是这一部分的。

在大多数情况下,不鼓舞使用vmalloc来申请内存,原因: 1、通过vmalloc函数获取的内存使用效率不高(由于要自己做映射,要推断哪些是空暇页等操作)。2、有些架构上给vmalloc使用的内存地址很小。对vmalloc调用可能会由于没有空暇地址而失败;3、不能保证物理地址是连续的,对一些驱动程序来说这是硬伤;综上所述。最好不要用包括vmalloc的代码作为内核的主线代码。

以下大概来说下vmalloc函数的原型:

void *vmalloc(unsigned long size);

该函数的实现有3个步骤:1、在vmalloc区域分配一段连续的虚拟内存地址;2、通过伙伴系统获取物理页;3、通过对页表的操作。把1中获取到的虚拟地址映射到2中分配到物理页上;

注意:

1、上面的图示我们能够看出每一个vmalloc虚拟地址之间都有4kb的切割区域(其作用就是防止越界。形成一个空洞,越界时产生异常),所以vmalloc函数实现时,会在size对齐后再添加4kb大小(一个页的大小)。

2、在分配物理页时,会从高端地址(上面的图示表示的不过虚拟地址而已,物理内存分配能够看 linux内核内存分配(一、基本概念)中物理页和虚拟地址的映射图)分配。gfp为:GFB_KERNEL | _GFP_HIGHMEM;表示该函数可能睡眠,分配的物理地址来自高端物理页。

常规物理页给kmalloc使用;vmalloc函数分配高端物理页时使用alloc_page函数或者alloc_pages_node函数来分配一个整页,多次调用分配函数来完毕全部的物理页的分配,这样就不能保证全部的物理页一定连续了。

3、对虚拟地址映射时不会对额外的4k的切割地址进行映射,第2步中也不会对这4k的虚拟切割地址进行分配映射的物理页。

以下是vmalloc的映射图。图来自《深入linux设备驱动程序内核机制》

上图中:从vmalloc区域分配的两个虚拟页地址映射到物理地址的高端页面。当中高端内存是不连续的,虚拟地址最后一个页没有进行映射,那就是额外的4k切割页面。

用vmalloc分配得到的地址是不能在微处理器之外使用的。由于它们仅仅在处理器的内存管理单元上才有意义。

使用vmalloc函数的正确场合是在分配一大块连续的、仅仅在软件中存在的、用于缓冲的内存区域的时候。

ioremap函数

函数原型:void __iomem  *ioremap(unsigned long phys_addr,  size_t  size);此处的__iomem仅仅是标识返回的地址是io类型的地址;该函数用来把vmalloc区域之间的内存映射到设备I/O地址空间,这个函数和vmalloc函数的实现很相似,不同的地方就是vmalloc是通过伙伴系统分配到物理页。而ioremap函数却是利用设备的I/O空间,而不是系统物理页;至于其它操作能够看:訪问I/O内存和I/Oport设备

ioremap函数很多其它用于映射(物理的)PCI缓冲区地址到(虚拟的)内核空间。ioremap函数映射的内存须要用iounmap函数来释放;

vmalloc和kmalloc比較

kmalloc函数:

1、得到的内存保留上次使用的数据,不正确申请到的内存进行初始化(zmalloc函数会初始化申请到的内存)。

2、返回的逻辑地址(事实上也是虚拟地址)和映射的物理页都是连续的。调用该函数时可能会休眠;

3、kmalloc函数和__get_free_pages函数返回的内存地址都是虚拟地址,事实上际的物理地址须要通过MMU转换后得到(事实上MMU就是通过页表机制来转换的)。

4、kmalloc函数和__get_free_pages函数使用的虚拟地址范围与物理内存是一一相应的,可能有个常量偏移。这两个函数不须要改动页表。

5、kmalloc函数申请的内存大小是有限制的,一般依据架构决定;

vmalloc函数和ioremap函数:

1、使用效率不高,物理页不保证连续,虚拟地址保证连续。

2、vmalloc函数和ioremap函数使用的地址范围全然是虚拟的。每次分配都要通过对页表的操作来建立映射关系;

3、vmalloc函数一般用来分配大块的内存。而且返回的地址不能在微处理器之外使用;

转载地址:http://blog.csdn.net/yuzhihui_no1/article/details/47429411

转载于:https://www.cnblogs.com/clnchanpin/p/7267338.html

linux内核内存分配(三、虚拟内存管理)相关推荐

  1. linux内核函数kmalloc,Linux内核内存分配函数之devm_kmalloc和devm_kzalloc

    本文介绍Linux内核内存分配函数devm_kmalloc()和devm_kzalloc(). 一.devm_kmalloc 文件:drivers/base/devres.c,定义如下: /** * ...

  2. 【Linux 内核】Linux 内核特性 ( 组织形式 | 进程调度 | 内核线程 | 多平台虚拟内存管理 | 虚拟文件系统 | 内核模块机制 | 定制系统调用 | 网络模块架构 )

    文章目录 一.Linux 内核特性 1.Linux 内核组织形式 2.Linux 进程调度 3.Linux 内核线程 4.Linux 内核多平台虚拟内存管理 5.Linux 虚拟文件系统 6.Linu ...

  3. Linux内核分析(三)----初识linux内存管理子系统

    原文:Linux内核分析(三)----初识linux内存管理子系统 Linux内核分析(三) 昨天我们对内核模块进行了简单的分析,今天为了让我们今后的分析没有太多障碍,我们今天先简单的分析一下linu ...

  4. 【Linux 内核 内存管理】分区伙伴分配器 ② ( free_area 空闲区域结构体源码 | 分配标志位 | GFP_ZONE_TABLE 标志位区域类型映射表 |分配标志位对应的内存区域类型 )

    文章目录 一.free_area 空闲区域结构体源码分析 二.分配标志位 三.GFP_ZONE_TABLE 标志位区域类型映射表 四.分配标志位对应的内存区域类型 一.free_area 空闲区域结构 ...

  5. 【Linux 内核 内存管理】物理分配页 ⑦ ( __alloc_pages_slowpath 慢速路径调用函数源码分析 | 判断页阶数 | 读取 mems_allowed | 分配标志位转换 )

    文章目录 一.__alloc_pages_slowpath 慢速路径调用函数 二.判断页阶数 三.读取进程 mems_allowed 成员 四.分配标志位转换 五.__alloc_pages_slow ...

  6. 【Linux 内核 内存管理】物理分配页 ⑧ ( __alloc_pages_slowpath 慢速路径调用函数源码分析 | 获取首选内存区域 | 异步回收内存页 | 最低水线也分配 | 直接分配 )

    文章目录 一.获取首选内存区域 二.异步回收内存页 三.最低水线也分配 四.直接分配内存 在 [Linux 内核 内存管理]物理分配页 ② ( __alloc_pages_nodemask 函数参数分 ...

  7. 【Linux 内核 内存管理】内存管理架构 ④ ( 内存分配系统调用过程 | 用户层 malloc free | 系统调用层 brk mmap | 内核层 kmalloc | 内存管理流程 )

    文章目录 一.内存分配系统调用过程 ( 用户层 | 系统调用 | 内核层 ) 二.内存管理流程 一.内存分配系统调用过程 ( 用户层 | 系统调用 | 内核层 ) " 堆内存 " ...

  8. 【Linux 内核 内存管理】物理分配页 ⑨ ( __alloc_pages_slowpath 慢速路径调用函数源码分析 | retry 标号代码分析 )

    文章目录 一.retry 标号代码分析 二.retry 标号完整代码 在 [Linux 内核 内存管理]物理分配页 ② ( __alloc_pages_nodemask 函数参数分析 | __allo ...

  9. Linux内核内存管理(3):kmemcheck介绍

    Linux内核内存管理 kmemcheck介绍 rtoax 2021年3月 在英文原文基础上,针对中文译文增加5.10.13内核源码相关内容. 5.10.13不存在kmemcheck的概念,取代的是k ...

  10. Linux内核内存管理(2):固定映射地址(fixmap)和输入输出重映射(ioremap)

    Linux内核内存管理 固定映射地址(fixmap)和输入输出重映射(ioremap) rtoax 2021年3月 在英文原文基础上,针对中文译文增加5.10.13内核源码相关内容. Print ke ...

最新文章

  1. Centos普通用户提权至ROOT
  2. 分享懒人张RDLC报表(四)
  3. mybatis之一对多
  4. 华为电脑c语言总是错误,关于华为机试题求代码!解决方法
  5. 《Python游戏编程快速上手》第十一章猜数字,推理游戏Bagels
  6. .Net组件程序设计之线程、并发管理(二)
  7. .Net 5性能改进
  8. 分享一个用Axure写的PRD文档
  9. Python机器学习:PCA与梯度上升:04求数据的前n个主成分
  10. Oracle作业job 没有自动调度起来
  11. 蓝牙精确定位技术下的化工厂安全管理系统,蓝牙定位标签-新导智能
  12. 《Fortran 95 程序设计》阅读笔记一
  13. MOS管耗尽型和增强型的区别是什么呢?
  14. 计算机编程ebcdic码,ASCII码和EBCDIC码
  15. python海龟绘图颜色_海龟绘图
  16. 数据加密标准DES详细过程总结、代码(自运行可实现)
  17. 直线电机的matlab仿真,matlab直线电机的制作
  18. Andrew Ng 深度学习课程——序列模型
  19. 郭天祥的10天学会51单片机_第三节
  20. JTextField问题

热门文章

  1. 混合使用UITabBarController和UINavigationController
  2. 我真的还是18岁的那个我
  3. php 二位数组排序
  4. PHP使用CURL使用问题
  5. Oracle 故障整理
  6. 植物大战僵尸模式修改
  7. Codeforces 853A 贪心 优先队列
  8. LVS学习系列(1)--入门
  9. 关于bootstrap--排版(标题、强调、背景、插入符等)
  10. HTTP所承载的货物(图像、文本、软件等)要满足的条件