Subversion Repositories Kolibri OS

Rev

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