本篇只是做个记录,把重要的东西记录一下.
不保证正确
x86中的物理地址计算过程
这要从8086实模式说起
8086实模式 是基于 分段机制的.
该模式下有段寄存器
该模式下存在 逻辑地址[a:b] 和 (线性地址) 物理地址
段寄存器中的值和 指令中的地址 算出来 线性地址
80286 新增了 保护模式.这里我们不说 80286 , 直接从 80386 说起, 这里也不说 16位保护模式
80386 新增了 32位保护模式
该模式下 有同样的段寄存器,只是位宽不一样
该模式下存在 逻辑地址[a:b] 和 (线性地址)物理地址
段寄存器中的值 和 描述符表中的描述符 和 指令中的地址 共同算出来 线性地址(即物理地址)
80386 新增了 分页机制
此时 存在 逻辑地址[a:b] 和 线性地址(虚拟地址) 和 物理地址
段寄存器中的值 和 描述符表中的描述符 和 指令中的地址 共同算出来 线性地址(即虚拟地址)
然后 线性地址(即虚拟地址) 经过 "分页机制带来的MMU" 转换 为物理地址
注意 :
1.分页机制肯定要建立于 分段机制之上
2.分页机制开了之后,会影响到分段机制
3.分页又分段是不必要的.
在OS中一般使用平坦内存模型.
x86_64 只是增加了位宽,并弱化段模式管理,保留权限概念
但是 还是 存在 逻辑地址[a:b] 和 线性地址(虚拟地址) 和 物理地址
物理地址计算过程和 "80386 时代的分页机制" 是一样的
x86_64 弱化段模式管理,保留权限概念, TODO
注意:
在64位保护模式下,必须遵从平坦内存模型.
80386 32位保护模式 分段机制
由于 兼容性 的问题,目前 dos 仍然能在 最新的 x86_64 上跑
8086 引入的分段机制 被保留了下来 , 虽然分段机制在变化,但是还是保留了下来,且分段机制不能关闭.
arm/riscv/ 根本没有 分段机制的影子,而是只有分页机制.
可以认为 x86 独有分段机制,是个特色.
但是 x86_64 和x86 都在淡化 分段机制 的影响.但由于 为了兼容性考虑,不能去掉这个 分段机制.
intel 之前做了 尝试,不兼容 x86 , 做出了 IA64(不兼容8086实模式和不存在分段机制),结局是失败了.
x86分段机制里面充斥着一些比较复杂的概念.
段寄存器
各种段描述符
各种门描述符(包括中断门)
各种描述符表和 表基寄存器
描述符中的 选择子
x86 的 权限管理(特权级ring0-3) 也和分段基址有扯不开的关系.
现在 x86/x86_64 linux 完成系统调用的时候,仍然要通过中断门.
一个syscall过后,过程中包含了 复杂过程(受硬件 和 软件设置的 表基址寄存器IDTR 和 中断门描述符和它索引的段描述符 影响),然后才进入内核的异常向量表
而 riscv-linux 完成系统调用的时候,非常简单
一个ecall过后,过程中包含了 简单过程(受硬件 和 软件设置的 mtatus mie mtvec 寄存器影响),然后就进入内核的异常向量表
描述符与描述符表
linux
调用门
任务门
局部描述符表 LDT
任务状态段描述符 TSS
参考书籍
x86
- INTEL ARCHITECTURE SOFTWARE DEVELOPER’S MANUAL, VOLUME 1: BASIC ARCHITECTURE
- INTEL ARCHITECTURE SOFTWARE DEVELOPER’S MANUAL, VOLUME 2: INSTRUCTION SET REFERENCE
- INTEL ARCHITECTURE SOFTWARE DEVELOPER’S MANUAL, VOLUME 3: SYSTEM PROGRAMMING GUIDE
- x86 汇编语言 从实模式到保护模式 第二版 李忠
- 我所认知的BIOS 系列博客
x86_64
- 64-ia-32-architectures-software-developer-manual-volume-1-basic-architecture
- 64-ia-32-architectures-software-developer-manual-volume-2-instruction-set-reference
- 64-ia-32-architectures-software-developer-manual-volume-3-system-programming-guide
- x64架构的汇编语言和操作系统基础 李忠 未出版