Subversion Repositories Kolibri OS

Rev

Rev 2785 | Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2783 clevermous 1
; KolibriOS bootloader
2
; bootsector for loading from FAT32 flash (or hard) drive
3
; intended for use with mtldr_f file in root folder
4
; this code has been written by diamond in 2005,2006,2007 specially for KolibriOS
5
 
6
; this code is loaded by BIOS to 0000:7C00
7
	org	0x7C00
8
	jmp	@f
9
	nop
10
;	times 57h db 0
11
	file 'bt2.dat':3,57h
12
@@:
13
	xor	eax, eax
14
	mov	ds, ax
15
	mov	ss, ax
16
	mov	sp, 7C00h
17
	mov	[boot_drive], dl
18
	cld
19
	sti
20
	push	800h
21
	pop	es
22
	movzx	ebx, word [7C0Eh]	; reserved_sect
23
	mov	[fat_start], ebx
24
	mov	al, byte [7C10h]	; num_fats
25
	mul	dword [7C24h]		; sect_fat
26
	add	eax, ebx
27
; cluster 2 begins from sector eax
28
	movzx	ebx, byte [7C0Dh]	; sects_per_clust
29
	add	bx, bx
30
	sub	eax, ebx
31
	mov	[data_start], eax
32
	mov	eax, [7C2Ch]		; root_cluster
33
	and	eax, 0FFFFFFFh
34
fat32_parse_dir:
35
	xor	bx, bx
36
	mov	di, bx
37
	push	eax
38
	call	read_cluster
39
	movzx	cx, byte [7C0Dh]	; sects_per_clust
40
	shl	cx, 4			; *0x200/0x20
41
scan_cluster:
42
	cmp	byte [es:di], 0
43
	jz	file_not_found
44
	push	cx di
45
	mov	cx, 11
46
	mov	si, mtldr_f
47
	repz	cmpsb
48
	pop	di cx
49
	jz	file_found
50
	add	di, 20h
51
	loop	scan_cluster
52
	pop	eax
53
	call	next_cluster
54
	jnc	file_not_found
55
	jc	fat32_parse_dir
56
file_found:
57
	pop	eax
58
	mov	ax, [es:di+14h]
59
	and	ax, 0FFFh
60
	shl	eax, 10h
61
	mov	ax, [es:di+1Ah]
62
; eax contains first cluster
63
@@:
64
	xor	bx, bx
65
	push	eax
66
	call	read_cluster
67
	mov	ax, es
68
	movzx	cx, byte [7C0Dh]
69
	shl	cx, 5
70
	add	ax, cx
71
	mov	es, ax
72
	pop	eax
73
	call	next_cluster
74
	jc	@b
75
	jmp	0:8000h
76
 
77
file_not_found:
78
	mov	si, file_not_found_msg
79
sayerr:
80
	call	out_string
81
	jmp	$
82
 
83
read_cluster:
84
; in: eax = cluster, bx->buffer
85
	movzx	ecx, byte [7C0Dh]
86
	mul	ecx
87
	add	eax, [data_start]
88
 
89
; read procedure
90
; in: eax = absolute sector
91
;     cx = number of sectors
92
;     es:bx -> buffer
93
read:
94
	add	eax, [7C1Ch]	; hidden sectors
95
	push	es
96
read_loop:
97
	pushad
98
; allocate disk address packet on the stack
99
; qword +8: absolute block number
100
	push	0
101
	push	0 		; dword +C is high dword
102
	push	eax		; dword +8 is low dword
103
; dword +4: buffer address
104
	push	es		; word +6 is segment
105
	push	bx		; word +4 is offset
106
; word +2: number of blocks, limited to 7Fh
107
	sub	cx, 7Fh
108
	sbb	ax, ax
109
	and	ax, cx
110
	add	ax, 7Fh
111
	push	ax
112
	shl	ax, 5
113
	mov	cx, es
114
	add	cx, ax
115
	mov	es, cx
116
; word +0: size of packet = 10h
117
	push	10h
118
; now pair ss:sp contain address of disk address packet
119
	mov	ax, 4200h
120
	mov	dl, [boot_drive]
121
	mov	si, sp
122
	int	13h
123
	mov	si, disk_read_err
124
	jc	sayerr
125
	popaw
126
	popad
127
	add	eax, 7Fh
128
	sub	cx, 7Fh
129
	ja	read_loop
130
	pop	es
131
	ret
132
 
133
next_cluster:
134
	push	es
135
	push	ds
136
	pop	es
137
	mov	bx, 7E00h
138
; sector is 200h bytes long, one entry in FAT occupies 4 bytes
139
; => 80h entries in sector
140
	push	eax
141
	shr	eax, 7		; div 80h
142
	cmp	eax, [fat_cur_sector]
143
	jz	@f
144
	mov	[fat_cur_sector], eax
145
	add	eax, [fat_start]
146
	mov	cx, 1
147
	call	read
148
@@:
149
	pop	eax
150
	and	eax, 7Fh
151
	mov	eax, [7E00h+eax*4]
152
	and	eax, 0FFFFFFFh
153
	cmp	eax, 0FFFFFF7h
154
	mov	si, bad_cluster
155
	jz	sayerr
156
	pop	es
157
	ret
158
 
159
out_string:
160
	lodsb
161
	test	al, al
162
	jz	.xxx
163
	mov	ah, 0Eh
164
	mov	bx, 7
165
	int	10h
166
	jmp	out_string
167
.xxx:	ret
168
 
169
file_not_found_msg	db	'Cannot find file '
170
mtldr_f			db	'MTLD_F32   '
171
			db	13,10,0
172
disk_read_err		db	'Disk read error',13,10,0
173
bad_cluster		db	'Bad cluster',13,10,0
174
fat_cur_sector	dd	-1
175
 
176
	times (7DFEh - $) db 0
177
	db	55h, 0AAh
178
 
179
virtual at 7A00h
180
fat_start	dd	?
181
data_start	dd	?
182
boot_drive	db	?
183
end virtual