从零到一手写操作系统(四、硬件知识 1)CPU工作模式)

image.png

如果追忆会荡起涟漪,那么今天的秋红落叶和晴空万里都归你
https://aeneag.xyz
微信公众号:技术乱舞
艾恩凝

手写操作系统目录

硬件知识

4.1)CPU工作模式

4.1.1)实模式

实模式,又叫实地址模式。运行真实的指令,直接执行指令的真实功能,发向内存的地址是真实的,并且不加限制。

4.1.1.1)实模式寄存器

007实模式寄存器.png

4.1.1.2)实模式访问内存

008实模式.png

代码段CS IP段,栈段SS SP段

4.1.1.3)实模式中断

1、硬件中断,中断控制器发送给CPU一个信号,CPU对信号做出应答,然后中断控制器会将中断号发送给CPU

2、软件中断,CPU执行INT指令 int 21h ,后面是软中断号

009中断实模式.png

4.1.2)保护模式

简言之,就是随着规模不断增加,计算量,内存等需求更大。

内存大了,解决寻址问题,16位只能2的16次方个地址,那么32位的就出现了

另一方面,指令不加区分,对内存访问的地址不加限制

4.1.2.1)保护模式寄存器

010保护寄存器.png

4.1.2.2)保护模式特权级

R0-R3,为了区分指令和资源,R0可以执行任何指令,并以此递减。
011特权级.png

4.1.2.3)保护模式的段描述符

012段.png

多个段描述符在内存中形成全局段描述符表,该表的基地址和长度由 CPU 和 GDTR 寄存器指示。如下图所示。
013.png

段寄存器中不再存段基地址,而是具体段描述符的索引,访问一个内存地址时,段寄存器中的索引首先会结合 GDTR 寄存器找到内存中的段描述符,再根据其中的段信息判断能不能访问成功。

4.1.3.4)保护模式段选择子

014.png

上图是段选择器中的内容,影子寄存器是靠硬件来操作的,对系统程序员不可见,是硬件为了减少性能损耗而设计的一个段描述符的高速缓存,不然每次内存访问都要去内存中查表,那性能损失是巨大的,影子寄存器也正好是 64 位,里面存放了 8 字节段描述符数据。

CPL:当前权限级别

RPL:请求权限级别

DPL:描述符权限级别

看别人的描述怎么就这么晦涩难懂呢,CPL是你的权限,RPL是你要请求的权限级别,一般是CPL=RPL,也可以CPL<RPL,毕竟就四个权限级别,但是如果 CPL > DPL,那么CPU就禁止你访问了,权限不够。

4.1.2.5)保护模式平坦模型

可以看4.1.7中的段描述符,CPU 32 位的寄存器最多只能产生 4GB 大小的地址,而一个段长度也只能是 4GB,所以我们把所有段的基地址设为 0,段的长度设为 0xFFFFF,段长度的粒度设为 4KB,这样所有的段都指向同一个(0~4GB-1)字节大小的地址空间。

 1GDT_START:
 2knull_dsc: dq 0
 3;第一个段描述符CPU硬件规定必须为0
 4kcode_dsc: dq 0x00cf9e000000ffff
 5;段基地址=0,段长度=0xfffff
 6;G=1,D/B=1,L=0,AVL=0 
 7;P=1,DPL=0,S=1
 8;T=1,C=1,R=1,A=0
 9kdata_dsc: dq 0x00cf92000000ffff
10;段基地址=0,段长度=0xfffff
11;G=1,D/B=1,L=0,AVL=0 
12;P=1,DPL=0,S=1
13;T=0,C=0,R=1,A=0
14GDT_END:
15
16GDT_PTR:
17GDTLEN  dw GDT_END-GDT_START-1
18GDTBASE  dd GDT_START

如果想真的弄明白,就要仔细读上面的汇编代码。

4.1.2.6)保护模式中断

保护模式中断,不像实模式下,不做权限检查,直接通过中断向量表中的值装载就好了。

保护模式下的中断要权限检查,还有特权级的切换,所以就需要扩展中断向量表的信息,即每个中断用一个中断门描述符来表示,也可以简称为中断门,中断门描述符依然有自己的格式。
015保护模式中断.png

产生中断后,CPU 首先会检查中断号是否大于最后一个中断门描述符,x86 CPU 最大支持 256 个中断源(即中断号:0~255),然后检查描述符类型(是否是中断门或者陷阱门)、是否为系统描述符,是不是存在于内存中。

接着,检查中断门描述符中的段选择子指向的段描述符。

最后做权限检查,如果 CPL 小于等于中断门的 DPL,并且 CPL 大于等于中断门中的段选择子所指向的段描述符的 DPL,就指向段描述符的 DPL。(这里权限不够,所以指向DPL)

进一步的,CPL 等于中断门中的段选择子指向段描述符的 DPL,则为同级权限不进行栈切换,否则进行栈切换。如果进行栈切换,还需要从 TSS 中加载具体权限的 SS、ESP,当然也要对 SS 中段选择子指向的段描述符进行检查。(简单说TSS段就是提权时会用到

做完这一系列检查之后,CPU 才会加载中断门描述符中目标代码段选择子到 CS 寄存器中,把目标代码段偏移加载到 EIP 寄存器中。

注:此处有些知识模糊,TSS段

4.1.2.7)保护模式切换

第一步,准备全局段描述符表

1GDT_START:
2knull_dsc: dq 0
3kcode_dsc: dq 0x00cf9e000000ffff
4kdata_dsc: dq 0x00cf92000000ffff
5GDT_END:
6GDT_PTR:
7GDTLEN  dw GDT_END-GDT_START-1
8GDTBASE  dd GDT_START

第二步,加载设置 GDTR 寄存器,使之指向全局段描述符表。

1lgdt [GDT_PTR]

第三步,设置 CR0 寄存器,开启保护模式。

1;开启 PE
2mov eax, cr0
3bts eax, 0 ; CR0.PE =1
4mov cr0, eax

第四步,进行长跳转,加载 CS 段寄存器,即段选择子。jmp dword 0x8 :_32bits_mode ;_32bits_mode为32位代码标号即段偏移。

4.1.3)长模式

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

4.1.3.1)长模式寄存器

016长模式寄存器.png

4.1.3.2)长模式段描述符

017长模式描述符.png

当描述符中的 L=1,D/B=0 时,就是 64 位代码段,DPL 还是 0~3 的特权级。然后有多个段描述在内存中形成一个全局段描述符表,同样由 CPU 的 GDTR 寄存器指向。

4.1.3.3)长模式中断

018长模式中断.png

首先为了支持 64 位寻址中断门描述符在原有基础上增加 8 字节,用于存放目标段偏移的高 32 位值。其次,目标代码段选择子对应的代码段描述符必须是 64 位的代码段。最后其中的 IST 是 64 位 TSS 中的 IST 指针,因为我们不使用这个特性,所以不作详细介绍。

长模式也同样在内存中有一个中断门描述符表,只不过表中的条目(如上图所示)是 16 字节大小,最多支持 256 个中断源,对中断的响应和相关权限的检查和保护模式一样,这里不再赘述。

4.1.3.4)长模式切换

第一步,准备长模式全局段描述符表。

1ex64_GDT:
2null_dsc:  dq 0
3;第一个段描述符CPU硬件规定必须为0
4c64_dsc:dq 0x0020980000000000  ;64位代码段
5d64_dsc:dq 0x0000920000000000  ;64位数据段
6eGdtLen   equ $ - null_dsc  ;GDT长度
7eGdtPtr:dw eGdtLen - 1  ;GDT界限
8     dq ex64_GDT

第二步,准备长模式下的 MMU 页表,切换到长模式必须要开启分页

1mov eax, cr4
2bts eax, 5   ;CR4.PAE = 1
3mov cr4, eax ;开启 PAE
4mov eax, PAGE_TLB_BADR ;页表物理地址
5mov cr3, eax

第三步,加载 GDTR 寄存器,使之指向全局段描述表:

1lgdt [eGdtPtr]

第四步,开启长模式,要同时开启保护模式和分页模式,在实现长模式时定义了 MSR 寄存器,需要用专用的指令 rdmsr、wrmsr 进行读写,IA32_EFER 寄存器的地址为 0xC0000080,它的第 8 位决定了是否开启长模式。

 1;开启 64位长模式
 2mov ecx, IA32_EFER
 3rdmsr
 4bts eax, 8  ;IA32_EFER.LME =1
 5wrmsr
 6;开启 保护模式和分页模式
 7mov eax, cr0
 8bts eax, 0    ;CR0.PE =1
 9bts eax, 31
10mov cr0, eax

第五步,进行跳转,加载 CS 段寄存器,刷新其影子寄存器。

1jmp 08:entry64 ;entry64为程序标号即64位偏移地址

切换到长模式和切换保护模式的流程差不多,只是需要准备的段描述符有所区别,还有就是要注意同时开启保护模式和分页模式。

手写操作系统目录


    


公众号'艾恩凝'
个人公众号
个人微信
个人微信
    吾心信其可行,
          则移山填海之难,
                  终有成功之日!
                                  ——孙文
    评论
    0 评论
avatar

取消