深入理解Linux 内核 内存总结 一
2018-11-04 本文已影响0人
zh_harry
物理内存管理区
在一个理想的计算机体系结构中,一个页框就是一个内存存储单元,可用于任何事情:存放内核数据和用户数据,缓冲磁盘数据等等。任何种类的数据页都可以存放任何页框中,没有什么限制。
但是,实际的计算机体系结构有硬件的限制,这限制了页框可以使用的方式。尤其是,Linux 内核必须处理80x86体系结构的两件硬件约束:
- isa 总结的直接内存存取(DMA)处理吕有一个严格的限制;它们只能对ram的前16mb寻址。
- 在具有大容量ram的现代32位计算机中,cpu不能直接访问所有的物理内存,因为线性空间太小。
为了应对这两种限制,linux 2.6 把每个内存节点的物理内存
划分为3个管理区(zone)。
在80x86 UMA 体系结构中的管理区为:
-
ZONE_DMA
包含低于16MB的内存管理页框
-
ZONE_NORMAL
包含高于16MB且低于896M的内存页框 -
ZONE_HIGHMEN
包含从896mb 开始且高于896MB的内存页框
进程页表
进程的线性地址空间分成两部分
- 从0x00000000到0xbFFFFFFF(0-3G) 的线性地址,无论进程运行的用户态还是内核态都可以寻址。
- 从0xc0000000到0xFFFFFFFF(3-4G)的线性地址,只有内核态的进程才能访问。
内核空间映射
宏PAGE_OFFSET =0xC0000000(32 bit) 这是进程在线性地址空间的偏移量,也是内核线性空间的开始之处。
linux 线性地址与物理地址映射(内核0-896M)PA(Physical Address)=VA(virtual address)-PAGE_OFFSET
内核空间 参见Linux 内核p343
- high_memory 变量
内存的开始部分包含的对前896MB RAM进行映射的线性地址;直接映射的物理内存末尾所对应的线性地址保存在high_memory变量中(3g+896m)。 - 固定映射(fix-mapped linear addresses)
内存区的结尾部分包含的是固定映射的线性地址 - 持久映射(Persistent Kernel Addresses)
从PKMAP_BASE 开始,我们查找用于高端内存页框的永久内核映射的线性地址。 - 其余部分
用于非连续内存区。在物理内存映射的末尾与第一个内存区之间插入一个大小为8MB(宏VMALLOC_OFFSET)的安全区,目的是为了捕获对内存的越界访问。出于同样的理由,插入其他4kb大小于的安全区来隔离非连续的内存区。
动态内存
RAM的某部分永久地分配给内核,并用于存放内核的代码以及静态的数据结构。RAM的其余部分称为动态内存(dynamic memory)
,这不仅是进程所需的宝贵资源,也是内核本身所需的宝贵资源。
动态内存由内核动态分配,由mmu(硬件)进行寻址(线性地址转换物理地址)
(p294 & P63)
不论是内核和用户程序对内存的访问都是基于线性地址
(深入理解linux 内核P544)