1.内存地址
- 1.逻辑地址:段地址(segment)+偏移量(offset)
MMU通过分段单元(segmentation unit)电路把1转化2
- 2.线性地址:也叫虚拟地址(virtual address),uint32表示
MMU通过分页单元(paging unit)电路把2转化为3
- 3.物理地址:内存芯片级内存单元寻址,uint32 or uint26
2.硬件中的分段
- 实模式:存在的主要原因是维持处理器与早期模型的兼容,让操作系统自举
- 保护模式:
2.1 段选择符和段寄存器
- 逻辑地址:段标识/选择符(segment selector)(16bit)+相对地址偏移量(32bit)
- 段寄存器:为了方便找到段选择符,只存放段选择符
- cs:代码段寄存器,其中两位字段指明CPU的特权级(0、3分别表示内核态和用户态)
- ss:栈段寄存器
- ds:数据段寄存器,指向包含静态数据或全局数据段
- es、fs、gs:可以指向任意数据段
2.1.1 段描述符(8bytes)
- 描述了段的特征,放在GDT或LDT中
- 段首字节的线性地址、粒度标志、段长度、系统标志、特权级等信息都包含在这个字段
- 有几种广泛采用的段描述符类型:
- 代码段描述符:
- 数据段描述符:段栈是通过一般的数据段实现的
- 任务状态段描述符:用于保存处理器寄存器的内容,只出现在GDT
- 局部描述符表描述符:代表一个包含LDT的段
2.2 快速访问段描述符
- 处理器提供一种附加的非编程寄存器(包含8字节的段描述符),每当一个段选择符被装入段寄存器时,相应的段描述符就由内存装入到对应的非编程CPU寄存器,这样就没必要访问GDT或LDT了
3. linux中的分段
- 分段可以给每一个进程分配不同的线性地址空间,分页可以把同一线性地址空间的映射到不同的物理空间
- 运行在用户态的所有Linux进程都使用一对相同的段来对指令和数据寻址
- 用户代码段
- 用户数据段
- 运行在内核态的所有Linux进程都使用一对相同的段来对指令和数据寻址
- 内核代码段
- 内核数据段
- …(后面的不懂了)
4. 硬件中的分页
- 分页单元把线性地址转换成物理地址,关键是访问类型与访问权限比较
- 为了效率起见,线性地址被分成以固定长度为单位的组,称为
页
(page) - 页内部连续的线性地址被映射到连续的物理地址中(这样指定一个页的权限就指定了一组线性地址的存取权限)
- 分页单元把所有RAM分成固定长度的页框(和页长度一致)
- 页框是主存的一部分,因此也是一个存储区域
- 页只是一个数据块,可以放在任何页或主存
- 把线性地址映射到物理地址的数据结构称为
页表
(page table)