boot工作:读setup,读system….

x86 PC 开机过程

  1. x86 PC 刚开机时 CPU 处于实模式
  2. 开机时,CS=0xFFFF;IP=0x0000
  3. 寻址 0xFFFF0(ROM BIOS 映射区)
  4. 检查 RAM,键盘,显示器,软硬磁盘
  5. 将磁盘 0 磁道 0扇区(引导扇区)读入 0x7c00 处
  6. 设置 cs=0x07c0,ip=0x0000

引导扇区代码: bootsect.s​

​ rep:重复执行该语句直至寄存器 CX 为 0

​ movw:将 DS:SI 的数据复制一个字到 ES:DI

​ jmpi a, b: 间接寻址。CS 设为 b ,IP 设为 a

​ BOOTSEG = 0x07C0

​ INITSEG = 0x9000

​ SETUPSEG = 0x9020

2vMXcrkiAzCW8yD

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
.globl begtext,begdata,begbss,endtext,enddata,endbss
.text ;文本段
begtext:
.data ;数据段
begdata:
.bss ;未初始化数据段
begbss: ;此处的.text、.data、.bss表明这3个段重叠,不分段
entry start ;关键字 entry 告诉链接器“程序入口”
start:
mov ax, #BOOTSEG ;此条语句就是 0x7C00 处存放的语句
mov ds, ax
mov ax, #INITSEG
mov es, ax
mov cx, #256
sub si, si
sub di, di
rep movw ;;将 0x07C0:0x0000 处的256个字复制到 0x9000:0x0000 处
jmpi go, INITSEG ;跳转到 0x9000:go 的位置
go:
mov ax, cs ;cs = 0x9000
mov ds, ax
mov es, ax
mov ss, ax
mov sp, #0xff00
load_setup: ;载入setup模块
mov dx, #0x0000
mov cx, #0x0002 ;boot 占了第一个扇区,故从第二个扇区继续读取
mov bx, #0x0200 ;boot 读入到 0x90000 处,占 256B,之后 setup 读入到 0x92000 处
mov ax, #0x0200+SETUPLEN
int 0x13 ;0x13 是 BIOS 读磁盘扇区的中断。ah=0x02-读磁盘,al=扇区数量(SETUPLEN=4),ch=柱面号,cl=开始扇区,dh=磁头号,dl=驱动器号,es:bx=内存地址
jnc ok_load_setup
mov dx, #0x0000
mov ax, #0xoooo ;复位
int 0x13
j load_setup ;重读
ok_load_setup:
mov dl, #0x00
mov ax, #0x0800 ;ah=8 获得磁盘参数
int 0x13
mov ch,#0x00
mov sectors,cx
mov ah, #0x03
xor bhbh
int 0x10 ;读光标
mov cx, #24 ;待显示字符串长度
mov bx, #0x0007 ;设置显示属性
mov bp, #msg1
mov ax, #1301
int 0x10 ;0x10 号中断,显示字符
mov ax, #SYSSEG ;SYSSEG=0x1000
mov es, ax
call read_it ;读入 system 模块
jmpi 0, SETUPSEG ;控制权交给 setup,转入 0x9020:0x0000 执行 setup.s
read_it: ;system 模块很大,可能跨越磁道,故额外定义一个函数
mov ax,es
cmp ax,#ENDSEG
jb ok1_read
ret
ok1_read:
mov ax, sectors
sub ax,sread ;sread 是当前磁道已读扇区数, ax 未读扇区数
call read_track ;读磁道
......
1
2
3
4
5
;在文件末尾 bootsect.s 中的数据
sectors: .word 0; ;磁道扇区数
msg1: .byte 13,10
.ascii "Loading system..."
.byte 13,10,13,10

setup 模块,即 setup.s,完成 OS 启动前的设置

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
start:
mov ax, #INITSEG
mov ds, ax
mov ah, #0x03
xor bh, bh
int 0x10 ;取光标位置 dx (包括其他硬件参数)
mov [0],dx ;到 0x90000 处
mov ah, #0x88
int 0x15 ;获得扩展内存大小
mov [2],ax ;到 0x90002 处
c1i ;关中断
mov ax, #0x0000
cld
do move:
mov es, ax
add ax, #0x1000
cmp ax, #0x9000
jz end_move
mov ds, ax
sub di, di
sub si, si
mov cx, #0x8000