《操作系统真相还原》——大战MBR
在开机的一瞬间,也就是接电的一瞬间,CPU 的 cs:ip 寄存器被强制初始化为 0xF000:0xFFF0。由于开机的时候处于实模式,再重复一遍加深印象,在实模式下的段基址要乘以16,也就是左移4位,于是0xF000:0xFFF0 的等效地址将是 0xFFFF0。上面说过了,此地址便是 BIOS 的入口地址。
认识到在实模式下20位总线,最大能访问1MB的空间,而此BIOS入口地址到最大只有16B,所以真正的代码在另外的地方
分段
重定位
程序中的地址若都是绝对物理地址,那该程序必须放在内存中固定的地方,于是,两个编译出来地址相同的用户程序还真没法同时运行,只能运行一个,什么是重定位呢,简单来说就是将程序中指令的地址改写成另外一个地址,但该地址处的内容还是原地址处的内容。
访问大内存
偏移地址也要存入寄存器,而那时的寄存器是 16 位的,也就
是一个段最多可以访问到 64KB。而那时的内存再小也有 1MB,
改变段基址,由一个段变为另一个段,就像一个段在内存中飘移,
采用这种在内存中来回挪位置的方式可以访问到任意内存位置。
所以说,程序分段又是为了将大内存分成可以访问的小段,
通过这样变通的方法便能够访问到所有内存了
MBR
nasm -o mbr.bin mbr.S
如果你使用了apt-get下载的话并且使用Ubuntu 22.04很有可能会遇到错误。
bx_dbg_read_linear: physical memory read error (phy=0x0000322f3130, lin=0x00000000322f3130)
这时需要把BIOS-bochs-latest ROM 替换为 BIOS-bochs-legacy
接下来,相关配置:
# 基本配置
megs: 32# 分配 64MB 内存
romimage: file=/usr/share/bochs/BIOS-bochs-legacy
vgaromimage: file=/usr/share/bochs/VGABIOS-lgpl-latest# 启动设备(从硬盘镜像启动)
boot: disk# 硬盘镜像配置
ata0:enabled=1,ioaddr1=0x1f0,ioaddr2=0x3f0,irq=14
ata0-master: type=disk, path="c.img", mode=flat,cylinders=121,heads=16,spt=63# 启用鼠标(可选)
mouse: enabled=1# 日志输出(可选)
log: bochsout.txt
非常酷