Subversion Repositories Kolibri OS

Rev

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

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