Subversion Repositories Kolibri OS

Rev

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