Subversion Repositories Kolibri OS

Rev

Rev 7215 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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