本篇只是做个记录, 把重要的东西记录一下.
不保证正确
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 的 权限管理( 特权级ring0- 3 ) 也和分段基址有扯不开的关系.
现在 x86/ x86_64 linux 完成系统调用的时候, 仍然要通过中断门.
一个syscall过后, 过程中包含了 复杂过程( 受硬件 和 软件设置的 表基址寄存器IDTR 和 中断门描述符和它索引的段描述符 影响) , 然后才进入内核的异常向量表
而 riscv- linux 完成系统调用的时候, 非常简单
一个ecall过后, 过程中包含了 简单过程( 受硬件 和 软件设置的 mtatus mie mtvec 寄存器影响) , 然后就进入内核的异常向量表
描述符与描述符表