一、回顾及存在问题
我们已经完成了:
1. 驻留内存的引导程序;
2. 驻留在第1个引导扇区的bootloader编写,将内核程序加载到内存执行;
3. 完成了由汇编转向C语言入口程序cstart_()地方(asm如何调用C,如何编译链接16位实模式下的C语言);
面临的问题:实模式最多支持1M内存大小,且是单任务,用户程序容易破坏操作系统内核。
二、保护模式
1. 基本概念:
(1)参考:Protected Mode - OSDev Wiki
参考:Operating Systems Development Series
The World of Protected Mode on Bona Fide OS Developer
(2)什么是保护模式(内存访问)
系统架构: CPU 从内存中获取数据和指令。内存控制器负责计算其所在的确切 RAM 芯片和内存单元。所有 I/O 端口都映射到给定的内存位置,通过 IN 和 OUT 指令访问。 系统总线是数据总线、地址总线和控制总线的组合,也称为前端总线,它将 CPU 连接到 主板上的 北桥。 如果我们将一个字节写入内存位置以供硬件设备控制器 读取,则处理器可以向设备发出信号,表明该地址处有数据。它通过整个系统总线的控制总线部分来实现这一点。这基本上就是软件与硬件设备交互的方式。(注:许多 PC 都基于早期的Intel 8042 微控制器芯片。该控制器芯片可以作为 IC(集成电路)芯片嵌入,也可以直接嵌入主板中。它通常位于南桥)。
内容映射:在 x86 架构上,处理器使用特定的内存位置来表示某些事物。例如,地址0xA000:0代表显卡中VRAM的起始位置。通过向此位置写入字节,您可以有效地更改视频内存中当前的内容以及屏幕上显示的内容。
- 0x00007C00 - 0x00007DFF - 我们的引导加载程序;
- 0x000B8000 - 0x000BFFFF - 彩色视频内存;向0x000B8000写入两个字节,我们可以有效地改变文本模式内存中的内容。
- 0x000F0000 - 0x000FFFFF - 系统 BIOS
端口映射:“端口地址”是每个控制器监听的特殊号码。这是在保护模式下与硬件通信的“唯一”方式! 启动时,ROM BIOS 为这些控制器设备分配不同的编号。机器打开时发生的第一件事是 CPU 开始尝试运行 4Gb 内存区域最末端的程序。该位置必须有某个包含 BIOS 初始化程序的 ROM。初始化代码可能很大,ROM 的大小可能高达 256Kb。操作系统程序员无法以任何方式修改或控制该过程的这个阶段。 BIOS 在任何硬件上找到任何 ROM 芯片,它们就会被映射(而不是加载)到 BIOS 选择的物理内存地址中(https://wiki.osdev.org/System_Initialization_(x86))。
代码可参考: https://github.com/b-dmitry1/BIOS
- 0x60-0x6F--键盘控制器; 如:获取键盘状态信息:in al, 64h
- 0x3B0-0x3BF-VGA/单色视频
- 0x3F0-0x3FF 软盘控制器
特权指令:只有内核级软件才能访问的指令。
- LGDT 将 GDT 的地址加载到 GDTR 中
80x86 处理器根据全局描述符表 (GDT) 映射内存区域。
A20门:当 IBM 设计IBM PC AT机器时,它使用了较新的Intel 80286 微处理器,该微处理器在实模式下与以前的 x86 微处理器不完全兼容。问题?较旧的 x86 处理器 没有地址线 A20 到 A31。他们还没有那么大的地址总线。任何超出前 1 MB 的程序都会出现回绕。虽然当时 80286 可以正常工作,但它的地址空间需要 32 条地址线。然而,如果所有 32 行均可访问,我们会再次遇到换行问题。为了解决这个问题,Intel 在处理器和系统总线之间的第 20 条地址线上放置了一个逻辑门。该逻辑门被命名为Gate A20,因为它可以启用和禁用。对于较旧的程序,对于依赖换行的程序将禁用它,而对于较新的程序则启用它。