Subversion Repositories Kolibri OS

Rev

Rev 4851 | Rev 7215 | Go to most recent revision | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | RSS feed

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