Subversion Repositories Kolibri OS

Rev

Rev 796 | Rev 2288 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
796 shurf 1
; FAT12 boot sector for Kolibri OS
2
;
3
; Copyright (C) Alex Nogueira Teixeira
4
; Copyright (C) Diamond
5
; Copyright (C) Dmitry Kartashov aka shurf
6
;
7
; Distributed under GPL, see file COPYING for details
8
;
9
; Version 1.0
10
 
11
lf		equ	0ah
12
cr		equ	0dh
13
 
14
pos_read_tmp	equ	0700h			;position for temporary read
15
boot_program	equ	07c00h			;position for boot code
16
seg_read_kernel	equ	01000h			;segment to kernel read
17
 
18
	jmp	start_program
19
	nop
20
 
21
; Boot Sector and BPB Structure
22
include 'floppy1440.inc'
23
;include 'floppy2880.inc'
24
;include 'floppy1680.inc'
25
;include 'floppy1743.inc'
26
 
27
start_program:
28
 
29
	xor	ax,ax
30
	mov	ss,ax
31
	mov	sp,boot_program
32
	push	ss
33
	pop	ds
34
 
35
	; print loading string
36
	mov	si,loading+boot_program
37
loop_loading:
38
	lodsb
39
	or	al,al
40
	jz	read_root_directory
41
	mov	ah,0eh
42
	mov	bx,7
43
	int	10h
44
	jmp	loop_loading
45
 
46
read_root_directory:
47
	push	ss
48
	pop	es
49
 
50
	; calculate some disk parameters
51
	; - beginning sector of RootDir
52
	mov	ax,word [BPB_FATSz16+boot_program]
53
	xor	cx,cx
54
	mov	cl,byte [BPB_NumFATs+boot_program]
55
	mul	cx
56
	add	ax,word [BPB_RsvdSecCnt+boot_program]
57
	mov	word [FirstRootDirSecNum+boot_program],ax	; 19
58
	mov	si,ax
59
 
60
	; - count of sectors in RootDir
61
	mov	bx,word [BPB_BytsPerSec+boot_program]
62
	mov	cl,5				; divide ax by 32
63
	shr	bx,cl				; bx = directory entries per sector
64
	mov	ax,word [BPB_RootEntCnt+boot_program]
65
	xor	dx,dx
66
	div	bx
67
	mov	word [RootDirSecs+boot_program],ax		; 14
68
 
69
	; - data start
70
	add	si,ax				; add beginning sector of RootDir and count sectors in RootDir
71
	mov	word [data_start+boot_program],si		; 33
72
	; reading root directory
73
	; al=count root dir sectrors !!!! TODO: al, max 255 sectors !!!!
74
	mov	ah,2				; read
75
	push	ax
76
 
77
	mov	ax,word [FirstRootDirSecNum+boot_program]
78
	call	conv_abs_to_THS			; convert abs sector (AX) to BIOS T:H:S (track:head:sector)
79
	pop	ax
80
	mov	bx,pos_read_tmp			; es:bx read buffer
81
	call	read_sector
82
 
83
	mov	si,bx				; read buffer address: es:si
84
	mov	ax,[RootDirSecs+boot_program]
85
	mul	word [BPB_BytsPerSec+boot_program]
86
	add	ax,si				; AX = end of root dir. in buffer pos_read_tmp
87
 
88
	; find kernel file in root directory
89
loop_find_dir_entry:
90
	push	si
91
	mov	cx,11
92
	mov	di,kernel_name+boot_program
93
	rep	cmpsb				; compare es:si and es:di, cx bytes long
94
	pop	si
95
	je	found_kernel_file
96
	add	si,32				; next dir. entry
97
	cmp	si,ax				; end of directory
98
	jb	loop_find_dir_entry
99
 
100
file_error_message:
101
	mov	si,error_message+boot_program
102
 
103
loop_error_message:
104
	lodsb
105
	or	al,al
106
	jz	freeze_pc
107
	mov	ah,0eh
108
	mov	bx,7
109
	int	10h
110
	jmp	loop_error_message
111
 
112
freeze_pc:
113
	jmp	$				; endless loop
114
 
115
	; === KERNEL FOUND. LOADING... ===
116
 
117
found_kernel_file:
118
	mov	bp,[si+01ah]			; first cluster of kernel file
119
	; 
120
	mov	[cluster1st+boot_program],bp	; starting cluster of kernel file
121
	; <\diamond>
122
 
123
	; reading first FAT table
124
	mov	ax,word [BPB_RsvdSecCnt+boot_program]	; begin first FAT abs sector number
125
	call	conv_abs_to_THS			; convert abs sector (AX) to BIOS T:H:S (track:head:sector)
126
	mov	bx,pos_read_tmp			; es:bx read position
127
	mov	ah,2				; ah=2 (read)
128
	mov	al, byte [BPB_FATSz16+boot_program]	; FAT size in sectors (TODO: max 255 sectors)
129
	call	read_sector
130
	jc	file_error_message		; read error
131
 
132
	mov	ax,seg_read_kernel
133
	mov	es,ax
134
	xor	bx,bx				; es:bx = 1000h:0000h
135
 
136
 
137
	; reading kernel file
138
loop_obtains_kernel_data:
139
	; read one cluster of file
140
	call	obtain_cluster
141
	jc	file_error_message		; read error
142
 
143
	; add one cluster length to segment:offset
144
	push	bx
145
	mov	bx,es
146
	mov	ax,word [BPB_BytsPerSec+boot_program]	;\
147
	movsx	cx,byte [BPB_SecPerClus+boot_program]	; | !!! TODO: !!!
148
	mul	cx					; | out this from loop !!!
149
	shr	ax,4					;/
150
	add	bx,ax
151
	mov	es,bx
152
	pop	bx
153
 
154
	mov	di,bp
155
	shr	di,1
156
	pushf
157
	add	di,bp				; di = bp * 1.5
158
	add	di,pos_read_tmp
159
	mov	ax,[di]				; read next entry from FAT-chain
160
	popf
161
	jc	move_4_right
162
	and	ax,0fffh
163
	jmp	verify_end_sector
164
move_4_right:
165
	mov	cl,4
166
	shr	ax,cl
167
verify_end_sector:
168
	cmp	ax,0ff8h			; last cluster
169
	jae	execute_kernel
170
	mov	bp,ax
171
	jmp	loop_obtains_kernel_data
172
 
173
execute_kernel:
174
	; 
175
	mov	ax,'KL'
176
	push	0
177
	pop	ds
178
	mov	si,loader_block+boot_program
179
	; 
180
	push	word	seg_read_kernel
181
	push	word	0
182
	retf					; jmp far 1000:0000
183
 
184
 
185
;------------------------------------------
186
	; loading cluster from file to es:bx
187
obtain_cluster:
188
	; bp - cluster number to read
189
	; carry = 0 -> read OK
190
	; carry = 1 -> read ERROR
191
 
192
	; print one dot
193
	push	bx
194
	mov	ax,0e2eh			; ah=0eh (teletype), al='.'
195
	xor	bh,bh
196
	int	10h
1738 clevermous 197
	pop	bx
796 shurf 198
 
1738 clevermous 199
writesec:
796 shurf 200
	; convert cluster number to sector number
201
	mov	ax,bp				; data cluster to read
202
	sub	ax,2
1738 clevermous 203
	xor	dx,dx
204
	mov	dl,byte [BPB_SecPerClus+boot_program]
205
	mul	dx
796 shurf 206
	add	ax,word [data_start+boot_program]
207
 
208
	call	conv_abs_to_THS			; convert abs sector (AX) to BIOS T:H:S (track:head:sector)
209
patchhere:
210
	mov	ah,2				; ah=2 (read)
211
	mov	al,byte [BPB_SecPerClus+boot_program]	; al=(one cluster)
212
	call	read_sector
213
	retn
214
;------------------------------------------
215
 
216
;------------------------------------------
217
	; read sector from disk
218
read_sector:
219
	push 	bp
220
	mov	bp,20				; try 20 times
221
newread:
222
	dec	bp
223
	jz	file_error_message
224
	push	ax bx cx dx
225
	int	13h
226
	pop	dx cx bx ax
227
	jc	newread
228
	pop	bp
229
	retn
230
;------------------------------------------
231
	; convert abs. sector number (AX) to BIOS T:H:S
232
	; sector number = (abs.sector%BPB_SecPerTrk)+1
233
	; pre.track number = (abs.sector/BPB_SecPerTrk)
234
	; head number = pre.track number%BPB_NumHeads
235
	; track number = pre.track number/BPB_NumHeads
236
	; Return: cl - sector number
237
	;	  ch - track number
238
	;	  dl - drive number (0 = a:)
239
	;	  dh - head number
240
conv_abs_to_THS:
241
	push	bx
242
	mov	bx,word [BPB_SecPerTrk+boot_program]
243
	xor	dx,dx
244
	div	bx
245
	inc	dx
246
	mov	cl, dl				; cl = sector number
247
	mov	bx,word [BPB_NumHeads+boot_program]
248
	xor	dx,dx
249
	div	bx
250
	; !!!!!!! ax = track number, dx = head number
251
	mov	ch,al				; ch=track number
252
	xchg	dh,dl				; dh=head number
253
	mov	dl,0				; dl=0 (drive 0 (a:))
254
	pop	bx
255
	retn
256
;------------------------------------------
257
 
258
loading		db	cr,lf,'Starting system ',00h
259
error_message	db	13,10
260
kernel_name	db	'KERNEL  MNT ?',cr,lf,00h
261
FirstRootDirSecNum	dw	?
262
RootDirSecs	dw	?
263
data_start	dw	?
264
 
265
; 
266
write1st:
267
	push	cs
268
	pop	ds
269
	mov	byte [patchhere+1+boot_program], 3	; change ah=2 to ah=3
1738 clevermous 270
	mov	bp,[cluster1st+boot_program]
796 shurf 271
	push	1000h
272
	pop	es
273
	xor	bx,bx
274
	call	writesec
275
	mov	byte [patchhere+1+boot_program], 2	; change back ah=3 to ah=2
276
	retf
277
cluster1st	dw	?
278
loader_block:
279
		db	1
280
		dw	0
281
		dw	write1st+boot_program
282
		dw	0
283
; <\diamond>
284
 
285
times	0x1fe-$ db 00h
286
 
287
	db	55h,0aah 			;boot signature