1.地址类型
物理地址---CPU地址总线的寻址物理内存的地址信号,地址变换的最终结果
线性地址(虚拟地址)
逻辑地址---汇编程序中的地址
逻辑地址—段式管理单元—虚拟地址—页式管理—物理地址
2.段式管理:
16位的CPU拥有20位地址线(8086),它的寻址范围是2的20次方,即1M内存空间.但16位CPU寄存器只有16位置能访问64K。因此CPU加入段寄存器,采用内存分段管理模式。16位吧1M内存分为若干个逻辑段.
逻辑段的起始地址必须是16的倍数,即低4位全零。
逻辑段最大容量位64K.
逻辑地址=段基地址+段内偏移量
物理地址得到方法:
PA=段寄存器值×16+逻辑地址
eg:
访问代码段CS+IP
访问堆栈:SS+SP
3.分页管理
分页单元吧所有的内存划分位固定长度的页,长度一般与线性地址页相同。两者一一映射关系
页目录索引(12位),页表索引(10位),偏移(12位)
Linux内核的设计并没有全部采用Intel提供的段机制,仅采用分页机制(很多RISC不支持段机制),每个段的逻辑地址空间范围0-4GB,所有段的基地址均为0,逻辑地址与现行地址保持一致,Linux完全的利用了分页机制。2.6.10版本Linux采用三级分页模型,但从2.6.11版本开始,采用四级分页模型,
四级分页模型向前兼容,比如64位CPU可能采用多级分页模型,低32位与现32位CPU保持一致,高位为0.
4.虚拟内存
(1)Linux采用虚拟内存管理技术,使得每个进程都有独立的进程地址空间,大小0-3G,利用虚拟地址,不但可以保护操作系统,更重要的是用户程序可以使用比实际内存更大的地址空间。内核空间从3G-4G。
(2)每个进程用户空间是完全独立的.
(3)实际的物理内存只有当进程真的去访问新获取的虚拟内存地址时,才会有“请页机制”产生“缺页异常”,从而进入分配实际页框的程序,该异常会分配物理页,建立对应页表,这之后,虚拟地址才实实在在映射到物理地址上。
5.内存分配函数
- <linux/slab.h>
- *kmalloc(size_t size,int flags)
- (unsigned int flags)
- (unsigned int flags)
- (unsigned int flags,unsigned int order)
- (unsigned long addr)
- (unsigned long addr,unsigned long order)
详细用法,参考LDD3的学习笔记
6.内核空间
内核空间完全是由内核负责映射的,不会跟着进程改变,是固定的。
(1)物理内存896MB以上的部分称为高端内存.
从3G开始,最大869MB的线性地址成为直接内存映射区,该区域的线性地址和物理地址存在线性转换关系
线性地址=3G+物理地址
(2)动态内存映射区,该区有内核函数vmalloc来分配的,特点是线性空间连续,物理地址空间不一定连续,vmallc分配的线性地址对应的物理页可能处于低端内存,也可能出于高端内存。