Subversion Repositories Kolibri OS

Rev

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

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