CPU工作模式-长模式

长模式

概述

  • 长模式又名 AMD64,因为这个标准是 AMD 公司最早定义的
  • 它使 CPU 在现有的基础上有了 64 位的处理能力,既能完成 64 位的数据运算,也能寻址 64 位的地址空间
  • 这在大型计算机上犹为重要,因为它们的物理内存通常有几百 GB

长模式寄存器

  • 在这里插入图片描述

  • 长模式相比保护模式,增加了一些通用寄存器,并扩展寄存器的位宽,所有的通用寄存器都是64位,还可以单独使用32位

  • 这个低32位可以拆分成一个低16位寄存器,低16位又可以拆分成两个8位寄存器

长模式段描述符

  • 长模式依然具备保护模式绝大多数特性,如特权级和权限检查

  • 在这里插入图片描述

  • 在长模式下,CPU 不再对段基址和段长度进行检查,只对 DPL 进行相关的检查,这个检查流程和保护模式下一样

  • 当描述符中的 L=1,D/B=0 时,就是 64 位代码段,DPL 还是 0~3 的特权级

  • 然后有多个段描述在内存中形成一个全局段描述符表,同样由 CPU 的 GDTR 寄存器指向

  • 例子 - 长模式下的段描述符表

    ex64_GDT:
    null_dsc:  dq 0
    ;第一个段描述符CPU硬件规定必须为0
    c64_dsc:dq 0x0020980000000000  ;64位代码段
    ;无效位填0
    ;D/B=0,L=1,AVL=0 
    ;P=1,DPL=0,S=1
    ;T=1,C=0,R=0,A=0
    d64_dsc:dq 0x0000920000000000  ;64位数据段
    ;无效位填0
    ;P=1,DPL=0,S=1
    ;T=0,C/E=0,R/W=1,A=0
    eGdtLen   equ $ - null_dsc  ;GDT长度
    eGdtPtr:dw eGdtLen - 1  ;GDT界限
    dq ex64_GDT
    
    • 上面代码中注释已经很清楚了,段长度和段基址都是无效的填充为 0,CPU 不做检查
    • 但是上面段描述符的 DPL=0,这说明需要最高权限即 CPL=0 才能访问
    • 若是数据段的话,G、D/B、L 位都是无效的

长模式中断

概述

  • 保护模式下为了实现对中断进行权限检查,实现了中断门描述符,在中断门描述符中存放了对应的段选择子和其段内偏移,还有 DPL 权限
  • 如果权限检查通过,则用对应的段选择子和其段内偏移装载 CS:EIP 寄存器

中断门描述符扩展

  • 在这里插入图片描述

  • 中断门描述符,就会发现其中的段内偏移只有 32 位

  • 但是长模式支持 64 位内存寻址,所以要对中断门描述符进行修改和扩展

  • 结合上图,我们可以看出长模式下中断门描述符的格式变化

    • 首先为了支持 64 位寻址中断门描述符在原有基础上增加 8 字节,用于存放目标段偏移的高 32 位值
    • 其次,目标代码段选择子对应的代码段描述符必须是 64 位的代码段
    • 最后其中的 IST 是 64 位 TSS 中的 IST 指针
  • 长模式也同样在内存中有一个中断门描述符表,只不过表中的条目(如上图所示)是 16 字节大小

  • 最多支持 256 个中断源,对中断的响应和相关权限的检查和保护模式一样

切换到长模式

概述

从实模式直接切换到长模式,也可以从保护模式切换长模式

切换模式

第一步,准备长模式全局段描述符表
ex64_GDT:
null_dsc:  dq 0
;第一个段描述符CPU硬件规定必须为0
c64_dsc:dq 0x0020980000000000  ;64位代码段
d64_dsc:dq 0x0000920000000000  ;64位数据段
eGdtLen   equ $ - null_dsc  ;GDT长度
eGdtPtr:dw eGdtLen - 1  ;GDT界限
     dq ex64_GDT
第二步,准备长模式下的 MMU 页表
  • 这个是为了开启分页模式,切换到长模式必须要开启分页,想想看,长模式下已经不对段基址和段长度进行检查了,那么内存地址空间就得不到保护了
  • 而长模式下内存地址空间的保护交给了 MMU,MMU 依赖页表对地址进行转换,页表有特定的格式存放在内存中,其地址由 CPU 的 CR3 寄存器指向
mov eax, cr4
bts eax, 5   ;CR4.PAE = 1
mov cr4, eax ;开启 PAE
mov eax, PAGE_TLB_BADR ;页表物理地址
mov cr3, eax
第三步,加载 GDTR 寄存器,使之指向全局段描述表
lgdt [eGdtPtr]
第四步, 开启长模式,要同时开启保护模式和分页模式
  • 实现长模式时定义了 MSR 寄存器,需要用专用的指令 rdmsr、wrmsr 进行读写
  • IA32_EFER 寄存器的地址为 0xC0000080,它的第 8 位决定了是否开启长模式
;开启 64位长模式
mov ecx, IA32_EFER
rdmsr
bts eax, 8  ;IA32_EFER.LME =1
wrmsr
;开启 保护模式和分页模式
mov eax, cr0
bts eax, 0    ;CR0.PE =1
bts eax, 31
mov cr0, eax 
第五步,进行跳转,加载 CS 段寄存器,刷新其影子寄存器
jmp 08:entry64 ;entry64为程序标号即64位偏移地址
最后
  • 切换到长模式和切换保护模式的流程差不多,只是需要准备的段描述符有所区别,还有就是要注意同时开启保护模式和分页模式
  • 3
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值