Subversion Repositories Kolibri OS

Rev

Go to most recent revision | Details | 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,2008 specially for KolibriOS
3
 
4
; this code is loaded by ntldr to 0D00:0000
5
; and by io.sys from config.sys to xxxx:0100
6
; and by bootmgr in vista to 0000:7C00
7
	format	binary
8
	use16
9
 
10
	org	0xD000
11
; entry point for 9x and Vista booting
12
	call	@f
13
;	db	'd' xor 'i' xor 'a' xor 'm' xor 'o' xor 'n' xor 'd'
14
	db	'NTFS'
15
@@:
16
	pop	si
17
	sub	si, 3
18
	cmp	si, 7C00h
19
	jz	boot_vista
20
	mov	si, load_question + 100h - 0D000h
21
	call	out_string
22
;	mov	si, answer + 100h - 0D000h	; already is
23
xxy:	mov	ah, 0
24
	int	16h
25
	or	al, 20h
26
	mov	[si], al
27
	cmp	al, 'y'
28
	jz	xxz
29
	cmp	al, 'n'
30
	jnz	xxy
31
; continue load Windows
32
;       call    out_string
33
;       ret
34
out_string:
35
	lodsb
36
	test	al, al
37
	jz	.xxx
38
	mov	ah, 0Eh
39
	mov	bx, 7
40
	int	10h
41
	jmp	out_string
42
.xxx:	ret
43
xxz:
44
; boot KolibriOS
45
	call	out_string
46
	push	0
47
	pop	ds
48
	mov	word [4], new01handler + 100h - 0D000h
49
	mov	[6], cs
50
	pushf
51
	pop	ax
52
	or	ah, 1
53
	push	ax
54
	popf
55
;	int	19h
56
;	pushf		; there will be no iret
57
	call	far [19h*4]
58
xxt:
59
; TF has been cleared when entered new01handler
60
;	pushf
61
;	pop	ax
62
;	and	ah, not 1
63
;	push	ax
64
;	popf
65
	xor	di, di
66
	mov	ds, di
67
	cmp	word [8*4+2], 0F000h
68
	jz	@f
69
	les	bx, [8*4]
70
	mov	eax, [es:bx+1]
71
	mov	[8*4], eax
72
@@:
73
	mov	si, 100h
74
boot_vista:
75
	push	cs
76
	pop	ds
77
	push	0D00h
78
	pop	es
79
	mov	cx, 2000h/2
80
	rep	movsw
81
	jmp	0D00h:0256h
82
load_question	db	'Load KolibriOS? [y/n]: ',0
83
answer	db	?
84
	db	13,10,0
85
 
86
new01handler:
87
; [sp]=ip, [sp+2]=cs, [sp+4]=flags
88
	push	bp
89
	mov	bp, sp
90
	push	bx
91
	push	ds
92
	lds	bx, [bp+2]
93
	cmp	word [bx], 19cdh
94
	jz	xxt
95
	pop	ds
96
	pop	bx
97
	pop	bp
98
	iret
99
 
100
relative_read:
101
	add	eax, [partition_start]
102
 
103
; read from hard disk
104
; drive_size must be already initialized
105
; in: eax = absolute sector
106
;     cx = number of sectors
107
;     es:bx -> buffer
108
read:
109
	pushad
110
	cmp	eax, [drive_size]
111
	jb	.old_style
112
; new style - LBA, function 42
113
	cmp	[has_lba], 0
114
	jz	disk_error
115
; allocate disk address packet on the stack
116
; qword +8: absolute block number
117
	push	dword 0 	; dword +C is high dword
118
	push	eax		; dword +8 is low dword
119
; dword +4: buffer address
120
	push	es		; word +6 is segment
121
	push	bx		; word +4 is offset
122
; word +2: number of blocks = 1
123
; word +0: size of packet = 10h
124
	push	dword 10010h
125
; now pair ss:sp contain address of disk address packet
126
.patch1:
127
	mov	ax, 4200h
128
	mov	dl, [boot_drive]
129
	mov	si, sp
130
	push	ds
131
	push	ss
132
	pop	ds
133
	int	13h
134
	pop	ds
135
	add	sp, 10h
136
.end:
137
	popad
138
	jc	disk_error
139
	add	bx, 200h
140
	inc	eax
141
	dec	cx
142
	jnz	read
143
	ret
144
.old_style:
145
; old style - CHS, function 2
146
; convert absolute sector in eax to cylinder-head-sector coordinates
147
; calculate sector
148
	xor	edx, edx
149
	movzx	ecx, [sectors]
150
	div	ecx
151
; sectors are counted from 1
152
	inc	dx
153
	mov	cl, dl		; low 6 bits of cl = sector number
154
; calculate head number
155
	shld	edx, eax, 10h	; convert eax to dx:ax
156
	div	[heads]
157
	mov	dh, dl		; dh = head
158
	mov	ch, al		; ch = low 8 bits of cylinder
159
	shl	ah, 6
160
	or	cl, ah		; high 2 bits of cl = high 2 bits of cylinder
161
.patch2:
162
	mov	ax, 201h	; function 2, al=1 - number of sectors
163
	mov	dl, [boot_drive]
164
	int	13h
165
	jmp	.end
166
 
167
disk_error:
168
	mov	si, disk_error_msg
169
	call	out_string
170
	jmp	$
171
 
172
has_lba db	0
173
 
174
disk_error_msg	db	'Disk read error!',0
175
start_msg	db	2,' KolibriOS bootloader',13,10,0
176
part_msg        db      'looking at partition '
177
part_char       db      '0'     ; will be incremented before writing message
178
                db      ' ... ',0
179
errfs_msg	db	'unknown filesystem',13,10,0
180
fat16_msg	db	'FAT12/FAT16 - unsupported',13,10,0
181
fat32_msg	db	'FAT32'
182
newline         db      13,10,0
183
ntfs_msg	db	'NTFS',13,10,0
184
error_msg	db	'Error'
185
colon		db	': ',0
186
mft_string	db	'MFT',0
187
root_string	db	'\',0
188
noindex_string	db	'$INDEX_ROOT not found',0
189
invalid_read_request_string db 'cannot read attribute',0
190
nodata_string	db	'$DATA '
191
notfound_string db	'not found',0
192
directory_string db	'is a directory',0
193
notdir_string	db	'not a directory',0
194
fragmented_string db	'too fragmented file',0
195
exmem_string	db	'extended memory error',0
196
bad_cluster_string db	'bad cluster',0
197
data_error_msg db	'data error',0
198
 
199
; init procedure - ntldr jmps here
200
	repeat	0D256h - $
201
		db	1
202
	end	repeat
203
start:
204
; cs=es=0D00, ds=07C0, ss=0
205
; esi=edi=ebp=0, esp=7C00
206
	xor	ax, ax
207
	mov	ds, ax
208
	mov	es, ax
209
; our stack is 4Kb-512b-2b!!! (0xDFE)
210
	mov	ss, ax
211
	mov	esp, 0FFFEh
212
 
213
; we are booting from hard disk identified by [boot_drive]
214
	mov	dl, [boot_drive]
215
	cld
216
	sti
217
; calculate drive size
218
	mov	ah, 8	; 8 = get drive parameters
219
	int	13h
220
; now: CF is set on error;
221
; ch = low 8 bits of maximum cylinder number
222
; cl : low 6 bits makes maximum sector number, high 2 bits are high 2 bits of maximum cylinder number
223
; dh = maximum head number
224
	jnc	@f
225
	mov	cx, -1
226
	mov	dh, cl
227
@@:
228
	movzx	ax, dh
229
	inc	ax
230
; ax = number of heads
231
	mov	[heads], ax
232
	mov	dl, cl
233
	and	dx, 3Fh
234
; dx = number of sectors
235
; (note that sectors are counted from 1, and maximum sector number = number of sectors)
236
	mov	[sectors], dx
237
	mul	dx
238
	xchg	cl, ch
239
	shr	ch, 6
240
	inc	cx
241
; cx = number of cylinders
242
	mov	[cyls], cx
243
	mul	cx
244
	mov	word [drive_size], ax
245
	mov	word [drive_size+2], dx
246
; this drive supports LBA?
247
	mov	dl, [boot_drive]
248
	mov	ah, 41h
249
	mov	bx, 55AAh
250
	int	13h
251
	jc	.no_lba
252
	cmp	bx, 0AA55h
253
	jnz	.no_lba
254
	test	cl, 1
255
	jz	.no_lba
256
	inc	[has_lba]
257
.no_lba:
258
; say hi to user
259
	mov	si, start_msg
260
	call	out_string
261
; now read first sector to determine file system type
262
; first sector of disk is MBR sector
263
	xor	eax, eax
264
new_partition_ex:
265
	mov	cx, 1
266
	mov	bx, 0F000h
267
	call	read
268
new_partition:
269
        mov     bx, [cur_partition_ofs]
270
        mov     al, [bx+4]      ; partition type
271
        test    al, al
272
        jz      next_partition
273
        cmp     al, 5
274
        jz      @f
275
        cmp     al, 0xF
276
        jnz     not_extended
277
@@:
278
; extended partition
279
        mov     eax, [bx+8]     ; partition start
280
        add     eax, [extended_part_start]
281
        mov     [extended_part_cur], eax
282
next_partition:
283
        add     [cur_partition_ofs], 10h
284
        cmp     [cur_partition_ofs], 0xF1FE
285
        jb      new_partition
286
        mov     eax, [extended_part_cur]
287
        test    eax, eax
288
        jz      partitions_done
289
        cmp     [extended_part_start], 0
290
        jnz     @f
291
        mov     [extended_part_start], eax
292
@@:
293
        mov     [extended_parent], eax
294
        and     [extended_part_cur], 0
295
        mov     [cur_partition_ofs], 0xF1BE
296
        jmp     new_partition_ex
297
partitions_done:
298
        mov     si, total_kaput
299
        call    out_string
300
        jmp     $
301
not_extended:
302
	mov	eax, [bx+8]
303
	add     eax, [extended_parent]
304
	mov	[partition_start], eax
305
	push    ax
306
	mov     si, part_msg
307
	inc     [si+part_char-part_msg]
308
	call    out_string
309
	pop     ax
310
	mov	cx, 1
311
	mov	bx, 500h
312
	call	read
313
	movzx	ax, byte [50Dh]
314
	mov	[sect_per_clust], ax
315
; determine file system
316
	cmp	dword [536h], 'FAT1'
317
	jz	fat1x
318
	cmp	dword [552h], 'FAT3'
319
	jz	fat32
320
	cmp	dword [503h], 'NTFS'
321
	jz	ntfs
322
        mov     si, errfs_msg
323
	call	out_string
324
	jmp	next_partition
325
fat1x:
326
	mov	si, fat16_msg
327
	call	out_string
328
	jmp	next_partition
329
fat32:
330
	mov	si, fat32_msg
331
	call	out_string
332
	movzx	eax, word [50Bh]	; bytes_per_sect
333
	movzx	ebx, byte [50Dh]	; sects_per_clust
334
	mul	ebx
335
	mov	[cluster_size], eax
336
	movzx	ebx, word [50Eh]	; reserved_sect
337
	mov	[fat_start], ebx
338
	movzx	eax, byte [510h]	; num_fats
339
	mul	dword [524h]		; sect_fat
340
	add	eax, ebx
341
; cluster 2 begins from sector eax
342
	movzx	ebx, byte [50Dh]	; sects_per_clust
343
	sub	eax, ebx
344
	sub	eax, ebx
345
	mov	[data_start], eax
346
; parse image name
347
	mov	eax, [52Ch]	; root_cluster
348
	mov	[cur_obj], root_string
349
.parsedir:
350
	push	ax
351
	mov	si, [imgnameofs]
352
	push	si
353
@@:
354
	lodsb
355
	cmp	al, 0
356
	jz	@f
357
	cmp	al, '\'
358
	jnz	@b
359
	dec     si
360
	mov     [missing_slash], si
361
	inc     si
362
@@:
363
	xchg	ax, [esp+2]
364
	mov	byte [si-1], 0
365
	mov	[imgnameofs], si
366
	call	fat32_parse_dir
367
	call    restore_slash
368
	pop	cx
369
	test	cl, cl
370
	jz	.end
371
	test	byte [di+0Bh], 10h
372
	mov	si, notdir_string
373
	jz	find_error_si
374
	jmp	.parsedir
375
.end:
376
	test	byte [di+0Bh], 10h
377
	mov	si, directory_string
378
	jnz	find_error_si
379
; parse FAT chunk
380
; runlist at 2000:0000
381
	mov	di, 5
382
	push	2000h
383
	pop	es
384
	mov	byte [es:di-5], 1	; of course, non-resident
385
	mov	dword [es:di-4], 1
386
	stosd
387
.parsefat:
388
	push	es
389
	push	ds
390
	pop	es
391
	call	next_cluster
392
	pop	es
393
	jnc	.done
394
	mov	ecx, [es:di-8]
395
	add	ecx, [es:di-4]
396
	cmp	eax, ecx
397
	jz	.contc
398
	mov	dword [es:di], 1
399
	scasd
400
	stosd
401
	jmp	.parsefat
402
.contc:
403
	inc	dword [es:di-8]
404
	jmp	.parsefat
405
.done:
406
	xor	eax, eax
407
	stosd
408
	jmp	read_img_file
409
 
410
ntfs:
411
	mov	si, ntfs_msg
412
	call	out_string
413
	movzx	eax, word [50Bh]	; bpb_bytes_per_sect
414
	push	eax
415
	movzx	ebx, byte [50Dh]	; bpb_sects_per_clust
416
	mul	ebx
417
	mov	[cluster_size], eax
418
	mov	[data_start], 0
419
	mov	ecx, [540h]		; frs_size
420
	cmp	cl, 0
421
	jg	.1
422
	neg	cl
423
	xor	eax, eax
424
	inc	eax
425
	shl	eax, cl
426
	jmp	.2
427
.1:
428
	mul	ecx
429
.2:
430
	mov	[frs_size], eax
431
	pop	ebx
432
	xor	edx, edx
433
	div	ebx
434
	mov	[frs_sectors], ax
435
; read first MFT record - description of MFT itself
436
	mov	[cur_obj], mft_string
437
	movzx	eax, byte [50Dh]	; bpb_sects_per_clust
438
	mul	dword [530h]		; mft_cluster
439
	mov	cx, [frs_sectors]
440
	mov	bx, 4000h
441
	mov	di, bx
442
	push	bx
443
	call	relative_read
444
	call	restore_usa
445
; scan for unnamed $DATA attribute
446
	pop	di
447
	mov	ax, 80h		; $DATA
448
	mov	bx, 700h
449
	call	load_attr
450
	mov	si, nodata_string
451
	jc	find_error_si
452
	mov	[free], bx
453
; load kolibri.img
454
; parse image name
455
	mov	eax, 5		; root cluster
456
	mov	[cur_obj], root_string
457
.parsedir:
458
	push	ax
459
	mov	si, [imgnameofs]
460
	push	si
461
@@:
462
	lodsb
463
	cmp	al, 0
464
	jz	@f
465
	cmp	al, '\'
466
	jnz	@b
467
	dec     si
468
	mov     [missing_slash], si
469
	inc     si
470
@@:
471
	xchg	ax, [esp+2]
472
	mov	byte [si-1], 0
473
	mov	[imgnameofs], si
474
	call	ntfs_parse_dir
475
	call    restore_slash
476
	pop	cx
477
	test	cl, cl
478
	jnz	.parsedir
479
read_img_file:
480
	xor	si, si
481
	push	es
482
	pop	fs
483
; yes! Now read file to 0x100000
484
	lods byte [fs:si]
485
	cmp	al, 0	; assume nonresident attr
486
	mov	si, invalid_read_request_string
487
	jz	find_error_si
488
	mov	si, 1
489
	xor	edi, edi
490
; read buffer to 1000:0000 and move it to extended memory
491
	push	1000h
492
	pop	es
493
	xor	bx, bx
494
.img_read_block:
495
	lods dword [fs:si]		; eax=length
496
	xchg	eax, ecx
497
	jecxz	.img_read_done
498
	lods dword [fs:si]		; eax=disk cluster
499
.img_read_cluster:
500
	pushad
501
; read part of file
502
	movzx	ecx, byte [50Dh]
503
	mul	ecx
504
	add	eax, [data_start]
505
	call	relative_read
506
; move it to extended memory
507
	mov	ah, 87h
508
	mov	ecx, [cluster_size]
509
	push	ecx
510
	shr	cx, 1
511
	mov	si, movedesc
512
	push	es
513
	push	ds
514
	pop	es
515
	int	15h
516
	pop	es
517
	test    ah, ah
518
	mov	si, exmem_string
519
	jnz	find_error_si
520
	pop	ecx
521
	add	[dest_addr], ecx
522
	popad
523
	inc	eax
524
	loop	.img_read_cluster
525
	jmp	.img_read_block
526
.img_read_done:
527
; kolibri.img loaded; now load kernel.mnt
528
load_kernel:
529
	push	ds
530
	pop	es
531
	mov	[cur_obj], kernel_mnt_name
532
; read boot sector
533
	xor	eax, eax
534
	mov	bx, 500h
535
	mov	cx, 1
536
	call	read_img
537
; init vars
538
	mov	ax, [50Eh]	; reserved_sect
539
	add	ax, [51Ch]	; hidden
540
	mov	word [fat_start], ax
541
	xchg	ax, bx
542
	movzx	ax, byte [510h]		; num_fats
543
	mul	word [516h]		; fat_length
544
	add	ax, bx
545
; read root dir
546
	mov	bx, 700h
547
	mov	cx, [511h]	; dir_entries
548
	add	cx, 0Fh
549
	shr	cx, 4
550
	call	read_img
551
	add	ax, cx
552
	mov	[img_data_start], ax
553
	shl	cx, 9
554
	mov	di, bx
555
	add	bx, cx
556
	mov	byte [bx], 0
557
.scan_loop:
558
	cmp	byte [di], 0
559
	mov	si, notfound_string
560
	jz	find_error_si
561
	mov	si, kernel_mnt_name
562
	call	fat_compare_name
563
	jz	.found
564
	and	di, not 1Fh
565
	add	di, 20h
566
	jmp	.scan_loop
567
.found:
568
	and	di, not 1Fh
569
	mov	si, directory_string
570
	test	byte [di+0Bh], 10h
571
	jnz	find_error_si
572
; found, now load it to 1000h:0000h
573
	mov	ax, [di+1Ah]
574
; first cluster of kernel.mnt in ax
575
; translate it to sector on disk in kolibri.img
576
	push	ax
577
	dec	ax
578
	dec	ax
579
	movzx	cx, byte [50Dh]
580
	mul	cx
581
	add	ax, [img_data_start]
582
; now ax is sector in kolibri.img
583
	mov	[kernel_mnt_in_img], ax
584
	div	[sect_per_clust]
585
; now ax is cluster in kolibri.img and
586
; dx is offset from the beginning of cluster
587
	movzx	eax, ax
588
	push	2000h
589
	pop	ds
590
	mov	si, 1
591
.scani:
592
	sub	eax, [si]
593
	jb	.scanidone
594
; sanity check
595
	cmp	dword [si], 0
596
	push	invalid_read_request_string
597
	jz	find_error_sp
598
	pop	cx
599
; next chunk
600
	add	si, 8
601
	jmp	.scani
602
.scanidone:
603
	add	eax, [si]	; undo last subtract
604
	add	eax, [si+4]	; get cluster
605
	push	0
606
	pop	ds
607
	movzx	ecx, [sect_per_clust]
608
	push	dx
609
	mul	ecx		; get sector
610
	pop	dx
611
	movzx	edx, dx
612
	add	eax, edx
613
	add	eax, [data_start]
614
	mov	[kernel_mnt_1st], eax
615
	pop	ax
616
	push	1000h
617
	pop	es
618
.read_loop:
619
	push	ax
620
	xor	bx, bx
621
	call	img_read_cluster
622
	shl	cx, 9-4
623
	mov	ax, es
624
	add	ax, cx
625
	mov	es, ax
626
	pop	ax
627
	call	img_next_cluster
628
	jc	.read_loop
629
	mov	ax, 'KL'
630
	mov	si, loader_block
631
	jmp	1000h:0000h
632
 
633
img_next_cluster:
634
	mov	bx, 700h
635
	push	ax
636
	shr	ax, 1
637
	add	ax, [esp]
638
	mov	dx, ax
639
	shr	ax, 9
640
	add	ax, word [fat_start]
641
	mov	cx, 2
642
	push	es
643
	push	ds
644
	pop	es
645
	call	read_img
646
	pop	es
647
	and	dx, 1FFh
648
	add	bx, dx
649
	mov	ax, [bx]
650
	pop	cx
651
	test	cx, 1
652
	jz	.1
653
	shr	ax, 4
654
.1:
655
	and	ax, 0FFFh
656
	mov	si, bad_cluster_string
657
	cmp	ax, 0FF7h
658
	jz	find_error_si
659
	ret
660
img_read_cluster:
661
	dec	ax
662
	dec	ax
663
	movzx	cx, byte [50Dh]	; sects_per_clust
664
	mul	cx
665
	add	ax, [img_data_start]
666
	movzx	eax, ax
667
;	call	read_img
668
;	ret
669
read_img:
670
; in: ax = sector, es:bx->buffer, cx=length in sectors
671
	pushad
672
	movzx	ebx, bx
673
	mov	si, movedesc
674
	shl	eax, 9
675
	add	eax, 93100000h
676
	mov	dword [si+sou_addr-movedesc], eax
677
	mov	eax, 9300000h
678
	mov	ax, es
679
	shl	eax, 4
680
	add	eax, ebx
681
	mov	[si+dest_addr-movedesc], eax
682
	mov	ah, 87h
683
	shl	cx, 8	; mul 200h/2
684
	push	es
685
	push	0
686
	pop	es
687
	int	15h
688
	pop	es
689
	cmp	ah, 0
690
	mov	si, exmem_string
691
	jnz	find_error_si
692
	popad
693
	ret
694
 
695
movedesc:
696
	times 16 db 0
697
; source
698
	dw	0xFFFF		; segment length
699
sou_addr dw	0000h		; linear address
700
	db	1		; linear address
701
	db	93h		; access rights
702
	dw	0
703
; destination
704
	dw	0xFFFF		; segment length
705
dest_addr dd	93100000h	; high byte contains access rights
706
				; three low bytes contains linear address (updated when reading)
707
	dw	0
708
	times 32 db 0
709
 
710
find_error_si:
711
	push	si
712
find_error_sp:
713
	mov	si, error_msg
714
	call	out_string
715
	mov	si, [cur_obj]
716
	call	out_string
717
	mov	si, colon
718
	call	out_string
719
	pop	si
720
	call	out_string
721
	mov     si, newline
722
	call    out_string
723
	or      [fat_cur_sector], -1
724
	mov     [imgnameofs], kolibri_img_name
725
	call    restore_slash
726
	mov     sp, 0xFFFE
727
	jmp     next_partition
728
 
729
file_not_found:
730
	mov	si, [esp+2]
731
	mov	[cur_obj], si
732
	push	notfound_string
733
	jmp	find_error_sp
734
 
735
restore_slash:
736
	mov     si, [missing_slash]
737
	test    si, si
738
	jz      @f
739
	and     [missing_slash], 0
740
	mov     byte [si], '\'
741
@@:     ret
742
 
743
	include 'fat32.inc'
744
	include	'ntfs.inc'
745
 
746
write1st:
747
; callback from kernel.mnt
748
; write first sector of kernel.mnt from 1000:0000 back to disk
749
	push	cs
750
	pop	ds
751
	push	cs
752
	pop	es
753
; sanity check
754
	mov	bx, 500h
755
	mov	si, bx
756
	mov	cx, 1
757
	push	cx
758
	mov	eax, [kernel_mnt_1st]
759
	push	eax
760
	call	relative_read
761
	push	1000h
762
	pop	es
763
	xor	di, di
764
	mov	cx, 8
765
	repz	cmpsw
766
	mov	si, data_error_msg
767
	jnz	find_error_si
768
; ok, now write back to disk
769
	or	byte [read.patch1+2], 1
770
	or	byte [read.patch2+2], 1
771
	xor	bx, bx
772
	pop	eax
773
	pop	cx
774
	call	relative_read
775
	and	byte [read.patch1+1], not 1
776
	and	byte [read.patch2+2], not 2
777
; and to image in memory (probably this may be done by kernel.mnt itself?)
778
	mov	dword [sou_addr], 93010000h
779
	movzx	eax, [kernel_mnt_in_img]
780
	shl	eax, 9
781
	add	eax, 93100000h
782
	mov	dword [dest_addr], eax
783
	mov	si, movedesc
784
	push	ds
785
	pop	es
786
	mov	ah, 87h
787
	mov	cx, 100h
788
	int	15h
789
	cmp	ah, 0
790
	mov	si, exmem_string
791
	jnz	find_error_si
792
	retf
793
 
794
loader_block:
795
	db	1	; version
796
	dw	1	; flags - image is loaded
797
	dw	write1st	; offset
798
	dw	0		; segment
799
 
800
fat_cur_sector dd -1
801
imgnameofs dw kolibri_img_name
802
 
803
; -----------------------------------------------
804
; ------------------ Settings -------------------
805
; -----------------------------------------------
806
 
807
; must be in lowercase, see ntfs_parse_dir.scan, fat32_parse_dir.scan
808
kernel_mnt_name 	db	'kernel.mnt',0
809
kolibri_img_name 	db	'kolibri.img',0
810
 
811
; change next variable if you want to boot from other physical drive
812
boot_drive              db      80h
813
 
814
total_kaput     db      13,10,'Fatal: image is not found.',13,10,0
815
missing_slash   dw      0
816
        align 2
817
 
818
cur_partition_ofs       dw      0xF1BE
819
extended_part_start     dd      0
820
extended_part_cur       dd      0
821
extended_parent         dd      0
822
 
823
; uninitialized data follows
824
drive_size		dd	?	; in sectors
825
heads			dw	?
826
sectors 		dw	?
827
cyls			dw	?
828
partition_start 	dd	?
829
free			dw	?
830
cur_obj 		dw	?
831
data_start		dd	?
832
img_data_start		dw	?
833
sect_per_clust		dw	?
834
kernel_mnt_in_img	dw	?
835
kernel_mnt_1st		dd	?
836
; NTFS data
837
cluster_size		dd	?	; in bytes
838
frs_size		dd	?	; in bytes
839
frs_sectors		dw	?	; in sectors
840
mft_data_attr		dw	?
841
index_root		dw	?
842
index_alloc		dw	?
843
ofs			dw	?
844
dir			dw	?
845
; FAT32 data
846
fat_start		dd	?
847
cur_cluster		dd	?
848
; file must be 16 sectors long
849
 
850
	repeat	0F000h - $
851
		db	2
852
	end	repeat