Subversion Repositories Kolibri OS

Rev

Rev 2288 | Rev 3274 | Go to most recent revision | Details | Compare with Previous | Last modification | View Log | RSS feed

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