-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathbootloader.asm
321 lines (210 loc) · 3.83 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
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
BITS 16
jmp short bootloader_start
nop
OEMLabel db "BESTSOFT"
BytesPerSector dw 512
SectorsPerCluster db 1
ReservedForBoot dw 1
NumberOfFats db 2
RootDirEntries dw 224
LogicalSectors dw 2880
MediumByte db 0F0h
SectorsPerFat dw 9
SectorsPerTrack dw 18
Sides dw 2
HiddenSectors dd 0
LargeSectors dd 0
DriveNo dw 0
Signature db 41
VolumeID dd 00000000h
VolumeLabel db " "
FileSystem db "FAT12 "
bootloader_start:
mov ax, 07C0h ; Set up 4K of stack space above buffer
add ax, 544 ; 8k buffer = 512 paragraphs + 32 paragraphs (loader)
cli ; Disable interrupts while changing stack
mov ss, ax
mov sp, 4096
sti ; Restore interrupts
mov ax, 07C0h ; Set data segment to where we are loaded
mov ds, ax
; NOTE: A few early BIOSes are reported to improperly set DL
cmp dl, 0
je no_change
mov [bootdev], dl ; Save boot device number
mov ah, 8 ; Get drive parameters
int 13h
jc fatal_disk_error
and cx, 3Fh ; Maximum sector number
mov [SectorsPerTrack], cx ; Sector numbers start at 1
movzx dx, dh ; Maximum head number
add dx, 1 ; Head numbers start at 0 - add 1 for total
mov [Sides], dx
no_change:
mov eax, 0 ; Needed for some older BIOSes
floppy_ok:
mov ax, 19
call l2hts
mov si, buffer
mov bx, ds
mov es, bx
mov bx, si
mov ah, 2
mov al, 14
pusha
read_root_dir:
popa
pusha
stc
int 13h
jnc search_dir
call reset_floppy
jnc read_root_dir
jmp reboot
search_dir:
popa
mov ax, ds
mov es, ax
mov di, buffer
mov cx, word [RootDirEntries]
mov ax, 0
next_root_entry:
xchg cx, dx
mov si, kern_filename
mov cx, 11
rep cmpsb
je found_file_to_load
add ax, 32
mov di, buffer
add di, ax
xchg dx, cx
loop next_root_entry
mov si, file_not_found
call print_string
jmp reboot
found_file_to_load:
mov ax, word [es:di+0Fh]
mov word [cluster], ax
mov ax, 1
call l2hts
mov di, buffer
mov bx, di
mov ah, 2
mov al, 9
pusha
read_fat:
popa
pusha
stc
int 13h
jnc read_fat_ok
call reset_floppy
jnc read_fat
fatal_disk_error:
mov si, disk_error
call print_string
jmp reboot
read_fat_ok:
popa
mov ax, 2000h
mov es, ax
mov bx, 0
mov ah, 2
mov al, 1
push ax
load_file_sector:
mov ax, word [cluster]
add ax, 31
call l2hts
mov ax, 2000h
mov es, ax
mov bx, word [pointer]
pop ax
push ax
stc
int 13h
jnc calculate_next_cluster
call reset_floppy
jmp load_file_sector
calculate_next_cluster:
mov ax, [cluster]
mov dx, 0
mov bx, 3
mul bx
mov bx, 2
div bx
mov si, buffer
add si, ax
mov ax, word [ds:si]
or dx, dx
jz even
odd:
shr ax, 4
jmp short next_cluster_cont
even:
and ax, 0FFFh
next_cluster_cont:
mov word [cluster], ax
cmp ax, 0FF8h
jae end
add word [pointer], 512
jmp load_file_sector
end:
pop ax
mov dl, byte [bootdev]
jmp 2000h:0000h
reboot:
mov ax, 0
int 16h
mov ax, 0
int 19h
print_string:
pusha
mov ah, 0Eh
.repeat:
lodsb
cmp al, 0
je .done
int 10h
jmp short .repeat
.done:
popa
ret
reset_floppy:
push ax
push dx
mov ax, 0
mov dl, byte [bootdev]
stc
int 13h
pop dx
pop ax
ret
l2hts:
push bx
push ax
mov bx, ax
mov dx, 0
div word [SectorsPerTrack]
add dl, 01h
mov cl, dl
mov ax, bx
mov dx, 0
div word [SectorsPerTrack]
mov dx, 0
div word [Sides]
mov dh, dl
mov ch, al
pop ax
pop bx
mov dl, byte [bootdev]
ret
kern_filename db "KERNEL BIN"
disk_error db "Floppy error! Press any key...", 0
file_not_found db "KERNEL.BIN not found!", 0
bootdev db 0
cluster dw 0
pointer dw 0
times 510-($-$$) db 0
dw 0AA55h
buffer: