Subversion Repositories Kolibri OS

Rev

Rev 2785 | Go to most recent revision | Blame | Compare with Previous | Last modification | View Log | Download | RSS feed

  1. ; KolibriOS bootloader
  2. ; bootsector for loading from FAT32 flash (or hard) drive
  3. ; intended for use with mtldr_f file in root folder
  4. ; this code has been written by diamond in 2005,2006,2007 specially for KolibriOS
  5.  
  6. ; this code is loaded by BIOS to 0000:7C00
  7.         org     0x7C00
  8.         jmp     @f
  9.         nop
  10.         times 57h db 0
  11. ;       file 'bt2.dat':3,57h
  12. @@:
  13.         cmp     byte [si], 80h
  14.         jnz     @f
  15.         mov     eax, [si+8]
  16.         mov     [cs:7C1Ch], eax
  17. @@:
  18.         xor     eax, eax
  19.         mov     ds, ax
  20.         mov     ss, ax
  21.         mov     sp, 7C00h
  22.         mov     bp, sp
  23.         mov     [boot_drive], dl
  24.         cld
  25.         sti
  26.         push    800h
  27.         pop     es
  28.         movzx   ebx, word [bp+0Eh]      ; reserved_sect
  29.         mov     [fat_start], ebx
  30.         mov     al, byte [bp+10h]       ; num_fats
  31.         mul     dword [bp+24h]          ; sect_fat
  32.         add     eax, ebx
  33. ; cluster 2 begins from sector eax
  34.         movzx   ebx, byte [bp+0Dh]      ; sects_per_clust
  35.         add     bx, bx
  36.         sub     eax, ebx
  37.         mov     [data_start], eax
  38.         mov     eax, [bp+2Ch]           ; root_cluster
  39.         and     eax, 0FFFFFFFh
  40. fat32_parse_dir:
  41.         xor     bx, bx
  42.         mov     di, bx
  43.         push    eax
  44.         call    read_cluster
  45.         movzx   cx, byte [bp+0Dh]       ; sects_per_clust
  46.         shl     cx, 4                   ; *0x200/0x20
  47. scan_cluster:
  48.         cmp     byte [es:di], 0
  49.         jz      file_not_found
  50.         push    cx di
  51.         mov     cx, 11
  52.         mov     si, mtldr_f
  53.         repz    cmpsb
  54.         pop     di cx
  55.         jz      file_found
  56.         add     di, 20h
  57.         loop    scan_cluster
  58.         pop     eax
  59.         call    next_cluster
  60.         jnc     file_not_found
  61.         jc      fat32_parse_dir
  62. file_found:
  63.         pop     eax
  64.         mov     ax, [es:di+14h]
  65.         and     ax, 0FFFh
  66.         shl     eax, 10h
  67.         mov     ax, [es:di+1Ah]
  68. ; eax contains first cluster
  69. @@:
  70.         xor     bx, bx
  71.         push    eax
  72.         call    read_cluster
  73.         mov     ax, es
  74.         movzx   cx, byte [bp+0Dh]
  75.         shl     cx, 5
  76.         add     ax, cx
  77.         mov     es, ax
  78.         pop     eax
  79.         call    next_cluster
  80.         jc      @b
  81.         jmp     0:8000h
  82.  
  83. file_not_found:
  84.         mov     si, file_not_found_msg
  85. sayerr:
  86.         call    out_string
  87.         jmp     $
  88.  
  89. read_cluster:
  90. ; in: eax = cluster, bx->buffer
  91.         movzx   ecx, byte [bp+0Dh]
  92.         mul     ecx
  93.         add     eax, [data_start]
  94.  
  95. ; read procedure
  96. ; in: eax = absolute sector
  97. ;     cx = number of sectors
  98. ;     es:bx -> buffer
  99. read:
  100.         add     eax, [bp+1Ch]   ; hidden sectors
  101.         push    es
  102. read_loop:
  103.         pushad
  104. ; allocate disk address packet on the stack
  105. ; qword +8: absolute block number
  106.         push    0
  107.         push    0               ; dword +C is high dword
  108.         push    eax             ; dword +8 is low dword
  109. ; dword +4: buffer address
  110.         push    es              ; word +6 is segment
  111.         push    bx              ; word +4 is offset
  112. ; word +2: number of blocks, limited to 7Fh
  113.         sub     cx, 7Fh
  114.         sbb     ax, ax
  115.         and     ax, cx
  116.         add     ax, 7Fh
  117.         push    ax
  118.         shl     ax, 5
  119.         mov     cx, es
  120.         add     cx, ax
  121.         mov     es, cx
  122. ; word +0: size of packet = 10h
  123.         push    10h
  124. ; now pair ss:sp contain address of disk address packet
  125.         mov     ax, 4200h
  126.         mov     dl, [boot_drive]
  127.         mov     si, sp
  128.         int     13h
  129.         mov     si, disk_read_err
  130.         jc      sayerr
  131.         popaw
  132.         popad
  133.         add     eax, 7Fh
  134.         sub     cx, 7Fh
  135.         ja      read_loop
  136.         pop     es
  137.         ret
  138.  
  139. next_cluster:
  140.         push    es
  141.         push    ds
  142.         pop     es
  143.         mov     bx, 7E00h
  144. ; sector is 200h bytes long, one entry in FAT occupies 4 bytes
  145. ; => 80h entries in sector
  146.         push    eax
  147.         shr     eax, 7          ; div 80h
  148.         cmp     eax, [fat_cur_sector]
  149.         jz      @f
  150.         mov     [fat_cur_sector], eax
  151.         add     eax, [fat_start]
  152.         mov     cx, 1
  153.         call    read
  154. @@:
  155.         pop     eax
  156.         and     eax, 7Fh
  157.         mov     eax, [7E00h+eax*4]
  158.         and     eax, 0FFFFFFFh
  159.         cmp     eax, 0FFFFFF7h
  160.         mov     si, bad_cluster
  161.         jz      sayerr
  162.         pop     es
  163.         ret
  164.  
  165. out_string:
  166.         lodsb
  167.         test    al, al
  168.         jz      .xxx
  169.         mov     ah, 0Eh
  170.         mov     bx, 7
  171.         int     10h
  172.         jmp     out_string
  173. .xxx:   ret
  174.  
  175. file_not_found_msg      db      'Cannot find file '
  176. mtldr_f                 db      'MTLD_F32   '
  177.                         db      13,10,0
  178. disk_read_err           db      'Disk read error',13,10,0
  179. bad_cluster             db      'Bad cluster',13,10,0
  180. fat_cur_sector  dd      -1
  181.  
  182.         times (7DFEh - $) db 0
  183.         db      55h, 0AAh
  184.  
  185. virtual at 7A00h
  186. fat_start       dd      ?
  187. data_start      dd      ?
  188. boot_drive      db      ?
  189. end virtual
  190.