【转载】linux内核笔记之高端内存映射
在32位的系统上,内核使用第3GB~第4GB的线性地址空间,共1GB大小。内核将其中的前896MB与物理内存的0~896MB进行直接映射,即线性映射,将剩余的128M线性地址空间作为访问高于896M的内存的一个窗口。
引入高端内存映射这样一个概念的主要原因就是我们所安装的内存大于1G时,内核的1G线性地址空间无法建立一个完全的直接映射来触及整个物理内存空间,而对于80x86开启PAE的情况下,允许的最大物理内存可达到64G,因此内核将自己的最后128M的线性地址空间腾出来,用以完成对高端内存的暂时性映射。
而在64位的系统上就不存在这样的问题了,因为可用的线性地址空间远大于可安装的内存。下图描述了内核1GB线性地址空间是如何划分的。

其中PAGE_OFFSET表示内核使用的1GB线性地址的起始处(第3GB),high_memory往右的部分则表示高端内存,共 128M 的线性地址。可以用来完成上述映射目的的区域为vmalloc area,Persistent kernel mappings区域和固定映射线性地址空间中的FIX_KMAP区域,这三个区域对应的映射机制分别为 非连续内存分配 , 永久内核映射和 临时内核映射 。
永久内核映射
在内核初始化页表管理机制时,专门用pkmap_page_table这个变量保存了PKMAP_BASE对应的页表项的地址,由pkmap_page_table来维护永久内核映射区的页表项的映射,页表项总数为LAST_PKMAP个。
这里的永久并不是指调用kmap()建立的映射关系会一直持续下去无法解除,而是指在调用kunmap()解除映射之间这种映射会一直存在,这是相对于临时内核映射机制而言的。
需要注意一点的是,当永久内核映射区没有空闲的页表项可供映射时,请求映射的进程会被阻塞,因此永久内核映射请求不能发生在中断和可延迟函数中。
临时内核映射
临时内核映射和永久内核映射相比,其最大的特点就是不会阻塞请求映射页框的进程,因此临时内核映射请求可以发生在中断和可延迟函数中。系统中的每个CPU都有自己的13个临时内核映射窗口,根据不同的需求(用于内核控制路径),选择不同的窗口来创建映射。每个CPU的映射窗口集合用 enum km_type 数据结构表示,该数据结构中的每个符号,如 KM_BOUNCE_READ 、 KM_USER0 或 KM_PTE0 ,标识了窗口的线性地址,其实是一个下标。当要内核建立一个临时映射时,通过 cpu_id 和 窗口下标 来确定线性地址。
临时内核映射的实现也比永久内核映射要简单,当一个进程申请在某个窗口创建映射,即使这个窗口已经在之前就建立了映射,新的映射也会建立并且覆盖之前的映射,所以说这种映射机制是临时的,并且不会阻塞当前进程。
非连续内存分配
非连续内存分配是指将物理地址不连续的页框映射到线性地址连续的线性地址空间,主要应用于大容量的内存分配。采用这种方式分配内存的主要优点是避免了外部碎片,而缺点是必须打乱内核页表,而且访问速度较连续分配的物理页框慢。
非连续内存分配的线性地址空间是从 VMALLOC_START 到 VMALLOC_END ,每当内核要用vmalloc类的函数进行非连续内存分配,就会申请一个vm_struct结构来描述对应的vmalloc区,两个vmalloc区之间的间隔至少为一个页框的大小,即PAGE_SIZE。
总结
由于内核的线性地址空间有限,因此采取上面介绍的三种方式来映射高端内存。但是每种映射的本质都是通过页表来建立线性地址与物理地址之间的联系。
永久内核映射和临时内核映射,都由内核指定了需要进行映射的页面,也就是说指定了页描述符(页描述符和物理页框之间的关系是固定不可变的)。在永久内核映射中,内核只需要在永久内核映射区找到空闲的,也就是未被映射的线性地址对应的页表项,然后将其分配给page即可,若找不到则将阻塞申请建立映射的进程;而临时内核映射更直接,连进行映射的线性地址窗口都是固定的,若是其已经分配给了某个页框,则直接抢过来用,因此之前的映射就被覆盖了,体现出了临时性。
非连续内存分配,内核不用指定具体的页框,只需指定要申请的内存大小,内核将在非连续内存分配区找到一块相应大小虚拟地址空间,然后再由伙伴系统分配页框,还要通过slab分配器为一些数据结构分配内存,最后再用同样的方式(设置PTE表项)来建立映射。
【转载】linux内核笔记之高端内存映射的更多相关文章
- 高端内存映射之kmap持久内核映射--Linux内存管理(二十)
1 高端内存与内核映射 尽管vmalloc函数族可用于从高端内存域向内核映射页帧(这些在内核空间中通常是无法直接看到的), 但这并不是这些函数的实际用途. 重要的是强调以下事实 : 内核提供了其他函数 ...
- kmalloc分配物理内存与高端内存映射--Linux内存管理(十八)
1 前景回顾 1.1 内核映射区 尽管vmalloc函数族可用于从高端内存域向内核映射页帧(这些在内核空间中通常是无法直接看到的), 但这并不是这些函数的实际用途. 重要的是强调以下事实 : 内核提供 ...
- linux arm的高端内存映射
linux arm的高端内存映射(1) vmalloc 高端内存映射 与高端映射对立的是低端映射或所谓直接映射,内核中有关变量定义它们的它们的分界点,全局变量high_memory,该变量定义在m ...
- Linux高端内存映射(上)【转】
转自:http://blog.csdn.net/vanbreaker/article/details/7579941 版权声明:本文为博主原创文章,未经博主允许不得转载. 目录(?)[-] 高端内 ...
- 高端内存映射之kmap_atomic固定映射--Linux内存管理(二十一)
1 固定映射 1.1 数据结构 linux高端内存中的临时内存区为固定内存区的一部分, 对于固定内存在linux内核中有下面描述 x86 arm arm64 arch/x86/include/asm/ ...
- 高端内存映射之vmalloc分配内存中不连续的页--Linux内存管理(十九)
1 内存中不连续的页的分配 根据上文的讲述, 我们知道物理上连续的映射对内核是最好的, 但并不总能成功地使用. 在分配一大块内存时, 可能竭尽全力也无法找到连续的内存块. 在用户空间中这不是问题,因为 ...
- linux用户空间和内核空间(内核高端内存)_转
转自:Linux用户空间与内核空间(理解高端内存) 参考: 1. 进程内核栈.用户栈 2. 解惑-Linux内核空间 3. linux kernel学习笔记-5 内存管理 Linux 操作系统和驱 ...
- Linux内核高端内存 转
Linux内核地址映射模型x86 CPU采用了段页式地址映射模型.进程代码中的地址为逻辑地址,经过段页式地址映射后,才真正访问物理内存. 段页式机制如下图. Linux内核地址空间划分 通 ...
- Linux用户空间与内核空间(理解高端内存)
Linux 操作系统和驱动程序运行在内核空间,应用程序运行在用户空间,两者不能简单地使用指针传递数据,因为Linux使用的虚拟内存机制,用户空间的数据可能被换出,当内核空间使用用户空间指针时,对应的数 ...
随机推荐
- ASP.NET MVC (一)
工作清闲好一段时间了,趁这段时间弄了弄PHP,做个了简单的MVC网页.玩了玩Android,弄了个拨号器,发短信的,嘿嘿,最满意的还是两天弄了个数独游戏.不务正业一个多月了,也该磨磨刀,接下来一段时间 ...
- Cannot spawn... TortoisePlink
error: cannot spawn "C:\Program Files\TortoiseGit\bin\TortoisePlink.exe": No such file or ...
- android小功能:checkbox使用自己的背景点击切换背景
xiazai_checkbox.xml <?xml version="1.0" encoding="utf-8"?> <selector xm ...
- redis监控状态
Redis介绍 Redis是一种高级key-value数据库.它跟memcached类似,不过数据可以持久化,而且支持的数据类型很丰富.有字符串,链表.哈希.集合和有序集合5种.支持在服务器端计算集合 ...
- oralce创建用户
oralce创建用户: sqlplus /nolog回车 -->conn esun/esun@esuntech; -->create user xlh identified by pass ...
- Mysql备份与还原实例
一.备份数据库 ----清空一下日志 mysql> reset master; Query OK, rows affected (0.02 sec) ----查看一下echo表的存储引擎 mys ...
- php blowfish加密解密具体算法
PHP Blowfish 算法的加密解密,供大家参考,具体内容如下<?php/*** php blowfish 算法* Class blowfish*/class blowfish{/*** b ...
- 3、JavaScript
1. JavaScript简介 1.1. JavaScript由来 Netscape 发明了 JavaScript JavaScript由Netscape 在1995年发明.早期的主要目的是处理 ...
- js 字符串比较
<script type="text/javascript"> function test(){ //1)纯数字之间比较 //alert(1<3);//true ...
- ReactDom.render和React.render的区别
这个是react最新版api,也就是0.14版本做出的改变.主要是为了使React能在更多的不同环境下更快.更容易构建.于是把react分成了react和react-dom两个部分.这样就为web版的 ...