Subversion Repositories Kolibri OS

Rev

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

  1. ; KolibriOS bootloader
  2. ; this code has been written by diamond in 2005,2006,2007 specially for KolibriOS
  3.  
  4. ; this code is loaded by our bootsector to 0000:8000
  5.         format  binary
  6.         use16
  7.  
  8. out_string = 0x7DAB
  9. read_cluster = 0x7D15
  10. relative_read = 0x7D22
  11. next_cluster = 0x7D65
  12.  
  13.         org     0x8000
  14. start:
  15. ; cs=ds=0, es undefined, ss=0, sp=7C00
  16.         movzx   esp, sp
  17.         push    1000h
  18.         pop     es
  19. ; say hi to user
  20.         mov     si, start_msg
  21.         call    out_string
  22. ; parse image name
  23.         mov     eax, [7C2Ch]    ; root_cluster
  24.         and     eax, 0xFFFFFFF
  25.         mov     [cur_obj], root_string
  26. .parsedir:
  27.         push    ax
  28.         mov     si, [imgnameofs]
  29.         push    si
  30. @@:
  31.         lodsb
  32.         cmp     al, 0
  33.         jz      @f
  34.         cmp     al, '\'
  35.         jnz     @b
  36.         dec     si
  37.         mov     [missing_slash], si
  38.         inc     si
  39. @@:
  40.         xchg    ax, [esp+2]
  41.         mov     byte [si-1], 0
  42.         mov     [imgnameofs], si
  43.         call    fat32_parse_dir
  44.         call    restore_slash
  45.         pop     cx
  46.         test    cl, cl
  47.         jz      .end
  48.         test    byte [es:di+0Bh], 10h
  49.         mov     si, notdir_string
  50.         jz      find_error_si
  51.         jmp     .parsedir
  52. .end:
  53.         test    byte [es:di+0Bh], 10h
  54.         mov     si, directory_string
  55.         jnz     find_error_si
  56. ; parse FAT chunk
  57. ; runlist at 5000:0000
  58.         mov     di, 4
  59.         push    5000h
  60.         pop     es
  61.         mov     dword [es:di-4], 1
  62.         stosd
  63. .parsefat:
  64.         call    next_cluster
  65.         jnc     .done
  66.         mov     ecx, [es:di-8]
  67.         add     ecx, [es:di-4]
  68.         cmp     eax, ecx
  69.         jz      .contc
  70.         mov     dword [es:di], 1
  71.         scasd
  72.         stosd
  73.         jmp     .parsefat
  74. .contc:
  75.         inc     dword [es:di-8]
  76.         jmp     .parsefat
  77. .done:
  78.         xor     eax, eax
  79.         stosd
  80. read_img_file:
  81.         xor     si, si
  82.         push    es
  83.         pop     fs
  84. ; yes! Now read file to 0x100000
  85.         xor     edi, edi
  86. ; read buffer to 1000:0000 and move it to extended memory
  87.         push    1000h
  88.         pop     es
  89.         xor     bx, bx
  90. .img_read_block:
  91.         lods dword [fs:si]              ; eax=length
  92.         xchg    eax, ecx
  93.         jecxz   .img_read_done
  94.         lods dword [fs:si]              ; eax=disk cluster
  95. .img_read_cluster:
  96.         pushad
  97. ; read part of file
  98.         movzx   esi, byte [7C0Dh]
  99.         mul     esi
  100.         add     eax, [7A04h]
  101.         push    ax
  102.         mov     ax, 0x200
  103.         div     si
  104.         cmp     cx, ax
  105.         jb      @f
  106.         mov     cx, ax
  107. @@:
  108.         pop     ax
  109.         add     [esp+1Ch], ecx
  110.         sub     [esp+18h], cx
  111.         imul    cx, si
  112.         push    cx
  113.         call    relative_read
  114.         pop     cx
  115. ; move it to extended memory
  116.         mov     byte [sou_addr+2], 1
  117. .move_loop:
  118.         push    cx
  119.         cmp     cx, 80h
  120.         jbe     @f
  121.         mov     cx, 80h
  122. @@:
  123.         mov     ah, 87h
  124.         xchg    cl, ch
  125.         mov     si, movedesc
  126.         push    cx es
  127.         push    ds
  128.         pop     es
  129.         int     15h
  130.         pop     es cx
  131.         test    ah, ah
  132.         mov     si, exmem_string
  133.         jnz     find_error_si
  134.         add     [dest_addr], ecx
  135.         add     [dest_addr], ecx
  136.         inc     byte [sou_addr+2]
  137.         mov     al, ch
  138.         mov     ah, cl
  139.         pop     cx
  140.         sub     cx, ax
  141.         jnz     .move_loop
  142.         popad
  143.         test    cx, cx
  144.         jnz     .img_read_cluster
  145.         jmp     .img_read_block
  146. .img_read_done:
  147. ; kolibri.img loaded; now load kernel.mnt
  148. load_kernel:
  149.         push    ds
  150.         pop     es
  151.         mov     [cur_obj], kernel_mnt_name
  152. ; read boot sector
  153.         xor     eax, eax
  154.         mov     bx, 500h
  155.         mov     cx, 1
  156.         call    read_img
  157. ; init vars
  158.         mov     ax, [50Eh]      ; reserved_sect
  159.         add     ax, [51Ch]      ; hidden
  160.         mov     word [fat_start], ax
  161.         xchg    ax, bx
  162.         movzx   ax, byte [510h]         ; num_fats
  163.         mul     word [516h]             ; fat_length
  164.         add     ax, bx
  165. ; read root dir
  166.         mov     bx, 700h
  167.         mov     cx, [511h]      ; dir_entries
  168.         add     cx, 0Fh
  169.         shr     cx, 4
  170.         call    read_img
  171.         add     ax, cx
  172.         mov     [img_data_start], ax
  173.         shl     cx, 9
  174.         mov     di, bx
  175.         add     bx, cx
  176.         mov     byte [bx], 0
  177. .scan_loop:
  178.         cmp     byte [di], 0
  179.         mov     si, notfound_string
  180.         jz      find_error_si
  181.         mov     si, kernel_mnt_name
  182.         call    fat_compare_name
  183.         jz      .found
  184.         and     di, not 1Fh
  185.         add     di, 20h
  186.         jmp     .scan_loop
  187. .found:
  188.         and     di, not 1Fh
  189.         mov     si, directory_string
  190.         test    byte [di+0Bh], 10h
  191.         jnz     find_error_si
  192. ; found, now load it to 1000h:0000h
  193.         mov     ax, [di+1Ah]
  194. ; first cluster of kernel.mnt in ax
  195. ; translate it to sector on disk in kolibri.img
  196.         push    ax
  197.         dec     ax
  198.         dec     ax
  199.         movzx   cx, byte [50Dh]
  200.         mul     cx
  201.         add     ax, [img_data_start]
  202. ; now ax is sector in kolibri.img
  203.         mov     [kernel_mnt_in_img], ax
  204.         movzx   cx, byte [7C0Dh]
  205.         div     cx
  206. ; now ax is cluster in kolibri.img and
  207. ; dx is offset from the beginning of cluster
  208.         movzx   eax, ax
  209.         push    5000h
  210.         pop     ds
  211.         xor     si, si
  212.         mov     si, 1
  213. .scani:
  214.         sub     eax, [si]
  215.         jb      .scanidone
  216. ; sanity check
  217.         cmp     dword [si], 0
  218.         push    data_error_msg
  219.         jz      find_error_sp
  220.         pop     cx
  221. ; next chunk
  222.         add     si, 8
  223.         jmp     .scani
  224. .scanidone:
  225.         add     eax, [si]       ; undo last subtract
  226.         add     eax, [si+4]     ; get cluster
  227.         push    0
  228.         pop     ds
  229.         movzx   ecx, byte [7C0Dh]
  230.         push    dx
  231.         mul     ecx             ; get sector
  232.         pop     dx
  233.         movzx   edx, dx
  234.         add     eax, edx
  235.         add     eax, [7A04h]
  236.         mov     [kernel_mnt_1st], eax
  237.         pop     ax
  238.         push    1000h
  239.         pop     es
  240. .read_loop:
  241.         push    ax
  242.         xor     bx, bx
  243.         call    img_read_cluster
  244.         shl     cx, 9-4
  245.         mov     ax, es
  246.         add     ax, cx
  247.         mov     es, ax
  248.         pop     ax
  249.         call    img_next_cluster
  250.         jc      .read_loop
  251.         mov     ax, 'KL'
  252.         mov     si, loader_block
  253.         jmp     1000h:0000h
  254.  
  255. img_next_cluster:
  256.         mov     bx, 700h
  257.         push    ax
  258.         shr     ax, 1
  259.         add     ax, [esp]
  260.         mov     dx, ax
  261.         shr     ax, 9
  262.         add     ax, word [fat_start]
  263.         mov     cx, 2
  264.         push    es
  265.         push    ds
  266.         pop     es
  267.         call    read_img
  268.         pop     es
  269.         and     dx, 1FFh
  270.         add     bx, dx
  271.         mov     ax, [bx]
  272.         pop     cx
  273.         test    cx, 1
  274.         jz      .1
  275.         shr     ax, 4
  276. .1:
  277.         and     ax, 0FFFh
  278.         mov     si, bad_cluster_string
  279.         cmp     ax, 0FF7h
  280.         jz      find_error_si
  281.         ret
  282. img_read_cluster:
  283.         dec     ax
  284.         dec     ax
  285.         movzx   cx, byte [50Dh] ; sects_per_clust
  286.         mul     cx
  287.         add     ax, [img_data_start]
  288.         movzx   eax, ax
  289. ;       call    read_img
  290. ;       ret
  291. read_img:
  292. ; in: ax = sector, es:bx->buffer, cx=length in sectors
  293.         pushad
  294.         movzx   ebx, bx
  295.         mov     si, movedesc
  296.         shl     eax, 9
  297.         add     eax, 93100000h
  298.         mov     dword [si+sou_addr-movedesc], eax
  299.         mov     eax, 9300000h
  300.         mov     ax, es
  301.         shl     eax, 4
  302.         add     eax, ebx
  303.         mov     [si+dest_addr-movedesc], eax
  304.         mov     ah, 87h
  305.         shl     cx, 8   ; mul 200h/2
  306.         push    es
  307.         push    0
  308.         pop     es
  309.         int     15h
  310.         pop     es
  311.         cmp     ah, 0
  312.         mov     si, exmem_string
  313.         jnz     find_error_si
  314.         popad
  315.         ret
  316.  
  317. movedesc:
  318.         times 16 db 0
  319. ; source
  320.         dw      0xFFFF          ; segment length
  321. sou_addr dw     0000h           ; linear address
  322.         db      1               ; linear address
  323.         db      93h             ; access rights
  324.         dw      0
  325. ; destination
  326.         dw      0xFFFF          ; segment length
  327. dest_addr dd    93100000h       ; high byte contains access rights
  328.                                 ; three low bytes contains linear address (updated when reading)
  329.         dw      0
  330.         times 32 db 0
  331.  
  332. find_error_si:
  333.         push    si
  334. find_error_sp:
  335.         mov     si, error_msg
  336.         call    out_string
  337.         mov     si, [cur_obj]
  338.         call    out_string
  339.         mov     si, colon
  340.         call    out_string
  341.         pop     si
  342.         call    out_string
  343.         mov     si, newline
  344.         call    out_string
  345.         jmp     $
  346.  
  347. file_not_found:
  348.         mov     si, [esp+2]
  349.         mov     [cur_obj], si
  350.         push    notfound_string
  351.         jmp     find_error_sp
  352.  
  353. restore_slash:
  354.         mov     si, [missing_slash]
  355.         test    si, si
  356.         jz      @f
  357.         and     [missing_slash], 0
  358.         mov     byte [si], '\'
  359. @@:     ret
  360.  
  361.         include 'fat32.inc'
  362.  
  363. if 0
  364. write1st:
  365. ; callback from kernel.mnt
  366. ; write first sector of kernel.mnt from 1000:0000 back to disk
  367.         push    cs
  368.         pop     ds
  369.         push    cs
  370.         pop     es
  371. ; sanity check
  372.         mov     bx, 500h
  373.         mov     si, bx
  374.         mov     cx, 1
  375.         push    cx
  376.         mov     eax, [kernel_mnt_1st]
  377.         push    eax
  378.         call    relative_read
  379.         push    1000h
  380.         pop     es
  381.         xor     di, di
  382.         mov     cx, 8
  383.         repz    cmpsw
  384.         mov     si, data_error_msg
  385.         jnz     find_error_si
  386. ; ok, now write back to disk
  387.         or      byte [read.patch1+2], 1
  388.         or      byte [read.patch2+2], 1
  389.         xor     bx, bx
  390.         pop     eax
  391.         pop     cx
  392.         call    relative_read
  393.         and     byte [read.patch1+1], not 1
  394.         and     byte [read.patch2+2], not 2
  395. ; and to image in memory (probably this may be done by kernel.mnt itself?)
  396.         mov     dword [sou_addr], 93010000h
  397.         movzx   eax, [kernel_mnt_in_img]
  398.         shl     eax, 9
  399.         add     eax, 93100000h
  400.         mov     dword [dest_addr], eax
  401.         mov     si, movedesc
  402.         push    ds
  403.         pop     es
  404.         mov     ah, 87h
  405.         mov     cx, 100h
  406.         int     15h
  407.         cmp     ah, 0
  408.         mov     si, exmem_string
  409.         jnz     find_error_si
  410.         retf
  411. else
  412. write1st = 0
  413. end if
  414.  
  415. loader_block:
  416.         db      1       ; version
  417.         dw      1       ; flags - image is loaded
  418.         dw      write1st        ; offset
  419.         dw      0               ; segment
  420.  
  421. imgnameofs dw kolibri_img_name
  422.  
  423. ; -----------------------------------------------
  424. ; ------------------ Settings -------------------
  425. ; -----------------------------------------------
  426.  
  427. ; must be in lowercase, see ntfs_parse_dir.scan, fat32_parse_dir.scan
  428. kernel_mnt_name         db      'kernel.mnt',0
  429. kolibri_img_name        db      'kolibri.img',0
  430.  
  431. missing_slash   dw      0
  432.  
  433. start_msg       db      2,' KolibriOS bootloader, FAT32 flash version'
  434. newline         db      13,10,0
  435. error_msg       db      'Error'
  436. colon           db      ': ',0
  437. root_string     db      '\',0
  438. nodata_string   db      '$DATA '
  439. notfound_string db      'not found',0
  440. directory_string db     'is a directory',0
  441. notdir_string   db      'not a directory',0
  442. exmem_string    db      'extended memory error',0
  443. bad_cluster_string db   'bad cluster',0
  444. data_error_msg db       'data error',0
  445.  
  446.         align 2
  447.  
  448. ; uninitialized data follows
  449. cur_obj                 dw      ?
  450. img_data_start          dw      ?
  451. kernel_mnt_in_img       dw      ?
  452. fat_start               dw      ?
  453. kernel_mnt_1st          dd      ?
  454.