运行扇区外的程序

目标:使启动扇区的BootLoader程序可以启动普通扇区内的程序

Screenshot_20220112_222729.png

BootLoader启动扇区

Screenshot_20220112_223010.png

所以程序需要准备一份“简历”,告诉BootLoader,BootLoader才能正确读取、加载并运行程序。这段程序要放到最前面,好让BootLoader读取第一个扇区后,就能获知所有的信息

Screenshot_20220112_223428.png

而对于BootLoader,结构为:

Screenshot_20220112_223503.png

Code

Program.asm

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
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
HDDPORT equ 0x1f0

section code align=16 vstart=0x7c00
mov si, [READSTART]
mov cx, [READSTART+2]
mov al, [SECTORNUM]
push ax
;Setup the destnation
mov ax, [DESTMEN]
mov dx, [DESTMEN+0x02]
mov bx, 16
div bx

mov ds, ax
xor di, di
pop ax
;read the first sector
call ReadHDD

ResetSegment:
mov bx, 0x04
mov cl, [0x10]

.reset:
mov ax, [bx]
mov dx, [bx+2]
add ax, [cs:DESTMEN]
adc dx, [cs:DESTMEN+2]

mov si, 16
div si
mov [bx], ax
add bx, 4
loop .reset

ResetEntry:
mov ax, [0x13]
mov dx, [0x15]
add ax, [cs:DESTMEN]
adc dx, [cs:DESTMEN+2]

mov si, 16
div si

mov [0x13], ax

jmp far [0x11]
ReadHDD:
push ax
push bx
push cx
push dx

mov dx, HDDPORT+2
out dx, al

mov dx, HDDPORT+3
mov ax, si
out dx, al

mov dx, HDDPORT+4
mov al, ah
out dx, al

mov dx, HDDPORT+5
mov ax, cx
out dx, al

mov dx, HDDPORT+6
mov al, ah
mov ah, 0xe0
or al, ah
out dx, al

mov dx, HDDPORT+7
mov al, 0x20
out dx, al

.waits:
in al, dx
and al, 0x88
cmp al, 0x08
jnz .waits

mov dx, HDDPORT
mov cx, 256

.readword:
in ax, dx
mov [ds:di], ax
add di, 2
;or ah, 0x00
;jnz .readword
loop .readword
.return:
pop dx
pop cx
pop bx
pop ax

ret

READSTART dd 1
SECTORNUM db 1
DESTMEN dd 0x10000

End: jmp End
times 510-($-$$) db 0
db 0x55, 0xaa

BootLoader.asm

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
64
NUL equ 0x00
SETCHAR equ 0x07
VIDEOMEM equ 0xb800
STRINGLEN equ 0xffff

section head align=16 vstart=0
Size dd ProgramEnd ; 4B 0x00
SegmentAddr:
CodeSeg dd section.code.start ;4B 0x04
DataSeg dd section.data.start ;4B 0x08
StackSeg dd section.stack.start ;4B 0x0c
SegmentNum:
SegNum db (SegmentNum-SegmentAddr)/4 ;1B 0x10
Entry dw CodeStart ;2B 0x11
dd section.code.start ;4B 0x13

section code align=16 vstart=0
CodeStart:
mov ax, [DataSeg]
mov ds, ax
xor si, si
call PrintString
jmp $

PrintString:
.setup:
push ax
push bx
push cx
push dx
mov ax, VIDEOMEM
mov es, ax
xor di, di

mov bh, SETCHAR
mov cx, STRINGLEN

.printchar:
mov bl, [ds:si]
inc si
mov [es:di], bl
inc di
mov [es:di], bh
inc di
or bl, NUL
jz .return
loop .printchar
.return:
mov bx, di
pop dx
pop cx
pop bx
pop ax
ret

section data align=16 vstart=0
Hello db 'Hello, I come from program on sector 1, loaded by bootloader!'

section stack align=16 vstart=0
; resb 保留一定空间
resb 128

section end align=16
ProgramEnd:

运行结果

Screenshot_20220112_225338.png