Subversion Repositories Kolibri OS

Rev

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

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