Subversion Repositories Kolibri OS

Rev

Rev 1505 | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ; FAT12 boot sector for Kolibri OS
  2. ;
  3. ; Copyright (C) Alex Nogueira Teixeira
  4. ; Copyright (C) Diamond
  5. ; Copyright (C) Dmitry Kartashov aka shurf
  6. ;
  7. ; Distributed under GPL, see file COPYING for details
  8. ;
  9. ; Version 1.0
  10.  
  11. lf              equ     0ah
  12. cr              equ     0dh
  13.  
  14. pos_read_tmp    equ     0700h                   ;position for temporary read
  15. boot_program    equ     07c00h                  ;position for boot code
  16. seg_read_kernel equ     01000h                  ;segment to kernel read
  17.  
  18.         jmp     start_program
  19.         nop
  20.  
  21. ; Boot Sector and BPB Structure
  22. include 'floppy1440.inc'
  23. ;include 'floppy2880.inc'
  24.  
  25. start_program:
  26.  
  27.         xor     ax,ax
  28.         mov     ss,ax
  29.         mov     sp,boot_program
  30.         push    ss
  31.         pop     ds
  32.  
  33.         ; print loading string
  34.         mov     si,loading+boot_program
  35. loop_loading:
  36.         lodsb
  37.         or      al,al
  38.         jz      read_root_directory
  39.         mov     ah,0eh
  40.         mov     bx,7
  41.         int     10h
  42.         jmp     loop_loading
  43.  
  44. read_root_directory:
  45.         push    ss
  46.         pop     es
  47.  
  48.         ; reading root directory
  49.         ; al=count root dir sectors !!!! TODO: al, max 255 sectors !!!!
  50.         mov     ah,2                            ; read
  51.         push    ax
  52.  
  53.         mov     ax,word [FirstRootDirSecNum+boot_program]
  54.         call    conv_abs_to_THS                 ; convert abs sector (AX) to BIOS T:H:S (track:head:sector)
  55.         pop     ax
  56.         mov     bx,pos_read_tmp                 ; es:bx read buffer
  57.         call    read_sector
  58.  
  59.         mov     si,bx                           ; read buffer address: es:si
  60.         mov     ax,[RootDirSecs+boot_program]
  61.         mul     word [BPB_BytsPerSec+boot_program]
  62.         add     ax,si                           ; AX = end of root dir. in buffer pos_read_tmp
  63.  
  64.         ; find kernel file in root directory
  65. loop_find_dir_entry:
  66.         push    si
  67.         mov     cx,11
  68.         mov     di,kernel_name+boot_program
  69.         rep     cmpsb                           ; compare es:si and es:di, cx bytes long
  70.         pop     si
  71.         je      found_kernel_file
  72.         add     si,32                           ; next dir. entry
  73.         cmp     si,ax                           ; end of directory
  74.         jb      loop_find_dir_entry
  75.         jmp     $
  76.  
  77.         ; === KERNEL FOUND. LOADING... ===
  78.  
  79. found_kernel_file:
  80.         mov     bp,[si+01ah]                    ; first cluster of kernel file
  81.         ; <diamond>
  82.         mov     [cluster1st+boot_program],bp    ; starting cluster of kernel file
  83.         ; <\diamond>
  84.  
  85.         ; reading first FAT table
  86.         mov     ax,word [BPB_RsvdSecCnt+boot_program]   ; begin first FAT abs sector number
  87.         call    conv_abs_to_THS                 ; convert abs sector (AX) to BIOS T:H:S (track:head:sector)
  88.         mov     bx,pos_read_tmp                 ; es:bx read position
  89.         mov     ah,2                            ; ah=2 (read)
  90.         mov     al, byte [BPB_FATSz16+boot_program]     ; FAT size in sectors (TODO: max 255 sectors)
  91.         call    read_sector
  92.  
  93.         mov     ax,seg_read_kernel
  94.         mov     es,ax
  95.         xor     bx,bx                           ; es:bx = 1000h:0000h
  96.  
  97.         ; reading kernel file
  98. loop_obtains_kernel_data:
  99.         call    obtain_cluster                  ; read one cluster of file
  100.  
  101.         mov     ax,es
  102.         add     ax,seg_inc_per_cluster          ; << =32(1.44M) or 64(2.88) >>
  103.         mov     es,ax                   ; add one cluster length to segment:offset
  104.  
  105.         mov     di,bp
  106.         shr     di,1
  107.         pushf
  108.         add     di,bp                           ; di = bp * 1.5
  109.         add     di,pos_read_tmp
  110.         mov     ax,[di]                         ; read next entry from FAT-chain
  111.         popf
  112.         jc      move_4_right
  113.         and     ax,0fffh
  114.         jmp     verify_end_sector
  115. move_4_right:
  116.         shr     ax,4
  117. verify_end_sector:
  118.         cmp     ax,0ff8h                        ; last cluster
  119.         jae     execute_kernel
  120.         mov     bp,ax
  121.         jmp     loop_obtains_kernel_data
  122.  
  123. execute_kernel:
  124.         ; <diamond>
  125.         mov     ax,'KL'
  126.         push    0
  127.         pop     ds
  128.         mov     si,loader_block+boot_program
  129.         ; </diamond>
  130.         push    word    seg_read_kernel
  131.         push    word    0
  132.         retf                                    ; jmp far 1000:0000
  133.  
  134.  
  135. ;------------------------------------------
  136.         ; loading cluster from file to es:bx
  137. obtain_cluster:
  138.         ; bp - cluster number to read
  139.         ; carry = 0 -> read OK
  140.         ; carry = 1 -> read ERROR
  141.  
  142.         ; print one dot
  143.         push    bx
  144.         mov     ax,0e2eh                        ; ah=0eh (teletype), al='.'
  145.         xor     bh,bh
  146.         int     10h
  147. ;       jc      $                               ; error
  148.         pop     bx
  149.  
  150. writesec:
  151.         ; convert cluster number to sector number
  152.         mov     ax,bp                           ; data cluster to read
  153.         sub     ax,2
  154. ;>>     add     ax,ax                           ; << only for 2.88M disks! >>
  155.         add     ax,word [data_start+boot_program]
  156.         call    conv_abs_to_THS                 ; convert abs sector (AX) to BIOS T:H:S (track:head:sector)
  157.  
  158. patchhere:
  159.         mov     ax,0x201                        ; ah=2 (read)
  160. ;>>                                             ; al=1(1.44) or 2(2.88)
  161.         ; read sector from disk
  162.  
  163. read_sector:
  164.         push    ax bx cx dx
  165.         int     13h
  166.         jc      $                               ; error: stop here
  167.         pop     dx cx bx ax
  168.         retn
  169.  
  170. ;------------------------------------------
  171.         ; converts abs. sector number (AX) to BIOS T:H:S
  172.         ; Returns: {pre.track number = (AX / BPB_SecPerTrk)}
  173.         ;       ch - track number  = pre.track number/2
  174.         ;       cl - sector number = (abs.sector%BPB_SecPerTrk)+1
  175.         ;       dh - head number   = pre.track number%BPB_NumHeads
  176.         ;       dl - drive number (0 = a:)
  177. conv_abs_to_THS:
  178.         mov     cx,word [BPB_SecPerTrk+boot_program]    ; << 18 or 36 >>
  179.         xor     dx,dx
  180.         div     cx
  181.         inc     dx
  182.         mov     cl, dl                          ; cl = sector number
  183.         xor     dx, dx
  184.         shr     ax, 1
  185.         rol     dx, 1                           ; dh = head number
  186.         mov     ch, al                          ; ch = track number
  187.         retn
  188. ;------------------------------------------
  189.  
  190. loading         db      cr,lf,'Starting system ',00h
  191. ;error_message  db      13,10
  192. kernel_name     db      'KERNEL  MNT',00h
  193. FirstRootDirSecNum      dw      19      ; 1st sector of the root dir
  194. RootDirSecs     dw      14              ; << = 14(1.44M) or 15(2.88M) >>
  195. data_start      dw      33              ; << = 33(1.44M) or 34(2.88M) >>
  196.  
  197. ; <diamond>
  198. write1st:
  199.         push    cs
  200.         pop     ds
  201.         mov     byte [patchhere+1+boot_program], 3      ; change ah=2 to ah=3
  202.         mov     bp,[cluster1st+boot_program]
  203.         push    1000h
  204.         pop     es
  205.         xor     bx,bx
  206.         call    writesec
  207.         mov     byte [patchhere+1+boot_program], 2      ; change back ah=3 to ah=2
  208.         retf
  209.  
  210. cluster1st      dw      ?       ; 1st cluster of kernel.mnt
  211. loader_block:
  212.                 db      1
  213.                 dw      0
  214.                 dw      write1st+boot_program
  215.                 dw      0
  216. ; <\diamond>
  217.  
  218. times   0x1fe-$ db 00h
  219.  
  220.         db      55h,0aah                        ;boot signature
  221.