Skip to content

点亮什么与为什么

这是 Cinux 真正"上电"的第一章。前面 000 只是把工具链和 ROADMAP 摆好,机器一个字节都没跑。这一章,我们要让 BIOS 把我们写的第一段代码从磁盘读进内存、执行,并在离开实模式之前,把后面所有阶段都要用的两样东西准备好:能读盘一块配好的图形屏

这一章我们要点亮什么

一台 x86 机器按电源的那一刻,CPU 处在一个非常复古的状态——实模式。它假装自己是 1978 年的 8086:16 位寄存器、段式寻址、只能寻址 1MB、没有任何保护。BIOS 做完自检(POST)后,会去硬盘的第一个扇区(512 字节)找一段叫 MBR(Master Boot Record) 的代码,把它原封不动读进内存的 0x7C00,然后跳过去执行。这个 0x7C00 不是我们挑的,是 BIOS 和所有 PC 定死的约定。

所以我们的第一段代码,只有 512 字节的预算,要做这些事:

text
BIOS ──读扇区0──▶ 0x7C00 ──执行 MBR──┐

                   ① 把段寄存器理顺(DS=ES=SS=CS)
                   ② 给自己搭个栈
                   ③ 让 BIOS 把"第 2 段代码"从磁盘读进来
                   ④ 跳过去,把接力棒交出去

这"第 2 段代码"叫 Stage2。它住在磁盘的扇区 1 之后,被读到 0x8000。为什么要分两段?因为 MBR 那个 512 字节太挤了——光是把"读磁盘、切图形模式"这些活干完就装不下,而且 BIOS 要求第 0 扇区末尾两个字节必须是魔数 0xAA55,挤得更死。所以标准做法是:MBR 当跳板,极简;真正干活的是 Stage2

Stage2 干完这章的活就停了:

  • 打印几句话(还能看,因为还在文本模式);
  • 打开 A20 地址线(为什么需要它,下面讲);
  • 调 BIOS 的 VESA 接口,把屏幕切成 1024×768 的图形模式,并把这块"画布"(framebuffer)的物理地址、宽度、每行字节数记到一个固定地址 0x6400,留给将来的内核;
  • 然后 hlt 原地停下。

完成后你会看到:QEMU 窗口里先是几行文本(Cinux Booting...Stage2 OKMode info OK, switching...),然后屏幕"啪"地切进图形模式(黑屏,因为还没人往 framebuffer 里画东西),机器安静地停在那里。这就是 001 的全部——通电、读盘、配屏、待命。

为什么现在需要它

你可能会问:既然我们最终要写一个 64 位、有保护、有分页的现代内核,为什么一开始要窝在这么古董的实模式里?

因为 BIOS 只在实模式下存在。BIOS 提供的那些"帮我读磁盘""帮我切显示模式""帮我查内存布局"的服务,统统是 16 位实模式的中断例程(int $0x10int $0x13int $0x15 …)。一旦我们走进保护模式(下一章)、再走进长模式,CPU 就不再认这些中断了,BIOS 这套"白嫖来的能力"当场作废。

所以这里有个时序上的硬约束:所有要用到 BIOS 的活,必须在离开实模式之前做完。读盘、配图形模式、开 A20,都是这一类。这一章就是"趁着 BIOS 还在,把能蹭的服务都蹭完"。

外部依据:OSDev 的 Boot Sequence 页描述了 BIOS POST 之后加载第一个可引导扇区到 0x7C00 并跳转的标准流程;Memory Map (x86) 页给出了 0x7C00 这个约定地址的由来。精确的实模式段式地址翻译(seg<<4+offset)见 Intel SDM Vol.3A §3.3。

035_multi_terminal-45-gf25de18 · f25de18 · 2026-08-04