-
Notifications
You must be signed in to change notification settings - Fork 0
/
boot.asm
209 lines (188 loc) · 3.24 KB
/
boot.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
%include "bios.h"
%include "fat.h"
%define FAT 0x7E00
[BITS 16]
[ORG BOOT_ENTRY + 64]
JMP 0:CORRECTION
CORRECTION:
MOV AX, CS
MOV ES, AX
MOV SS, AX
MOV DS, AX
MOV SP, BOOT_ENTRY
MOV BYTE [DRIVE_NUM], DL
MOV SI, ENTRYSTR
CALL PRINT
XOR AX, AX
MOV AL, BYTE [NUM_FATS]
MUL WORD [SECTORS_PER_FAT]
MOV WORD [CLUSTER_START], AX
MOV AX, WORD [NUM_ENTRIES]
MOV BX, DIR_SIZE
MUL BX
DIV WORD [BYTES_PER_SECTOR]
ADD AX, WORD [NUM_HIDDEN]
ADD WORD [CLUSTER_START], AX
;Read the FAT into memory
MOV BX, 0x7E00
MOV CX, WORD [SECTORS_PER_FAT]
MOV AX, WORD [NUM_HIDDEN]
INC AX
LOADFAT:
CALL READSECTOR
ADD BX, 512
INC AX
LOOP LOADFAT
;Get the root directory LBA
MOV WORD [DIRSTART], BX
PUSH AX
XOR AX, AX
MOV AL, BYTE [NUM_FATS]
DEC AX
MUL WORD [SECTORS_PER_FAT]
POP DX
ADD AX, DX
DEC AX
;Get the root directory size in sectors
PUSH AX
MOV AX, WORD [NUM_ENTRIES]
MOV CX, 32
MUL CX
DIV WORD [BYTES_PER_SECTOR]
MOV CX, AX
POP AX
;Load the root directory off disk
LOADROOT:
CALL READSECTOR
INC AX
ADD BX, 512
LOOP LOADROOT
;Print out the files found (That are > 0 bytes)
MOV AX, WORD [DIRSTART]
MOV CX, WORD [NUM_ENTRIES]
LOOPDIR:
MOV SI, AX
MOV DI, KERNELNAME
PUSH AX
CALL NAMECMP
OR AX, AX
JE FOUNDKERNEL
POP AX
ADD AX, DIR_SIZE
LOOP LOOPDIR
DONEPRINT:
MOV SI, NOTFOUNDSTR
CALL PRINT
CLI
HLT
FOUNDKERNEL:
POP AX
MOV SI, AX
MOV AX, [SI + CLUSTER_LOW]
MOV BX, WORD [DIRSTART] ;Kernel goes after FAT
KERNELLOAD:
XOR CX, CX
MOV CL, BYTE [SECTORS_PER_CLUSTER]
PUSH AX
CALL CLUSTER2LBA
KERNELREADSEC:
CALL READSECTOR
ADD BX, 512
INC AX
LOOP KERNELREADSEC
POP AX
MOV CX, AX
SHR AX, 1 ;Multiply by 1.5
ADD AX, CX
MOV SI, AX
MOV AX, [SI + FAT]
TEST AX, 1 ;Check to see if it's odd
JNZ FINISH
SHR AX, 4 ;Shift it right if it is
FINISH:
AND AX, 0xFFF ;And always cancel the high nibble
CMP AX, 0xFFE ;End of cluster chain?
JL KERNELLOAD
MOV AX, WORD [DIRSTART] ;Our entrypoint
JMP AX
;Assumes SI=STR1, DI=STR2
NAMECMP:
XOR AX, AX
MOV CX, 11
REPE CMPSB
OR CX, CX
JE DONECMP
MOV AX, 0xFFFF
DONECMP:
RET
;Assumes AX=LBA, ES:BX=BUFFER
READSECTOR:
PUSHA
CALL LBA2CHS
MOV DL, BYTE [DRIVE_NUM]
MOV AL, 1
MOV CL, BYTE [SECTOR]
MOV CH, BYTE [TRACK]
MOV AH, READSECTOR_B
MOV DH, BYTE [HEAD]
INT DISK_SERVICE
JNC READSUCCESS
MOV SI, BADREADSTR ;Bad sector read, Hang the machine
CALL PRINT
CLI
HLT
READSUCCESS:
POPA
RET
;Assumes AX=cluster
CLUSTER2LBA:
DEC AX
DEC AX
MUL BYTE [SECTORS_PER_CLUSTER]
ADD AX, WORD [CLUSTER_START]
INC AX
RET
;Assumes AX=LBA
LBA2CHS:
PUSHA
XOR DX, DX
DIV WORD [SECTORS_PER_TRACK]
INC DL
;Save sector referenced by the LBA
MOV BYTE [SECTOR], DL
XOR DX, DX
DIV WORD [NUM_HEADS]
;Save head from LBA
MOV BYTE [HEAD], DL
;Save track from LBA
MOV BYTE [TRACK], AL
POPA
RET
;Assumes ES:SI=string
PRINT:
PUSHA
MOV AH, PUTCHAR
PRINTLOOP:
LODSB
OR AL, AL
JZ ENDPRINT
INT TEXT_SERVICE
JMP PRINTLOOP
ENDPRINT:
MOV AL, 13
INT TEXT_SERVICE
MOV AL, 10
INT TEXT_SERVICE
POPA
RET
ENTRYSTR: DB "Dosile boot started.", 0
BADREADSTR: DB "Fatal read error. Halting.", 0
NOTFOUNDSTR: DB "Dosile not found. Halting.", 0
KERNELNAME: DB "DOSILE SYS"
TRACK: DB 0
HEAD: DB 0
SECTOR: DB 0
CLUSTER_START: DW 0
DIRSTART: DW 0
TIMES 510 - 64 - ($ - $$) DB 0
DW BOOT_SIGNATURE