Subversion Repositories Kolibri OS

Rev

Rev 2783 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2783 clevermous 1
; KolibriOS bootloader
2
; this code has been written by diamond in 2005,2006,2007 specially for KolibriOS
3
 
4
; this code is loaded by our bootsector to 0000:8000
5
	format	binary
6
	use16
7
 
4299 clevermous 8
out_string = 0x7DAB
9
read_cluster = 0x7D15
10
relative_read = 0x7D22
11
next_cluster = 0x7D65
2783 clevermous 12
 
13
	org	0x8000
14
start:
15
; cs=ds=0, es undefined, ss=0, sp=7C00
16
	movzx	esp, sp
17
	push	1000h
18
	pop	es
19
; say hi to user
20
	mov	si, start_msg
21
	call	out_string
22
; parse image name
23
	mov	eax, [7C2Ch]	; root_cluster
24
	and	eax, 0xFFFFFFF
25
	mov	[cur_obj], root_string
26
.parsedir:
27
	push	ax
28
	mov	si, [imgnameofs]
29
	push	si
30
@@:
31
	lodsb
32
	cmp	al, 0
33
	jz	@f
34
	cmp	al, '\'
35
	jnz	@b
36
	dec     si
37
	mov     [missing_slash], si
38
	inc     si
39
@@:
40
	xchg	ax, [esp+2]
41
	mov	byte [si-1], 0
42
	mov	[imgnameofs], si
43
	call	fat32_parse_dir
44
	call    restore_slash
45
	pop	cx
46
	test	cl, cl
47
	jz	.end
48
	test	byte [es:di+0Bh], 10h
49
	mov	si, notdir_string
50
	jz	find_error_si
51
	jmp	.parsedir
52
.end:
53
	test	byte [es:di+0Bh], 10h
54
	mov	si, directory_string
55
	jnz	find_error_si
56
; parse FAT chunk
57
; runlist at 5000:0000
58
	mov	di, 4
59
	push	5000h
60
	pop	es
61
	mov	dword [es:di-4], 1
62
	stosd
63
.parsefat:
64
	call	next_cluster
65
	jnc	.done
66
	mov	ecx, [es:di-8]
67
	add	ecx, [es:di-4]
68
	cmp	eax, ecx
69
	jz	.contc
70
	mov	dword [es:di], 1
71
	scasd
72
	stosd
73
	jmp	.parsefat
74
.contc:
75
	inc	dword [es:di-8]
76
	jmp	.parsefat
77
.done:
78
	xor	eax, eax
79
	stosd
80
read_img_file:
81
	xor	si, si
82
	push	es
83
	pop	fs
84
; yes! Now read file to 0x100000
85
	xor	edi, edi
86
; read buffer to 1000:0000 and move it to extended memory
87
	push	1000h
88
	pop	es
89
	xor	bx, bx
90
.img_read_block:
91
	lods dword [fs:si]		; eax=length
92
	xchg	eax, ecx
93
	jecxz	.img_read_done
94
	lods dword [fs:si]		; eax=disk cluster
95
.img_read_cluster:
96
	pushad
97
; read part of file
98
	movzx	esi, byte [7C0Dh]
99
	mul	esi
100
	add	eax, [7A04h]
101
	push	ax
102
	mov	ax, 0x200
103
	div	si
104
	cmp	cx, ax
105
	jb	@f
106
	mov	cx, ax
107
@@:
108
	pop	ax
109
	add	[esp+1Ch], ecx
110
	sub	[esp+18h], cx
111
	imul	cx, si
112
	push	cx
113
	call	relative_read
114
	pop	cx
115
; move it to extended memory
116
	mov	byte [sou_addr+2], 1
117
.move_loop:
118
	push	cx
119
	cmp	cx, 80h
120
	jbe	@f
121
	mov	cx, 80h
122
@@:
123
	mov	ah, 87h
124
	xchg	cl, ch
125
	mov	si, movedesc
126
	push	cx es
127
	push	ds
128
	pop	es
129
	int	15h
130
	pop	es cx
131
	test    ah, ah
132
	mov	si, exmem_string
133
	jnz	find_error_si
134
	add	[dest_addr], ecx
135
	add	[dest_addr], ecx
136
	inc	byte [sou_addr+2]
137
	mov	al, ch
138
	mov	ah, cl
139
	pop	cx
140
	sub	cx, ax
141
	jnz	.move_loop
142
	popad
143
	test	cx, cx
144
	jnz	.img_read_cluster
145
	jmp	.img_read_block
146
.img_read_done:
147
; kolibri.img loaded; now load kernel.mnt
148
load_kernel:
149
	push	ds
150
	pop	es
151
	mov	[cur_obj], kernel_mnt_name
152
; read boot sector
153
	xor	eax, eax
154
	mov	bx, 500h
155
	mov	cx, 1
156
	call	read_img
157
; init vars
158
	mov	ax, [50Eh]	; reserved_sect
159
	add	ax, [51Ch]	; hidden
160
	mov	word [fat_start], ax
161
	xchg	ax, bx
162
	movzx	ax, byte [510h]		; num_fats
163
	mul	word [516h]		; fat_length
164
	add	ax, bx
165
; read root dir
166
	mov	bx, 700h
167
	mov	cx, [511h]	; dir_entries
168
	add	cx, 0Fh
169
	shr	cx, 4
170
	call	read_img
171
	add	ax, cx
172
	mov	[img_data_start], ax
173
	shl	cx, 9
174
	mov	di, bx
175
	add	bx, cx
176
	mov	byte [bx], 0
177
.scan_loop:
178
	cmp	byte [di], 0
179
	mov	si, notfound_string
180
	jz	find_error_si
181
	mov	si, kernel_mnt_name
182
	call	fat_compare_name
183
	jz	.found
184
	and	di, not 1Fh
185
	add	di, 20h
186
	jmp	.scan_loop
187
.found:
188
	and	di, not 1Fh
189
	mov	si, directory_string
190
	test	byte [di+0Bh], 10h
191
	jnz	find_error_si
192
; found, now load it to 1000h:0000h
193
	mov	ax, [di+1Ah]
194
; first cluster of kernel.mnt in ax
195
; translate it to sector on disk in kolibri.img
196
	push	ax
197
	dec	ax
198
	dec	ax
199
	movzx	cx, byte [50Dh]
200
	mul	cx
201
	add	ax, [img_data_start]
202
; now ax is sector in kolibri.img
203
	mov	[kernel_mnt_in_img], ax
204
	movzx	cx, byte [7C0Dh]
205
	div	cx
206
; now ax is cluster in kolibri.img and
207
; dx is offset from the beginning of cluster
208
	movzx	eax, ax
209
	push	5000h
210
	pop	ds
211
	xor	si, si
212
	mov	si, 1
213
.scani:
214
	sub	eax, [si]
215
	jb	.scanidone
216
; sanity check
217
	cmp	dword [si], 0
218
	push	data_error_msg
219
	jz	find_error_sp
220
	pop	cx
221
; next chunk
222
	add	si, 8
223
	jmp	.scani
224
.scanidone:
225
	add	eax, [si]	; undo last subtract
226
	add	eax, [si+4]	; get cluster
227
	push	0
228
	pop	ds
229
	movzx	ecx, byte [7C0Dh]
230
	push	dx
231
	mul	ecx		; get sector
232
	pop	dx
233
	movzx	edx, dx
234
	add	eax, edx
235
	add	eax, [7A04h]
236
	mov	[kernel_mnt_1st], eax
237
	pop	ax
238
	push	1000h
239
	pop	es
240
.read_loop:
241
	push	ax
242
	xor	bx, bx
243
	call	img_read_cluster
244
	shl	cx, 9-4
245
	mov	ax, es
246
	add	ax, cx
247
	mov	es, ax
248
	pop	ax
249
	call	img_next_cluster
250
	jc	.read_loop
251
	mov	ax, 'KL'
252
	mov	si, loader_block
253
	jmp	1000h:0000h
254
 
255
img_next_cluster:
256
	mov	bx, 700h
257
	push	ax
258
	shr	ax, 1
259
	add	ax, [esp]
260
	mov	dx, ax
261
	shr	ax, 9
262
	add	ax, word [fat_start]
263
	mov	cx, 2
264
	push	es
265
	push	ds
266
	pop	es
267
	call	read_img
268
	pop	es
269
	and	dx, 1FFh
270
	add	bx, dx
271
	mov	ax, [bx]
272
	pop	cx
273
	test	cx, 1
274
	jz	.1
275
	shr	ax, 4
276
.1:
277
	and	ax, 0FFFh
278
	mov	si, bad_cluster_string
279
	cmp	ax, 0FF7h
280
	jz	find_error_si
281
	ret
282
img_read_cluster:
283
	dec	ax
284
	dec	ax
285
	movzx	cx, byte [50Dh]	; sects_per_clust
286
	mul	cx
287
	add	ax, [img_data_start]
288
	movzx	eax, ax
289
;	call	read_img
290
;	ret
291
read_img:
292
; in: ax = sector, es:bx->buffer, cx=length in sectors
293
	pushad
294
	movzx	ebx, bx
295
	mov	si, movedesc
296
	shl	eax, 9
297
	add	eax, 93100000h
298
	mov	dword [si+sou_addr-movedesc], eax
299
	mov	eax, 9300000h
300
	mov	ax, es
301
	shl	eax, 4
302
	add	eax, ebx
303
	mov	[si+dest_addr-movedesc], eax
304
	mov	ah, 87h
305
	shl	cx, 8	; mul 200h/2
306
	push	es
307
	push	0
308
	pop	es
309
	int	15h
310
	pop	es
311
	cmp	ah, 0
312
	mov	si, exmem_string
313
	jnz	find_error_si
314
	popad
315
	ret
316
 
317
movedesc:
318
	times 16 db 0
319
; source
320
	dw	0xFFFF		; segment length
321
sou_addr dw	0000h		; linear address
322
	db	1		; linear address
323
	db	93h		; access rights
324
	dw	0
325
; destination
326
	dw	0xFFFF		; segment length
327
dest_addr dd	93100000h	; high byte contains access rights
328
				; three low bytes contains linear address (updated when reading)
329
	dw	0
330
	times 32 db 0
331
 
332
find_error_si:
333
	push	si
334
find_error_sp:
335
	mov	si, error_msg
336
	call	out_string
337
	mov	si, [cur_obj]
338
	call	out_string
339
	mov	si, colon
340
	call	out_string
341
	pop	si
342
	call	out_string
343
	mov     si, newline
344
	call    out_string
345
	jmp	$
346
 
347
file_not_found:
348
	mov	si, [esp+2]
349
	mov	[cur_obj], si
350
	push	notfound_string
351
	jmp	find_error_sp
352
 
353
restore_slash:
354
	mov     si, [missing_slash]
355
	test    si, si
356
	jz      @f
357
	and     [missing_slash], 0
358
	mov     byte [si], '\'
359
@@:     ret
360
 
361
	include 'fat32.inc'
362
 
363
if 0
364
write1st:
365
; callback from kernel.mnt
366
; write first sector of kernel.mnt from 1000:0000 back to disk
367
	push	cs
368
	pop	ds
369
	push	cs
370
	pop	es
371
; sanity check
372
	mov	bx, 500h
373
	mov	si, bx
374
	mov	cx, 1
375
	push	cx
376
	mov	eax, [kernel_mnt_1st]
377
	push	eax
378
	call	relative_read
379
	push	1000h
380
	pop	es
381
	xor	di, di
382
	mov	cx, 8
383
	repz	cmpsw
384
	mov	si, data_error_msg
385
	jnz	find_error_si
386
; ok, now write back to disk
387
	or	byte [read.patch1+2], 1
388
	or	byte [read.patch2+2], 1
389
	xor	bx, bx
390
	pop	eax
391
	pop	cx
392
	call	relative_read
393
	and	byte [read.patch1+1], not 1
394
	and	byte [read.patch2+2], not 2
395
; and to image in memory (probably this may be done by kernel.mnt itself?)
396
	mov	dword [sou_addr], 93010000h
397
	movzx	eax, [kernel_mnt_in_img]
398
	shl	eax, 9
399
	add	eax, 93100000h
400
	mov	dword [dest_addr], eax
401
	mov	si, movedesc
402
	push	ds
403
	pop	es
404
	mov	ah, 87h
405
	mov	cx, 100h
406
	int	15h
407
	cmp	ah, 0
408
	mov	si, exmem_string
409
	jnz	find_error_si
410
	retf
411
else
412
write1st = 0
413
end if
414
 
415
loader_block:
416
	db	1	; version
417
	dw	1	; flags - image is loaded
418
	dw	write1st	; offset
419
	dw	0		; segment
420
 
421
imgnameofs dw kolibri_img_name
422
 
423
; -----------------------------------------------
424
; ------------------ Settings -------------------
425
; -----------------------------------------------
426
 
427
; must be in lowercase, see ntfs_parse_dir.scan, fat32_parse_dir.scan
428
kernel_mnt_name 	db	'kernel.mnt',0
429
kolibri_img_name 	db	'kolibri.img',0
430
 
431
missing_slash   dw      0
432
 
433
start_msg	db	2,' KolibriOS bootloader, FAT32 flash version'
434
newline		db	13,10,0
435
error_msg	db	'Error'
436
colon		db	': ',0
437
root_string	db	'\',0
438
nodata_string	db	'$DATA '
439
notfound_string db	'not found',0
440
directory_string db	'is a directory',0
441
notdir_string	db	'not a directory',0
442
exmem_string	db	'extended memory error',0
443
bad_cluster_string db	'bad cluster',0
444
data_error_msg db	'data error',0
445
 
446
        align 2
447
 
448
; uninitialized data follows
449
cur_obj 		dw	?
450
img_data_start		dw	?
451
kernel_mnt_in_img	dw	?
452
fat_start		dw	?
453
kernel_mnt_1st		dd	?