5.1 获取物理内存容量
5.1.1 学习 Linux 获取内存的方法
Linux 2.6 内核中用 detect_memory
函数获取内存容量,其本质上是通过调用 BIOS 中断 0x15 实现的,分别是 BIOS 中断 0x15 的 3 个子功能,子功能号要放在寄存器 EAX 或 AX 中:
- EAX = 0xE820:遍历主机上全部内存
- AX = 0xE801:分别检测低 15MB 和 16MB ~ 4GB 的内存,最大支持 4GB
- AH = 0x88:最多检测出 64MB 内存,实际内存容量超过此容量也按照 64MB 返回
5.1.2 利用 BIOS 中断 0x15 子功能 0xE820 获取内存
内存信息的内容用地址范围描述符(ARDS)来描述。
ARDS 的 Type 字段的具体意义。
此中断的调用步骤:
- 填写好“调用前输入”中列出的寄存器
- 执行中断调用 int0x15
- 在 CF 位为 0 的情况下,“返回后输出”中对应的寄存器便会有对应的结果
5.1.3 利用 BIOS 中断 0X15 子功能 0xe801 获取内存
此中断的调用步骤:
- 将 AX 寄存器写入 0xE801
- 执行中断调用 int 0x15
- 在 CF 位为 0 的情况下,“返回后输出”中对应的寄存器便会有对应的结果
5.1.4 利用 BIOS 中断 0x15 子功能 0x88 获取内存
此中断的调用步骤:
- 将 AX 寄存器写入 0X88
- 执行中断调用 int 0x15
- 在 CF 位为 0 的情况下,“返回后输出”中对应的寄存器便会有对应的结果
5.1.5 实战内存容量检测
需要注意的是 loader.S 中应去掉开始的 jmp loader_start
,这是为了保证 total_mem_bytes
变量的偏移量为 0xb00。
另外,由于去掉了 jmp loader_start
,mbr.S 中的 jmp LOADER_BASE_ADDR