收藏 分享(赏)

linux 内存管理 -- 高端内存的映射方式.doc

上传人:cjc2202537 文档编号:1317409 上传时间:2018-06-23 格式:DOC 页数:6 大小:24.50KB
下载 相关 举报
linux 内存管理 -- 高端内存的映射方式.doc_第1页
第1页 / 共6页
linux 内存管理 -- 高端内存的映射方式.doc_第2页
第2页 / 共6页
linux 内存管理 -- 高端内存的映射方式.doc_第3页
第3页 / 共6页
linux 内存管理 -- 高端内存的映射方式.doc_第4页
第4页 / 共6页
linux 内存管理 -- 高端内存的映射方式.doc_第5页
第5页 / 共6页
点击查看更多>>
资源描述

1、Linux 内存管理 - 高端内存的映射方式解释一:高端内存是指物理地址大于 896M 的内存。对于这样的内存,无法在“内核直接映射空间”进行映射。为什么?因为“内核直接映射空间”最多只能从 3G 到 4G,只能直接映射 1G 物理内存,对于大于 1G 的物理内存,无能为力。实际上, “内核直接映射空间”也达不到 1G, 还得留点线性空间给“内核动态映射空间”呢。因此,Linux 规定“内核直接映射空间” 最多映射 896M 物理内存。对 于高端内存,可以通过 alloc_page() 或者其它函数获得对应的 page,但是要想访问实际物理内存,还得把 page 转为线性地址才行(为什么?想想

2、 MMU 是如何访问物理内存的) ,也就是说,我们需要为高端内存对应的 page 找一个线性空间,这个过程称为高端内存映射。高端内存映射有三种方式:1、映射到“内核动态映射空间”这种方式很简单,因为通过 vmalloc() ,在”内核动态映射空间“申请内存的时候,就可能从高端内存获得页面(参看 vmalloc 的实现) ,因此说高端内存有可能映射到”内核动态映射空间“ 中。2、永久内核映射如果是通过 alloc_page() 获得了高端内存对应的 page,如何给它找个线性空间?内核专门为此留出一块线性空间,从 PKMAP_BASE 到 FIXADDR_START ,用于映射高端内存。在 2.

3、4 内核上,这个地址范围是 4G-8M 到 4G-4M 之间。这个空间起叫“内核永久映射空间”或者“永久内核映射空间” 这个空间和其它空间使用同样的页目录表,对于内核来说,就是 swapper_pg_dir,对普通进程来说,通过 CR3 寄存器指向。通常情况下,这个空间是 4M 大小,因此仅仅需要一个页表即可,内核通过来 pkmap_page_table 寻找这个页表。通过 kmap(), 可以把一个 page 映射到这个空间来由于这个空间是 4M 大小,最多能同时映射 1024 个 page。因此,对于不使用的的 page,及应该时从这个空间释放掉(也就是解除映射关系) ,通过 kunmap

4、() ,可以把一个 page 对应的线性地址从这个空间释放出来。3、临时映射内核在 FIXADDR_START 到 FIXADDR_TOP 之间保留了一些线性空间用于特殊需求。这个空间称为“固定映射空间” 在这个空间中,有一部分用于高端内存的临时映射。 这块空间具有如下特点: 1、 每个 CPU 占用一块空间 2、 在每个 CPU 占用的那块空间中,又分为多个小空间,每个小空间大小是 1 个 page,每个小空间用于一个目的,这些目的定义在 kmap_types.h 中的 km_type 中。 当要进行一次临时映射的时候,需要指定映射的目的,根据映射目的,可以找到对应的小空间,然后把这个空间的

5、地址作为映射地址。这意味着一次临时映射会导致以前的映射被覆盖。 通过 kmap_atomic() 可实现临时映射。 下图简单简单表达如何对高端内存进行映射 解释二: 高端内存含义为:线性地址空间 PAGE_OFFSET + 896M 至 4G 的最后 128M 线性地址 896M 以上的物理页框,非直接映射。有 3 种方法:非连续内存区映射,永久内核映射,临时内核映射(固定映射)从 PAGE_OFFSET 开始的线性地址区域为:PAGE_OFFSET(3G)|物理内存映射 -8M- vmalloc 区 -4K- vmalloc 区 -8K- 永久内核映射-临时内核映射(固定映射)|4G1. 非

6、连续区映射1.1 每个非连续内存区都对应一个类型为 vm_struct 的描述符,通过 next 字段,这些描述符被插入到一个 vmlist 链表中。1.2 三种非连续区的类型:VM_ALLOC - 物理内存(调用 alloc_page)和线性地址同时申请,物理内存是 _GFP_HIGHMEM 类型(分配顺序是 HIGH, NORMAL , DMA ) (可见 vmalloc 不仅仅可以映射 _GFP_HIGHMEM 页框,它的主要目的是为了将零散的,不连续的页框拼凑成连续的内核逻辑地址空间. )VM_MAP - 仅申请线性区,物理内存另外申请,是 VM_ALLOC 的简化版VM_IOREMA

7、P - 仅申请线性区,物理内存另外申请(这里的物理内存一般都是高端内存,大于 896M 的内存)2. 永久内核映射2.1 永久内存映射允许建立长期映射。使用主内核页表中 swapper_pg_dir 的一个专门页表。pkmap_page_table: 专门的页表。页表表项数由 LAST_PKMAP(512 或 1024)产生。page_address_htable: 存放地址的pkmap_count: 包含 LAST_PKMAP 个计数器的数组。PKMAP_BASE: 页表线性地址从 PKMAP_BASE 开始。2.2 如果 LAST_PKMAP 个项都用完,则把当前进程置为 TASK_UNI

8、NTERRUPTIBLE,并调用 schedule()3. 临时内存映射3.1 可以用在中断处理函数和可延迟函数的内部,从不阻塞。因为临时内存映射是固定内存映射的一部分,一个地址固定给一个内核成分使用。3.2 每个 CPU 都有自己的一个 13 个窗口(一个线性地址及页表项)的集合。enum km_type KM_BOUNCE_READ,KM_SKB_SUNRPC_DATA,KM_SKB_DATA_SOFTIRQ,KM_USER0,KM_USER1,KM_BIO_SRC_IRQ,KM_BIO_DST_IRQ,KM_PTE0,KM_PTE1,KM_IRQ0,KM_IRQ1,KM_SOFTIRQ0

9、,KM_SOFTIRQ1,KM_TYPE_NR;所有固定映射的固定线性地址enum fixed_addresses FIX_HOLE,FIX_VSYSCALL,.#ifdef CONFIG_HIGHMEMFIX_KMAP_BEGIN, /* reserved ptes for temporary kernel mappings */FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,#endif._end_of_permanent_fixed_addresses,/* temporary boot-time mappings, used b

10、efore ioremap() is functional */#define NR_FIX_BTMAPS 16FIX_BTMAP_END = _end_of_permanent_fixed_addresses,FIX_BTMAP_BEGIN = FIX_BTMAP_END + NR_FIX_BTMAPS - 1,FIX_WP_TEST,_end_of_fixed_addresses;3.3 注意 fixed_addresses 的地址从上至下是倒着的,FIX_HOLE 的地址等于 0xfffff000,是一个洞#define _fix_to_virt(x) (FIXADDR_TOP - (x

11、) next) printk(“%p %p %dn“, tmp, tmp-addr, tmp-size用户空间当然可以使用高端内存,而且是正常的使用,内核在分配那些不经常使用的内存时,都用高端内存空间(如果有) ,所谓不经常使用是相对来说的,比如内核的一些数据结构就属于经常使用的,而用户的一些数据就属于不经常使用的。用户在启动一个应用程序时,是需要内存的,而每个应用程序都有 3G 的线性地址,给这些地址映射页表时就可以直接使用高端内存。而且还要纠正一点的是:那 128M 线性地址不仅仅是用在这些地方的,如果你要加载一个设备,而这个设备需要映射其内存到内核中,它也需要使用这段线性地址空间来完成,

12、否则内核就不能访问设备上的内存空间了。总之,内核的高端线性地址是为了访问内核固定映射以外的内存资源实际上高端内存是针对内核一段特殊的线性空间提出的概念,和实际的物理内存是两码事。进程在使用内存时,触发缺页异常,具体将哪些物理页映射给用户进程是内核考虑的事情。在用户空间中没有高端内存这个概念。 解释四(代码解释 是基于 linux2.4 内核代码的) 发表于 2009 年 12 月 20 日 23:27:00 | 评论( loading. ) | 编辑| 举报| 收藏 旧一篇:linux 内核启动代码解释网站 | 新一篇: 读内存初始化代码有感查看最新精华文章 请访问博客首页相关文章 本文来自 CSDN 博客,转载请标明出处:http:/

展开阅读全文
相关资源
猜你喜欢
相关搜索
资源标签

当前位置:首页 > 企业管理 > 经营企划

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报