背景
构建一个极简的 x86 引导程序,运行于 16 位实模式,执行以下基本操作:
- 引导加载初始化
- 设置视频模式
- 显示启动信息
- 系统停止运行
启动过程
引导程序的执行流程如下:
- BIOS 将引导扇区加载至内存地址
0x7C00
- 初始化段寄存器和堆栈
- 设置文本模式,并在屏幕上打印
"Booted!"
- 系统停止,进入死循环
项目目标
提供一个精简、直观的引导加载器示例,用于演示以下内容:
- BIOS 基本交互(视频服务调用)
- 引导扇区的结构与构建规范
- 实模式下输出字符串到屏幕
该引导程序不包含高级功能(如磁盘读写、命令解析等),但可作为理解引导机制的起点
引导扇区规范说明:
- 文件大小需为 512 字节
- 使用
times 510-($-$$) db 0
填充空白区域 - 以 0xAA55 签名结尾,供 BIOS 识别为有效引导扇区
示例代码:boot.asm
用 NASM 编写的引导扇区汇编代码
[org 0x7C00] ; BIOS 加载引导扇区的默认地址
bits 16 ; 指定 16 位代码(实模式)
start:
; 初始化段寄存器
cli ; 清除中断
xor ax, ax
mov ds, ax
mov es, ax
mov ss, ax
mov sp, 0x7C00 ; 设置堆栈顶
sti ; 启用中断
; 设置视频模式为 80x25 文本模式 (BIOS 中断 10h, 功能 00h)
mov ah, 0x00
mov al, 0x03
int 0x10
; 显示字符串 "Booted!",使用 BIOS 中断 10h 的逐字符输出
mov si, message
.print_char:
lodsb ; 加载下一个字符到 AL,并自动 SI++
cmp al, 0
je .halt ; 如果是 null 字符,结束
mov ah, 0x0E ; BIOS teletype 输出功能
mov bh, 0x00 ; 页面号
mov bl, 0x07 ; 属性(灰色前景,黑色背景)
int 0x10
jmp .print_char
.halt:
cli
hlt ; 停止系统,等待中断
jmp .halt ; 死循环防止继续执行
message db 'Booted!', 0
; 填充引导扇区到 512 字节
times 510 - ($ - $$) db 0
dw 0xAA55 ; 引导扇区签名(必须)
编译与运行说明
编译(使用 NASM)
nasm -f bin boot.asm -o boot.bin
在 QEMU 中测试
qemu-system-i386 -drive file=boot.bin,format=raw
说明与分析
-
[org 0x7C00]
指示汇编器假定该程序加载在
0x7C00
地址,这是 BIOS 加载引导扇区的标准位置 -
段寄存器初始化
实模式下,段寄存器必须显式初始化,常设为
0x0000
以便段地址从 0 开始 -
文本模式设置
BIOS 中断
INT 0x10
提供多种视频服务。功能号AH=0x00
、AL=0x03
切换到 80x25 文本模式 -
字符串显示
使用 BIOS
INT 0x10
的AH=0x0E
功能一字符一字符地输出 ASCII -
引导扇区要求
- 大小必须精确为 512 字节
- 最后两个字节为
0xAA55
(小端存储为55 AA
) - 否则 BIOS 将忽略该扇区,跳过启动
ref
https://www.linkedin.com/pulse/minimal-os-qemu-hani-fahmi-augge/