Subversion Repositories Kolibri OS

Rev

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

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