使用二进制编辑器手动编写 bootloader

直接用二进制编辑器写机器码来实现 bootloader 是完全可行的(早期操作系统开发常用此方法)。核心是 手动写出每条指令对应的机器码,并保证启动扇区规范:512 字节 + 结尾 0xAA55


一、核心原理:指令 → 机器码对应关系

x86 16 位实模式指令有固定机器码格式,例如:

指令 机器码 说明
mov ah, 0x0e b4 0e BIOS 打印功能
mov al, 'H' b0 48 ‘H’ 的 ASCII 码 0x48
int 0x10 cd 10 BIOS 视频中断
jmp loop(无限循环) eb fe 相对偏移 0xfe 跳转自身

二、用二进制编辑器编写步骤(以打印 "Hi" 为例)

1. 确定指令与机器码

打印 'H' → 打印 'i' → 无限循环,对应机器码序列:

1
2
3
4
5
6
b4 0e    ; mov ah, 0x0e
b0 48 ; mov al, 'H'
cd 10 ; int 0x10
b0 69 ; mov al, 'i'
cd 10 ; int 0x10
eb fe ; jmp loop

共 12 字节。


2. 填充剩余字节至 510 字节

启动扇区总长度 512 字节,前 510 字节为代码 + 填充。
填充字节数 = 510 - 12 = 498 字节,使用 0x00 填充。


3. 添加启动标志(最后 2 字节)

启动扇区必须以 0xAA55 结尾(小端存储,实际写入顺序为 0x55 0xAA)。


4. 使用二进制编辑器输入字节

示例(Linux 下):

1
hexedit boot.bin

操作步骤:

  1. 打开文件(不存在会创建)
  2. 输入十六进制模式下的字节:
    • 前 12 字节:b4 0e b0 48 cd 10 b0 69 cd 10 eb fe
    • 填充 498 个 00
    • 末尾 2 字节:55 aa
  3. 保存并退出(F2 保存,Ctrl+Q 退出)

其他二进制编辑器如 blessvim 的二进制模式也可使用。


三、验证文件正确性

使用 hexdump 检查:

1
hexdump -C boot.bin

应满足:

  • 总长度 512 字节(显示 00000200 结束)
  • 前 12 字节为指令机器码
  • 中间 498 字节为 00
  • 最后 2 字节为 55 aa

四、制作镜像并测试

可直接使用 boot.bin 或生成软盘镜像:

1
dd if=boot.bin of=boot.img conv=notrunc

挂载到 VMware 或其他虚拟机并启动,屏幕应显示:

1
Hi

说明手动编写的机器码已生效。


五、关键注意事项

  1. 机器码准确性
    • 每条 x86 指令的机器码必须严格对应
    • 可参考 x86 指令集手册或在线机器码查询工具
  2. 指令长度
    • 16 位指令长度可变(1~6 字节)
    • 确保每条指令长度正确,否则后续指令可能被覆盖
  3. 填充计算
    • 启动扇区总长度必须 512 字节,否则 BIOS 无法识别

这种方式完全绕开汇编器,直接操作机器码,虽然繁琐,但能直观理解指令与二进制的对应关系,是深入学习底层原理的好方法。