-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbootloader.asm
288 lines (231 loc) · 3.45 KB
/
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
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
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
bits 16
jmp short start
nop
OEMLabel db "BOOTLOAD"
BytesPerSector dw 512
SectorsPerCluster db 1
ReservedSectors dw 1
FATs db 2
MaxRootEntries dw 224
Sectors dw 2880
Medium db 0F0h
SectorsPerFAT dw 9
SectorsPerTrack dw 18
Heads dw 2
HiddenSectors dd 0
LargeSectors dd 0
DriveNo dw 0
BootSignature db 41
VolumeId dd 00000000h
VolumeLabel db "BOOTLOAD "
FileSystem db "FAT12 "
start:
mov ax, 07C0h
mov ds, ax
add ax, 544
cli
mov ss, ax
mov sp, 4096
sti
; read drive parameters
mov [device], dl
mov ah, 08h
stc
int 13h
jc fatal_error
movzx dx, dh
add dx, 1
mov [Heads], dx
and cx, 3Fh
mov [SectorsPerTrack], cx
; read root directory
mov ax, 19
mov cl, 14
mov bx, ds
mov es, bx
mov bx, buffer
call read_sectors
; read FAT
call find_kernel
xchg dx, ax
mov ax, 1
mov cl, 9
mov bx, ds
mov es, bx
mov bx, buffer
call read_sectors
; read kernel
xchg ax, dx
mov cl, 1
mov bx, 2000h
mov es, bx
mov bx, 0
.loop:
call read_sectors
mov si, still ; debug
call print_string ; debug
call get_next_sector
cmp ax, 0FF0h
jae .break
add bx, 512
jmp .loop
.break:
mov si, done ; debug
call print_string ; debug
mov al, [device]
jmp 2000h:0000h
find_kernel:
; OUT: ax: kernel's first logical sector
push si
push di
push bx
push es
push cx
push dx
mov bx, ds
mov es, bx
mov cx, [MaxRootEntries]
mov ax, buffer
.loop:
mov si, kernel
mov di, ax
cmp byte [di], 0
je .notfound
cmp byte [di], 0E5h
je .continue
xchg cx, dx
mov cx, 11
rep cmpsb
je .found
xchg cx, dx
.continue:
add ax, 32
loop .loop
.notfound:
mov si, kernerr
call print_string
call fatal_error
.found:
mov si, kernfound
call print_string
add ax, 26
mov si, ax
mov ax, [si]
add ax, 31
pop dx
pop cx
pop bx
mov es, bx
pop bx
pop di
pop si
ret
get_next_sector:
; IN: FAT table in the buffer
; IN: ax: current logical sector
;
; OUT: ax: next logical sector
push bx
push cx
push dx
push si
sub ax, 31
mov bx, ax
mov dx, 0
mov cx, 3
mul cx
mov cx, 2
div cx
mov si, buffer
add si, ax
mov ax, [si]
cmp dx, 0
je .even_record
.odd_record:
shr ax, 4
jmp .return
.even_record:
and ax, 0FFFh
.return:
pop si
pop dx
pop cx
pop bx
add ax, 31
ret
read_sectors:
; IN: ax: logical sector
; IN: es:bx: destination
;
; OUT: cl: sector count
pusha
push cx
call ltolhs
pop ax
mov ah, 2h
.try:
stc
int 13h
jnc .continue ; no need to retry
call reset_disk
jc fatal_error
jmp .try
.continue:
popa
ret
ltolhs:
; IN: ax: logical sector
; OUT: cx, dx: parameters to int 13h
push ax
mov dx, 0
div word [SectorsPerTrack]
mov cl, dl
add cl, 1
mov dx, 0
div word [Heads]
mov ch, al
mov dh, dl
mov dl, byte [device]
pop ax
ret
reset_disk:
; OUT: c: error flag
push ax
push dx
mov ah, 0
mov dl, [device]
stc
int 13h
pop dx
pop ax
ret
print_string:
; IN: si: output string
pusha
mov ah, 0Eh
.loop:
lodsb
cmp al, 0
je .return
int 10h
jmp short .loop
.return:
popa
ret
fatal_error:
mov si, diskerr
call print_string
jmp $
; variables
kernel db "KERNEL SYS"
diskerr db "disk error", 13, 10, 0
kernerr db "no kernel file", 13, 10, 0
kernfound db "found kernel entry", 13, 10, 0
newline db 13, 10, 0
device db 0
still db ".", 0
done db " ok", 13, 10, 0
; bootloader padding and sigature
times 510-($-$$) db 0
dw 0AA55h
buffer: