0. 参考资料
- https://www.zhihu.com/question/280526042
- https://blog.csdn.net/ibless/article/details/81545359
1.1 进程线性地址空间划分
在 32 位操作系统中,最大可寻址范围为 4G,这就意味着虚拟地址空间(线性地址空间)有 4G,进程地址划分方式是:0~3G用户空间、3~4G内核空间,用户进程最多只可以访问3G线性地址空间。
1.2 x86 体系架构下的两种硬件约束
- ISA 总线下的直接内存存取(DMA):只能对RAM前16MB地址进行寻址;
- 大容量RAM的32位计算机中(<4G),CPU 不能直接访问所有的物理内存,线性地址大小仅为 4G,超过 4G 大小无法访问,不仅是 4G,模糊来说,1~4G空间都无法访问;
1.3 应对硬件约束的方法
将内存区域进行划分,划分为三个管理区间:
| 区域 |
---|
ZONE_DMA | 低于16MB的内存空间 | ZONE_NORMAL | 16MB~895MB | ZONE_HIGHMEM | 896MB~4G |
内核和应用程序在访问内存时,都是操作线性地址,“均需要”借助MMU实现对应物理内存地址的映射。
对于内核来讲,前两个区域直接通过 -3G 的方式实现对应到物理内存地址的目的 —— 毕竟这样最快!(Linux 规定这样的直接映射范围最大为 896MB)。那么 ZONE_HIGHMEM 区域怎么办? 用户空间怎么进行转换?
- ZONE_HIGHMEM 区域的存在,能够帮助我们访问超过 896MB 的内存,大概的空间大小为 128MB。当内核想访问超过 896MB 的物理内存时,就借用 MMU,将某页物理内存映射到高端内存空间(线性地址空间)中,借用这段线性地址空间,用完后便归还,实现了使用有限的地址空间,访问所有物理内存的目的。
- 内核空间不关心0~3G的用户空间,这块的空间需要借助MMU完成,一般除非陷入内核,不然不会走捷径。
针对 ZONE_HIGHMEM 区域还进行了如下划分,划分为了三个区域:
- vmalloc:分配虚拟地址上连续的内存;
- persistent kernel mappings:用于较长期的动态映射,允许内核建立高端页框到内核虚拟地址空间的长期映射。永久内核映射不能用于中断处理程序和可延迟函数,因为建立永久内核映射可能阻塞当前进程;
- fixmaps:高端固定映射区域,其中的一部分用于建立临时内核映射;
更具体一点,如下图所示,小区域之间有安全区分隔:
若机器安装的物理内存超过内核地址空间范围(超过896MB,32位高端内存范围是3G+896MB~4G,64位可支持超过512TB的内核地址空间范围),就会存在高端内存。
- Linux对内存的管理分为三个层次:Node、Zone、Page三个层次
层次 | 说明 |
---|
Node(存储节点) | CPU被划分成多个节点,每个节点都有自己的一块内存,可以参考NUMA架构有关节点的介绍 | Zone(管理区) | 每一个Node(节点)中的内存被划分成多个管理区域(Zone),用于表示不同范围的内存 | Page(页面) | 每一个管理区又进一步被划分为多个页面,页面是内存管理中最基础的分配单位 |
———————————————— 版权声明:本文为CSDN博主「ibless」的原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接及本声明。 原文链接:https://blog.csdn.net/ibless/article/details/81545359
引用:https://www.kernel.org/doc/gorman/html/understand/understand005.html
|