理论讲解:BIOS与启动过程

1. 按下电源后发生了什么

当你按下电源键,计算机经历以下步骤:

① CPU上电,跳转到固定地址 0xFFFFFFF0
        ↓
② 执行BIOS/UEFI代码
        ↓
③ POST(加电自检)
   - 检查CPU、内存、显卡等硬件
        ↓
④ 初始化硬件设备
   - 设置中断向量表
   - 初始化显卡(文本模式)
        ↓
⑤ 查找引导设备
   - 按设定顺序检查:软盘、硬盘、光盘、USB...
        ↓
⑥ 加载引导扇区
   - 读取第一个扇区(512字节)到内存地址 0x7C00
   - 检查最后两字节是否为 0x55AA
        ↓
⑦ 跳转到 0x7C00 执行
   - 控制权从BIOS转移到我们的代码!

📝 这时CPU处于实模式(16位),可访问的内存只有1MB。

2. BIOS的职责

BIOS(Basic Input/Output System)的核心职责:

  1. 硬件自检和初始化 — 确保硬件正常
  2. 提供基本I/O服务 — 通过中断调用(int指令)
  3. 加载引导程序 — 从磁盘读取第一个扇区

BIOS中断服务

BIOS通过中断提供基本服务,我们在引导阶段会频繁使用:

中断号用途常用功能
INT 0x10视频服务打印字符、设置光标、清屏
INT 0x13磁盘服务读写磁盘扇区
INT 0x15系统服务获取内存大小
INT 0x16键盘服务读取键盘输入

示例 — 打印字符:

mov ah, 0x0E    ; 功能号:teletype输出
mov al, 'H'    ; 要打印的字符
int 0x10        ; 调用视频中断

⚠️ BIOS中断只能在实模式下使用。进入保护模式后就不能用了。

3. 主引导记录(MBR)

结构

MBR位于磁盘的第一个扇区(LBA 0),共512字节:

偏移      大小       内容
───────────────────────────────
0x000    446字节    引导代码(我们写的代码)
0x1BE     16字节    分区表项1
0x1CE     16字节    分区表项2
0x1DE     16字节    分区表项3
0x1EE     16字节    分区表项4
0x1FE      2字节    引导签名 0x55 0xAA

关键约束

  • 总大小为512字节 — 引导代码最多用446字节
  • 必须以 0xAA55 结尾 — BIOS通过这个签名判断是否是有效的引导扇区
  • 加载地址为 0x7C00 — 所有地址计算基于此

为什么是 0x7C00?

这是IBM PC设计时定下的地址。0x7C00 = 32KB - 1024B,选择这个位置是为了:

  • 在低端内存中留出足够空间给中断向量表和BIOS数据
  • 在引导扇区代码下方留出空间给栈使用
  • 0x7C00之上还有大量可用内存

4. 编写最简单的引导扇区

现在你已经了解了启动过程,让我们动手编写第一个引导扇区代码。

进入 code 目录查看完整代码和运行说明。

核心代码预览:

[BITS 16]           ; 告诉汇编器生成16位代码
[ORG 0x7C00]        ; 告诉汇编器代码从0x7C00开始
 
start:
    mov ah, 0x0E    ; BIOS功能:打印字符
    mov al, 'A'     ; 要打印的字符
    int 0x10        ; 调用BIOS视频中断
 
    jmp $           ; 无限循环($ = 当前地址)
 
times 510-($-$$) db 0   ; 用0填充到510字节
dw 0xAA55               ; 引导签名(小端序:先55后AA)

理解每一行:

代码含义
[BITS 16]CPU现在是16位实模式
[ORG 0x7C00]BIOS把我们加载到了这个地址
mov ah, 0x0E选择BIOS的”打印字符”功能
mov al, 'A'把字符’A’放入AL寄存器
int 0x10触发BIOS视频中断
jmp $死循环(没有更多代码要执行)
times 510-($-$$) db 0填充剩余空间为0
dw 0xAA55引导签名,让BIOS认可这是引导扇区

5. 与OS其他部分的关系

引导扇区是操作系统的起点。后续章节将在此基础上:

第3章 引导扇区(当前)
  └→ 第4章 Bootloader(从磁盘加载更多代码)
      └→ 第5章 保护模式(从16位切换到32位)
          └→ 第6章 加载C内核

参考资料