内存管理子系统:
内存
内存管理子系统
对于立志从事内核开发的工程师来说,熟悉Linux 的内存管理系统非常重要.
地址类型:
1,物理地址:
物理地址是指出现在
是地址变换的最终结果;
2,线性地址 ( 虚拟地址 ):
线性地址又名
用 16进制 表示就是 0x00000000 到 0xFFFFFFFF.
3,逻辑地址:
程序代码经过编译后,在汇编程序中使用的地址;
地址转换:
CPU 要将一个
需要两步:
首先 CPU 利用
再利用
段式管理:
十六 位 CPU :
16 位 CPU
但是 16 位 CPU 用于存放地址
为了能够访问 1M 的内存空间,CPU 就采用了
16 位 CPU 把 1M 内存空间分为若干个逻辑段,
每个逻辑段的要求如下:
1,逻辑段的起始地址 ( 段地址 ) 必须是 16 的倍数,即 最后 4 个 二进制位必须全为 0.
2,逻辑段 的最大容量为 64 K.
物理地址的形成方式:
由于段地址 必须是 16 的倍数,所以值的一般形式 为 XXXX0H , 即 前 16 位 二进制是变化的,后 4 位 是固定的.
鉴于段地址的这种特性,可以只保存前 16 位 二进制来保存整个段基地址,
所以每次使用时要用段寄存器左移补 4 个 0
在确定了某个存储单元所属的段后,只是知道了该存储单元所属的范围
如果想确定 该内存单元的具体位置,还必须知道
就可以唯一的 确定内存单元在 存储器中的具体位置.
逻辑地址 = 段基地址 + 段内偏移量
由
PA = 段寄存器的值 * 16 + 逻辑地址
段寄存器是为了对内存进行分段管理而增加的,
16位 CPU 有四个段寄存器,
程序可同时访问四个不同含义的段:
1,CS + IP :
用于代码段的访问, CS 指向 存放程序的段基址, IP 指向下条要执行的指令在 CS 段的偏移量,
用这两个 寄存器就可以得到一个内存物理地址,该地址存放着一条要执行的指令.
2,SS + SP :
用于堆栈段的访问, SS 指向栈顶,
3,DS + BX :
用于数据的访问. DS 中的值左移四位得到数据段起始地址,再加上 BX 中的偏移量,
得到一个存储单元 的物理地址.
4,ES + BX :
用于附加段的访问. ES 中的值在 左移四位 得到 附加段起始地址,再加上 BX 中的偏移量,
得到一个存储单元的 物理地址.
三十二 位 CPU:
32 位 PC 的内存管理仍然采用 " 分段 " 的管理模式,逻辑地址同样由段地址和偏移量两部分组成,
32 位 PC 的内存管理和 16 位 PC 的内存管理有 相同 和不同之处,因为 32位 PC 采用了两种不同的工作模式:
实模式 和 保护模式.
实模式:
在实模式下, 32 位 CPU 的内存管理 与 16 位 CPU 是一致的.
保护模式:
段基地址长达 32 位,每个 段的最大容量可达 4G ,段寄存器的值是段地址的 “ 选择器 ” ( Selector ),
用该 “选择器” 从内存中得到一个 32 位的段地址,存储单元的物理地址就是 该段地址加上 段内偏移量,
这与 32 位 CPU 的物理地址计算方式完全不同.
三十二 位 CPU 内有 6 个段寄存器
其值在不同的模式下具有不同的意义:
1,在实模式下:
段寄存器的值 * 16 就是 段地址.
2,在保护模式下:
段寄存器的值是一个选择器,间接指出一个 32 位 的段地址.
分页管理:
从管理 和效率 的角度出发,线性地址
例如: 32 位的机器,线性地址最大可为 4G ,如果用 4K 为一个页 来划分,
这样整个线性地址就被划分为 2 的 20 次方个页.
另一类 “ 页 ” ,称之为
分页单元把所有的
它的长度一般与线性地址页是相同的.
Linux 内存管理:
Linux 内核
仅仅是
而且 为把 Linux 移植到其他平台创造了条件,因为
所有段的基地址均为0
由此可以得出,每个段的逻辑地址空间范围 为 0 - 4 GB,
因为每个段的基地址为 0 ,因此,逻辑地址 与 线性地址保持一致
在 Linux 中所提到的
看来 , Linux 巧妙的把 段机制给绕过去了,而
Linux 页式管理: