第2章 编写MBR主引导记录,开始掌权
2.1 计算机启动过程
2.2 第一棒,BIOS
2.2.1 实模式下1MB内存布局
intel 8086有20条地址线,故其可以访问1MB的内存空间。0x00000-0xFFFFF
实模式1M内存:
FFFF0-FFFFF 16B BIOS jmp f000:e05b
F0000-FFFEF 64K-16B system BIOS
C8000-EFFFF 160K hardware adapter ROM or memory map
C0000-C7FFF 32K dispaly adapter BIOS
B8000-BFFFF 32K text mode display adapter
B0000-B7FFF 32K black/white mode display adapter
A0000-AFFFF 64K color mode display adapter
9FC00-9FFFF 1K EBDA Extended BIOS Data Area
7E00-9FBFF 608K memory
7C00- 7DFF 512B MBR
500- 7BFF 30K memory
400- 4FF 256B BIOS Data Area
000- 3FF 1KB Interrupt Vector Table
2.2.2 BIOS 何时苏醒
BIOS入口地址是0xFFFF0,开机时,CPU的CS:IP寄存器被强制初始化成0xF000:0xFFF0,最终地址是0xFFFF0
这里只有16B的空间,就是一条跳转指令jmp f000:e05b,跳到0xfe05b,这里是BIOS代码真正开始的地方。
2.2.3 为什么是0x7c00
BIOS最后一项工作校验启动盘中位于0盘(0磁头)0道(0柱面)1扇区(CHS方式中扇区编号从1开始)
512 bytes, mbr storage
如果扇区末尾两个字节是魔数0x55 0xaa,BIOS便认为此扇区确实是MBR,便加载到0x7c00,随后跳转到此地址,继续执行。
jmp 0: 0x7c00
0x7c00来源于IBM PC 5150(1981年)的ROM BIOS 的INT19H中断处理程序。
IBM PC 5150 BIOS 开发团队规定的这个数。
8086 CPU在0x0-0x3FF存放中断向量表。
DOS 1.0最小内存32K,MBR希望给人家尽可能多的预留空间,所以MBR放在32KB的末尾。
MBR有512字节,但还要为其所用的栈分配点空间,所以内存要大于512字节,估计1KB内存够用了。
所以用32KB的最后1KB。32K就是0x8000,减去1KB(0x400),等于0x7c00
这就是倍受质疑的0x7c00的由来,这也是我看到最合理的解释,其他书上都没有解释清楚这个魔数的由来。
2.3 让MBR先飞一会儿
2.3.1 神奇的$,$$,令人迷惑的section
1.($) 本行代码前的标号;
2.“\$\$” 本section的起始地址;
3.($-“\$\$”)指的是本段到当前行占用的字节数。
2.3.2 NASM简单用法
提前安装nasm
bochs]$ nasm
bash: nasm: 未找到命令
参考:《操作系统真象还原》第二章 ---- 编写MBR主引导记录 初尝编写的快乐 雏形已显!_编写mbr主引导程序-CSDN博客
sudo yum install nasm
nasm -h
bochs]$ nasm -v
NASM version 2.15.03 compiled on Mar 10 2022
安装完毕
nasm -f <format><filename> [-o <output>]
bin
elf
2.3.3 MBR
c2/a/boot/mbr.S
; main boot program
;------------------------------
SECTION MBR vstart=0x7c00
mov ax,cs
mov ds,ax
mov es,ax
mov ss,ax
mov fs,ax
mov sp,0x7c00
; clear screen, use int 0x06
; ----------------------------
; INT 0x10 function code:0x06 function:clear screen
; ----------------------------
;Input:
;AH function code=0x06
;AL = rows:0
;BH = row attribute?
;(CL,CH)=windows left corner(x,y)
;(DL,DH)=windwos right corner(x,y)
;return value null
mov ax,0x600
mov bx,0x700
mov cx,0
mov dx,0x184f
;VGA text mode:80,25
;from 0:0x18=24,0x4f=79
int 0x10
;;;; 3 rows get cursor ;;;;
;.get_cursor get cursor position, print at cursor
mov ah, 3
mov bh, 0
int 0x10
; dh=cursor row,dl=cursor colum
;;;; get cursor end ;;;;
;;;; print string ;;;;
;int 10h,function code 13
mov ax, message
mov bp, ax
; sreg init
; cursor in dx, cx ignore
mov cx,5
mov ax,0x1301
; al set write mode ah=01:cursor move behind string
mov bx,0x2
; bl char attribute, bl=02h:screen font
int 0x10
;;;; print string end ;;;;
jmp $
message db "1 MBR"
times 510-($-$$) db 0
db 0x55,0xaa
nasm -o mbr.bin mbr.S
ls -lb mbr.bin
512字节
dd if=/media/vdc/emu/bochs/mbr.bin of=/media/vdc/emu/bochs/hd60M.img bs=512 count=1 conv=notrunc
bin/bochs -f bochsrc.disk