这部分没办法,汇编计组都忘完了,只能靠嗯背了
bootasm.S
- 打开 A20 地址线:
- 作用: A20地址线控制着对于1MB以上内存的访问,启用A20地址线可以让系统正常访问超过1MB的物理内存。
- 对xv6启动过程的影响: xv6需要访问大于1MB的物理内存,因此在启动阶段需要确保A20地址线是打开的,以便能够正常访问整个内存空间。
- 构建加载 GDT(全局描述符表):
- 作用: GDT是用于管理和定义不同段(代码段、数据段等)的数据结构。在保护模式下,需要加载GDT来定义不同段的属性。
- 对xv6启动过程的影响: 在保护模式下,操作系统需要使用GDT来设置代码段和数据段等的属性。通过加载GDT,xv6确保了在32位保护模式下可以正常运行。
- 设置 CR0 寄存器:
- 作用: CR0寄存器的PE(Protection Enable)位用于启用保护模式。通过将PE位设置为1,可以使处理器切换到32位保护模式。
- 对xv6启动过程的影响: 在启动过程中,将CR0寄存器的PE位设置为1,从而使处理器进入32位保护模式。这是切换到保护模式的关键步骤。
- 长跳转(ljmp):
- 作用: 通过长跳转指令**
ljmp
**,刷新处理器的指令流水线,将执行流从16位实模式切换到32位保护模式。
- 对xv6启动过程的影响: 通过长跳转到32位代码段,xv6完成了从实模式到保护模式的切换。在32位保护模式下,操作系统可以更充分地利用处理器的功能和全局内存空间。
打开 A20
使用键盘控制器打开 A20,打开 A20 后地址总线达到了 32 根,确保系统可以正常访问大于 1MB 的内存,寻址范围达到 4GB
构建加载临时 GDT
在切换到保护模式之前提供一个简单的GDT,确保切换过程的正常进行。在实际的操作系统启动过程中,会在后续的初始化阶段替换这个临时GDT为更为复杂的操作系统所需的GDT。
设置 CR0 寄存器的 PE 位
PE 位置一开启保护模式,从此开始进入保护模式,16 位的 CPU 变成了 32 位的 CPU,此刻前后的指令格式也是不一样的,在此之前使用的 16 位指令,在此之后使用的 32 位指令
为了加快 CPU 执行指令的效率,存在着一种机制:流水线,简单来说,就是把多条指令加载到流水线上,同时运行不同指令不同部分。问题就出在这儿,进入保护模式后流水线上可能还存在 16位的指令,所以进入保护模式后需要清空流水线,无条件跳转 jmp 指令可以用来清空流水线
start32
- 设置保护模式下的数据段寄存器
- 设置栈指针 ESP 并调用
bootmain
函数
- 处理错误情况的代码段
- 进入一个无限循环
entry.S