Subversion Repositories Kolibri OS

Rev

Blame | Last modification | View Log | Download | RSS feed

  1. ; KolibriOS bootloader
  2. ; this code has been written by diamond in 2005,2006,2008 specially for KolibriOS
  3.  
  4. ; this code is loaded by ntldr to 0D00:0000
  5. ; and by io.sys from config.sys to xxxx:0100
  6. ; and by bootmgr in vista to 0000:7C00
  7.         format  binary
  8.         use16
  9.  
  10.         org     0xD000
  11. ; entry point for 9x and Vista booting
  12.         call    @f
  13. ;       db      'd' xor 'i' xor 'a' xor 'm' xor 'o' xor 'n' xor 'd'
  14.         db      'NTFS'
  15. @@:
  16.         pop     si
  17.         sub     si, 3
  18.         cmp     si, 7C00h
  19.         jz      boot_vista
  20.         mov     si, load_question + 100h - 0D000h
  21.         call    out_string
  22. ;       mov     si, answer + 100h - 0D000h      ; already is
  23. xxy:    mov     ah, 0
  24.         int     16h
  25.         or      al, 20h
  26.         mov     [si], al
  27.         cmp     al, 'y'
  28.         jz      xxz
  29.         cmp     al, 'n'
  30.         jnz     xxy
  31. ; continue load Windows
  32. ;       call    out_string
  33. ;       ret
  34. out_string:
  35.         lodsb
  36.         test    al, al
  37.         jz      .xxx
  38.         mov     ah, 0Eh
  39.         mov     bx, 7
  40.         int     10h
  41.         jmp     out_string
  42. .xxx:   ret
  43. xxz:
  44. ; boot KolibriOS
  45.         call    out_string
  46.         push    0
  47.         pop     ds
  48.         mov     word [4], new01handler + 100h - 0D000h
  49.         mov     [6], cs
  50.         pushf
  51.         pop     ax
  52.         or      ah, 1
  53.         push    ax
  54.         popf
  55. ;       int     19h
  56. ;       pushf           ; there will be no iret
  57.         call    far [19h*4]
  58. xxt:
  59. ; TF has been cleared when entered new01handler
  60. ;       pushf
  61. ;       pop     ax
  62. ;       and     ah, not 1
  63. ;       push    ax
  64. ;       popf
  65.         xor     di, di
  66.         mov     ds, di
  67.         cmp     word [8*4+2], 0F000h
  68.         jz      @f
  69.         les     bx, [8*4]
  70.         mov     eax, [es:bx+1]
  71.         mov     [8*4], eax
  72. @@:
  73.         mov     si, 100h
  74. boot_vista:
  75.         push    cs
  76.         pop     ds
  77.         push    0D00h
  78.         pop     es
  79.         mov     cx, 2000h/2
  80.         rep     movsw
  81.         jmp     0D00h:0256h
  82. load_question   db      'Load KolibriOS? [y/n]: ',0
  83. answer  db      ?
  84.         db      13,10,0
  85.  
  86. new01handler:
  87. ; [sp]=ip, [sp+2]=cs, [sp+4]=flags
  88.         push    bp
  89.         mov     bp, sp
  90.         push    bx
  91.         push    ds
  92.         lds     bx, [bp+2]
  93.         cmp     word [bx], 19cdh
  94.         jz      xxt
  95.         pop     ds
  96.         pop     bx
  97.         pop     bp
  98.         iret
  99.  
  100. relative_read:
  101.         add     eax, [partition_start]
  102.  
  103. ; read from hard disk
  104. ; drive_size must be already initialized
  105. ; in: eax = absolute sector
  106. ;     cx = number of sectors
  107. ;     es:bx -> buffer
  108. read:
  109.         pushad
  110.         cmp     eax, [drive_size]
  111.         jb      .old_style
  112. ; new style - LBA, function 42
  113.         cmp     [has_lba], 0
  114.         jz      disk_error
  115. ; allocate disk address packet on the stack
  116. ; qword +8: absolute block number
  117.         push    dword 0         ; dword +C is high dword
  118.         push    eax             ; dword +8 is low dword
  119. ; dword +4: buffer address
  120.         push    es              ; word +6 is segment
  121.         push    bx              ; word +4 is offset
  122. ; word +2: number of blocks = 1
  123. ; word +0: size of packet = 10h
  124.         push    dword 10010h
  125. ; now pair ss:sp contain address of disk address packet
  126. .patch1:
  127.         mov     ax, 4200h
  128.         mov     dl, [boot_drive]
  129.         mov     si, sp
  130.         push    ds
  131.         push    ss
  132.         pop     ds
  133.         int     13h
  134.         pop     ds
  135.         add     sp, 10h
  136. .end:
  137.         popad
  138.         jc      disk_error
  139.         add     bx, 200h
  140.         inc     eax
  141.         dec     cx
  142.         jnz     read
  143.         ret
  144. .old_style:
  145. ; old style - CHS, function 2
  146. ; convert absolute sector in eax to cylinder-head-sector coordinates
  147. ; calculate sector
  148.         xor     edx, edx
  149.         movzx   ecx, [sectors]
  150.         div     ecx
  151. ; sectors are counted from 1
  152.         inc     dx
  153.         mov     cl, dl          ; low 6 bits of cl = sector number
  154. ; calculate head number
  155.         shld    edx, eax, 10h   ; convert eax to dx:ax
  156.         div     [heads]
  157.         mov     dh, dl          ; dh = head
  158.         mov     ch, al          ; ch = low 8 bits of cylinder
  159.         shl     ah, 6
  160.         or      cl, ah          ; high 2 bits of cl = high 2 bits of cylinder
  161. .patch2:
  162.         mov     ax, 201h        ; function 2, al=1 - number of sectors
  163.         mov     dl, [boot_drive]
  164.         int     13h
  165.         jmp     .end
  166.  
  167. disk_error:
  168.         mov     si, disk_error_msg
  169.         call    out_string
  170.         jmp     $
  171.  
  172. has_lba db      0
  173.  
  174. disk_error_msg  db      'Disk read error!',0
  175. start_msg       db      2,' KolibriOS bootloader',13,10,0
  176. part_msg        db      'looking at partition '
  177. part_char       db      '0'     ; will be incremented before writing message
  178.                 db      ' ... ',0
  179. errfs_msg       db      'unknown filesystem',13,10,0
  180. fat16_msg       db      'FAT12/FAT16 - unsupported',13,10,0
  181. fat32_msg       db      'FAT32'
  182. newline         db      13,10,0
  183. ntfs_msg        db      'NTFS',13,10,0
  184. error_msg       db      'Error'
  185. colon           db      ': ',0
  186. mft_string      db      'MFT',0
  187. root_string     db      '\',0
  188. noindex_string  db      '$INDEX_ROOT not found',0
  189. invalid_read_request_string db 'cannot read attribute',0
  190. nodata_string   db      '$DATA '
  191. notfound_string db      'not found',0
  192. directory_string db     'is a directory',0
  193. notdir_string   db      'not a directory',0
  194. fragmented_string db    'too fragmented file',0
  195. exmem_string    db      'extended memory error',0
  196. bad_cluster_string db   'bad cluster',0
  197. data_error_msg db       'data error',0
  198.  
  199. ; init procedure - ntldr jmps here
  200.         repeat  0D256h - $
  201.                 db      1
  202.         end     repeat
  203. start:
  204. ; cs=es=0D00, ds=07C0, ss=0
  205. ; esi=edi=ebp=0, esp=7C00
  206.         xor     ax, ax
  207.         mov     ds, ax
  208.         mov     es, ax
  209. ; our stack is 4Kb-512b-2b!!! (0xDFE)
  210.         mov     ss, ax
  211.         mov     esp, 0FFFEh
  212.  
  213. ; we are booting from hard disk identified by [boot_drive]
  214.         mov     dl, [boot_drive]
  215.         cld
  216.         sti
  217. ; calculate drive size
  218.         mov     ah, 8   ; 8 = get drive parameters
  219.         int     13h
  220. ; now: CF is set on error;
  221. ; ch = low 8 bits of maximum cylinder number
  222. ; cl : low 6 bits makes maximum sector number, high 2 bits are high 2 bits of maximum cylinder number
  223. ; dh = maximum head number
  224.         jnc     @f
  225.         mov     cx, -1
  226.         mov     dh, cl
  227. @@:
  228.         movzx   ax, dh
  229.         inc     ax
  230. ; ax = number of heads
  231.         mov     [heads], ax
  232.         mov     dl, cl
  233.         and     dx, 3Fh
  234. ; dx = number of sectors
  235. ; (note that sectors are counted from 1, and maximum sector number = number of sectors)
  236.         mov     [sectors], dx
  237.         mul     dx
  238.         xchg    cl, ch
  239.         shr     ch, 6
  240.         inc     cx
  241. ; cx = number of cylinders
  242.         mov     [cyls], cx
  243.         mul     cx
  244.         mov     word [drive_size], ax
  245.         mov     word [drive_size+2], dx
  246. ; this drive supports LBA?
  247.         mov     dl, [boot_drive]
  248.         mov     ah, 41h
  249.         mov     bx, 55AAh
  250.         int     13h
  251.         jc      .no_lba
  252.         cmp     bx, 0AA55h
  253.         jnz     .no_lba
  254.         test    cl, 1
  255.         jz      .no_lba
  256.         inc     [has_lba]
  257. .no_lba:
  258. ; say hi to user
  259.         mov     si, start_msg
  260.         call    out_string
  261. ; now read first sector to determine file system type
  262. ; first sector of disk is MBR sector
  263.         xor     eax, eax
  264. new_partition_ex:
  265.         mov     cx, 1
  266.         mov     bx, 0F000h
  267.         call    read
  268. new_partition:
  269.         mov     bx, [cur_partition_ofs]
  270.         mov     al, [bx+4]      ; partition type
  271.         test    al, al
  272.         jz      next_partition
  273.         cmp     al, 5
  274.         jz      @f
  275.         cmp     al, 0xF
  276.         jnz     not_extended
  277. @@:
  278. ; extended partition
  279.         mov     eax, [bx+8]     ; partition start
  280.         add     eax, [extended_part_start]
  281.         mov     [extended_part_cur], eax
  282. next_partition:
  283.         add     [cur_partition_ofs], 10h
  284.         cmp     [cur_partition_ofs], 0xF1FE
  285.         jb      new_partition
  286.         mov     eax, [extended_part_cur]
  287.         test    eax, eax
  288.         jz      partitions_done
  289.         cmp     [extended_part_start], 0
  290.         jnz     @f
  291.         mov     [extended_part_start], eax
  292. @@:
  293.         mov     [extended_parent], eax
  294.         and     [extended_part_cur], 0
  295.         mov     [cur_partition_ofs], 0xF1BE
  296.         jmp     new_partition_ex
  297. partitions_done:
  298.         mov     si, total_kaput
  299.         call    out_string
  300.         jmp     $
  301. not_extended:
  302.         mov     eax, [bx+8]
  303.         add     eax, [extended_parent]
  304.         mov     [partition_start], eax
  305.         push    ax
  306.         mov     si, part_msg
  307.         inc     [si+part_char-part_msg]
  308.         call    out_string
  309.         pop     ax
  310.         mov     cx, 1
  311.         mov     bx, 500h
  312.         call    read
  313.         movzx   ax, byte [50Dh]
  314.         mov     [sect_per_clust], ax
  315. ; determine file system
  316.         cmp     dword [536h], 'FAT1'
  317.         jz      fat1x
  318.         cmp     dword [552h], 'FAT3'
  319.         jz      fat32
  320.         cmp     dword [503h], 'NTFS'
  321.         jz      ntfs
  322.         mov     si, errfs_msg
  323.         call    out_string
  324.         jmp     next_partition
  325. fat1x:
  326.         mov     si, fat16_msg
  327.         call    out_string
  328.         jmp     next_partition
  329. fat32:
  330.         mov     si, fat32_msg
  331.         call    out_string
  332.         movzx   eax, word [50Bh]        ; bytes_per_sect
  333.         movzx   ebx, byte [50Dh]        ; sects_per_clust
  334.         mul     ebx
  335.         mov     [cluster_size], eax
  336.         movzx   ebx, word [50Eh]        ; reserved_sect
  337.         mov     [fat_start], ebx
  338.         movzx   eax, byte [510h]        ; num_fats
  339.         mul     dword [524h]            ; sect_fat
  340.         add     eax, ebx
  341. ; cluster 2 begins from sector eax
  342.         movzx   ebx, byte [50Dh]        ; sects_per_clust
  343.         sub     eax, ebx
  344.         sub     eax, ebx
  345.         mov     [data_start], eax
  346. ; parse image name
  347.         mov     eax, [52Ch]     ; root_cluster
  348.         mov     [cur_obj], root_string
  349. .parsedir:
  350.         push    ax
  351.         mov     si, [imgnameofs]
  352.         push    si
  353. @@:
  354.         lodsb
  355.         cmp     al, 0
  356.         jz      @f
  357.         cmp     al, '\'
  358.         jnz     @b
  359.         dec     si
  360.         mov     [missing_slash], si
  361.         inc     si
  362. @@:
  363.         xchg    ax, [esp+2]
  364.         mov     byte [si-1], 0
  365.         mov     [imgnameofs], si
  366.         call    fat32_parse_dir
  367.         call    restore_slash
  368.         pop     cx
  369.         test    cl, cl
  370.         jz      .end
  371.         test    byte [di+0Bh], 10h
  372.         mov     si, notdir_string
  373.         jz      find_error_si
  374.         jmp     .parsedir
  375. .end:
  376.         test    byte [di+0Bh], 10h
  377.         mov     si, directory_string
  378.         jnz     find_error_si
  379. ; parse FAT chunk
  380. ; runlist at 2000:0000
  381.         mov     di, 5
  382.         push    2000h
  383.         pop     es
  384.         mov     byte [es:di-5], 1       ; of course, non-resident
  385.         mov     dword [es:di-4], 1
  386.         stosd
  387. .parsefat:
  388.         push    es
  389.         push    ds
  390.         pop     es
  391.         call    next_cluster
  392.         pop     es
  393.         jnc     .done
  394.         mov     ecx, [es:di-8]
  395.         add     ecx, [es:di-4]
  396.         cmp     eax, ecx
  397.         jz      .contc
  398.         mov     dword [es:di], 1
  399.         scasd
  400.         stosd
  401.         jmp     .parsefat
  402. .contc:
  403.         inc     dword [es:di-8]
  404.         jmp     .parsefat
  405. .done:
  406.         xor     eax, eax
  407.         stosd
  408.         jmp     read_img_file
  409.  
  410. ntfs:
  411.         mov     si, ntfs_msg
  412.         call    out_string
  413.         movzx   eax, word [50Bh]        ; bpb_bytes_per_sect
  414.         push    eax
  415.         movzx   ebx, byte [50Dh]        ; bpb_sects_per_clust
  416.         mul     ebx
  417.         mov     [cluster_size], eax
  418.         mov     [data_start], 0
  419.         mov     ecx, [540h]             ; frs_size
  420.         cmp     cl, 0
  421.         jg      .1
  422.         neg     cl
  423.         xor     eax, eax
  424.         inc     eax
  425.         shl     eax, cl
  426.         jmp     .2
  427. .1:
  428.         mul     ecx
  429. .2:
  430.         mov     [frs_size], eax
  431.         pop     ebx
  432.         xor     edx, edx
  433.         div     ebx
  434.         mov     [frs_sectors], ax
  435. ; read first MFT record - description of MFT itself
  436.         mov     [cur_obj], mft_string
  437.         movzx   eax, byte [50Dh]        ; bpb_sects_per_clust
  438.         mul     dword [530h]            ; mft_cluster
  439.         mov     cx, [frs_sectors]
  440.         mov     bx, 4000h
  441.         mov     di, bx
  442.         push    bx
  443.         call    relative_read
  444.         call    restore_usa
  445. ; scan for unnamed $DATA attribute
  446.         pop     di
  447.         mov     ax, 80h         ; $DATA
  448.         mov     bx, 700h
  449.         call    load_attr
  450.         mov     si, nodata_string
  451.         jc      find_error_si
  452.         mov     [free], bx
  453. ; load kolibri.img
  454. ; parse image name
  455.         mov     eax, 5          ; root cluster
  456.         mov     [cur_obj], root_string
  457. .parsedir:
  458.         push    ax
  459.         mov     si, [imgnameofs]
  460.         push    si
  461. @@:
  462.         lodsb
  463.         cmp     al, 0
  464.         jz      @f
  465.         cmp     al, '\'
  466.         jnz     @b
  467.         dec     si
  468.         mov     [missing_slash], si
  469.         inc     si
  470. @@:
  471.         xchg    ax, [esp+2]
  472.         mov     byte [si-1], 0
  473.         mov     [imgnameofs], si
  474.         call    ntfs_parse_dir
  475.         call    restore_slash
  476.         pop     cx
  477.         test    cl, cl
  478.         jnz     .parsedir
  479. read_img_file:
  480.         xor     si, si
  481.         push    es
  482.         pop     fs
  483. ; yes! Now read file to 0x100000
  484.         lods byte [fs:si]
  485.         cmp     al, 0   ; assume nonresident attr
  486.         mov     si, invalid_read_request_string
  487.         jz      find_error_si
  488.         mov     si, 1
  489.         xor     edi, edi
  490. ; read buffer to 1000:0000 and move it to extended memory
  491.         push    1000h
  492.         pop     es
  493.         xor     bx, bx
  494. .img_read_block:
  495.         lods dword [fs:si]              ; eax=length
  496.         xchg    eax, ecx
  497.         jecxz   .img_read_done
  498.         lods dword [fs:si]              ; eax=disk cluster
  499. .img_read_cluster:
  500.         pushad
  501. ; read part of file
  502.         movzx   ecx, byte [50Dh]
  503.         mul     ecx
  504.         add     eax, [data_start]
  505.         call    relative_read
  506. ; move it to extended memory
  507.         mov     ah, 87h
  508.         mov     ecx, [cluster_size]
  509.         push    ecx
  510.         shr     cx, 1
  511.         mov     si, movedesc
  512.         push    es
  513.         push    ds
  514.         pop     es
  515.         int     15h
  516.         pop     es
  517.         test    ah, ah
  518.         mov     si, exmem_string
  519.         jnz     find_error_si
  520.         pop     ecx
  521.         add     [dest_addr], ecx
  522.         popad
  523.         inc     eax
  524.         loop    .img_read_cluster
  525.         jmp     .img_read_block
  526. .img_read_done:
  527. ; kolibri.img loaded; now load kernel.mnt
  528. load_kernel:
  529.         push    ds
  530.         pop     es
  531.         mov     [cur_obj], kernel_mnt_name
  532. ; read boot sector
  533.         xor     eax, eax
  534.         mov     bx, 500h
  535.         mov     cx, 1
  536.         call    read_img
  537. ; init vars
  538.         mov     ax, [50Eh]      ; reserved_sect
  539.         add     ax, [51Ch]      ; hidden
  540.         mov     word [fat_start], ax
  541.         xchg    ax, bx
  542.         movzx   ax, byte [510h]         ; num_fats
  543.         mul     word [516h]             ; fat_length
  544.         add     ax, bx
  545. ; read root dir
  546.         mov     bx, 700h
  547.         mov     cx, [511h]      ; dir_entries
  548.         add     cx, 0Fh
  549.         shr     cx, 4
  550.         call    read_img
  551.         add     ax, cx
  552.         mov     [img_data_start], ax
  553.         shl     cx, 9
  554.         mov     di, bx
  555.         add     bx, cx
  556.         mov     byte [bx], 0
  557. .scan_loop:
  558.         cmp     byte [di], 0
  559.         mov     si, notfound_string
  560.         jz      find_error_si
  561.         mov     si, kernel_mnt_name
  562.         call    fat_compare_name
  563.         jz      .found
  564.         and     di, not 1Fh
  565.         add     di, 20h
  566.         jmp     .scan_loop
  567. .found:
  568.         and     di, not 1Fh
  569.         mov     si, directory_string
  570.         test    byte [di+0Bh], 10h
  571.         jnz     find_error_si
  572. ; found, now load it to 1000h:0000h
  573.         mov     ax, [di+1Ah]
  574. ; first cluster of kernel.mnt in ax
  575. ; translate it to sector on disk in kolibri.img
  576.         push    ax
  577.         dec     ax
  578.         dec     ax
  579.         movzx   cx, byte [50Dh]
  580.         mul     cx
  581.         add     ax, [img_data_start]
  582. ; now ax is sector in kolibri.img
  583.         mov     [kernel_mnt_in_img], ax
  584.         div     [sect_per_clust]
  585. ; now ax is cluster in kolibri.img and
  586. ; dx is offset from the beginning of cluster
  587.         movzx   eax, ax
  588.         push    2000h
  589.         pop     ds
  590.         mov     si, 1
  591. .scani:
  592.         sub     eax, [si]
  593.         jb      .scanidone
  594. ; sanity check
  595.         cmp     dword [si], 0
  596.         push    invalid_read_request_string
  597.         jz      find_error_sp
  598.         pop     cx
  599. ; next chunk
  600.         add     si, 8
  601.         jmp     .scani
  602. .scanidone:
  603.         add     eax, [si]       ; undo last subtract
  604.         add     eax, [si+4]     ; get cluster
  605.         push    0
  606.         pop     ds
  607.         movzx   ecx, [sect_per_clust]
  608.         push    dx
  609.         mul     ecx             ; get sector
  610.         pop     dx
  611.         movzx   edx, dx
  612.         add     eax, edx
  613.         add     eax, [data_start]
  614.         mov     [kernel_mnt_1st], eax
  615.         pop     ax
  616.         push    1000h
  617.         pop     es
  618. .read_loop:
  619.         push    ax
  620.         xor     bx, bx
  621.         call    img_read_cluster
  622.         shl     cx, 9-4
  623.         mov     ax, es
  624.         add     ax, cx
  625.         mov     es, ax
  626.         pop     ax
  627.         call    img_next_cluster
  628.         jc      .read_loop
  629.         mov     ax, 'KL'
  630.         mov     si, loader_block
  631.         jmp     1000h:0000h
  632.  
  633. img_next_cluster:
  634.         mov     bx, 700h
  635.         push    ax
  636.         shr     ax, 1
  637.         add     ax, [esp]
  638.         mov     dx, ax
  639.         shr     ax, 9
  640.         add     ax, word [fat_start]
  641.         mov     cx, 2
  642.         push    es
  643.         push    ds
  644.         pop     es
  645.         call    read_img
  646.         pop     es
  647.         and     dx, 1FFh
  648.         add     bx, dx
  649.         mov     ax, [bx]
  650.         pop     cx
  651.         test    cx, 1
  652.         jz      .1
  653.         shr     ax, 4
  654. .1:
  655.         and     ax, 0FFFh
  656.         mov     si, bad_cluster_string
  657.         cmp     ax, 0FF7h
  658.         jz      find_error_si
  659.         ret
  660. img_read_cluster:
  661.         dec     ax
  662.         dec     ax
  663.         movzx   cx, byte [50Dh] ; sects_per_clust
  664.         mul     cx
  665.         add     ax, [img_data_start]
  666.         movzx   eax, ax
  667. ;       call    read_img
  668. ;       ret
  669. read_img:
  670. ; in: ax = sector, es:bx->buffer, cx=length in sectors
  671.         pushad
  672.         movzx   ebx, bx
  673.         mov     si, movedesc
  674.         shl     eax, 9
  675.         add     eax, 93100000h
  676.         mov     dword [si+sou_addr-movedesc], eax
  677.         mov     eax, 9300000h
  678.         mov     ax, es
  679.         shl     eax, 4
  680.         add     eax, ebx
  681.         mov     [si+dest_addr-movedesc], eax
  682.         mov     ah, 87h
  683.         shl     cx, 8   ; mul 200h/2
  684.         push    es
  685.         push    0
  686.         pop     es
  687.         int     15h
  688.         pop     es
  689.         cmp     ah, 0
  690.         mov     si, exmem_string
  691.         jnz     find_error_si
  692.         popad
  693.         ret
  694.  
  695. movedesc:
  696.         times 16 db 0
  697. ; source
  698.         dw      0xFFFF          ; segment length
  699. sou_addr dw     0000h           ; linear address
  700.         db      1               ; linear address
  701.         db      93h             ; access rights
  702.         dw      0
  703. ; destination
  704.         dw      0xFFFF          ; segment length
  705. dest_addr dd    93100000h       ; high byte contains access rights
  706.                                 ; three low bytes contains linear address (updated when reading)
  707.         dw      0
  708.         times 32 db 0
  709.  
  710. find_error_si:
  711.         push    si
  712. find_error_sp:
  713.         mov     si, error_msg
  714.         call    out_string
  715.         mov     si, [cur_obj]
  716.         call    out_string
  717.         mov     si, colon
  718.         call    out_string
  719.         pop     si
  720.         call    out_string
  721.         mov     si, newline
  722.         call    out_string
  723.         or      [fat_cur_sector], -1
  724.         mov     [imgnameofs], kolibri_img_name
  725.         call    restore_slash
  726.         mov     sp, 0xFFFE
  727.         jmp     next_partition
  728.  
  729. file_not_found:
  730.         mov     si, [esp+2]
  731.         mov     [cur_obj], si
  732.         push    notfound_string
  733.         jmp     find_error_sp
  734.  
  735. restore_slash:
  736.         mov     si, [missing_slash]
  737.         test    si, si
  738.         jz      @f
  739.         and     [missing_slash], 0
  740.         mov     byte [si], '\'
  741. @@:     ret
  742.  
  743.         include 'fat32.inc'
  744.         include 'ntfs.inc'
  745.  
  746. write1st:
  747. ; callback from kernel.mnt
  748. ; write first sector of kernel.mnt from 1000:0000 back to disk
  749.         push    cs
  750.         pop     ds
  751.         push    cs
  752.         pop     es
  753. ; sanity check
  754.         mov     bx, 500h
  755.         mov     si, bx
  756.         mov     cx, 1
  757.         push    cx
  758.         mov     eax, [kernel_mnt_1st]
  759.         push    eax
  760.         call    relative_read
  761.         push    1000h
  762.         pop     es
  763.         xor     di, di
  764.         mov     cx, 8
  765.         repz    cmpsw
  766.         mov     si, data_error_msg
  767.         jnz     find_error_si
  768. ; ok, now write back to disk
  769.         or      byte [read.patch1+2], 1
  770.         or      byte [read.patch2+2], 1
  771.         xor     bx, bx
  772.         pop     eax
  773.         pop     cx
  774.         call    relative_read
  775.         and     byte [read.patch1+1], not 1
  776.         and     byte [read.patch2+2], not 2
  777. ; and to image in memory (probably this may be done by kernel.mnt itself?)
  778.         mov     dword [sou_addr], 93010000h
  779.         movzx   eax, [kernel_mnt_in_img]
  780.         shl     eax, 9
  781.         add     eax, 93100000h
  782.         mov     dword [dest_addr], eax
  783.         mov     si, movedesc
  784.         push    ds
  785.         pop     es
  786.         mov     ah, 87h
  787.         mov     cx, 100h
  788.         int     15h
  789.         cmp     ah, 0
  790.         mov     si, exmem_string
  791.         jnz     find_error_si
  792.         retf
  793.  
  794. loader_block:
  795.         db      1       ; version
  796.         dw      1       ; flags - image is loaded
  797.         dw      write1st        ; offset
  798.         dw      0               ; segment
  799.  
  800. fat_cur_sector dd -1
  801. imgnameofs dw kolibri_img_name
  802.  
  803. ; -----------------------------------------------
  804. ; ------------------ Settings -------------------
  805. ; -----------------------------------------------
  806.  
  807. ; must be in lowercase, see ntfs_parse_dir.scan, fat32_parse_dir.scan
  808. kernel_mnt_name         db      'kernel.mnt',0
  809. kolibri_img_name        db      'kolibri.img',0
  810.  
  811. ; change next variable if you want to boot from other physical drive
  812. boot_drive              db      80h
  813.  
  814. total_kaput     db      13,10,'Fatal: image is not found.',13,10,0
  815. missing_slash   dw      0
  816.         align 2
  817.  
  818. cur_partition_ofs       dw      0xF1BE
  819. extended_part_start     dd      0
  820. extended_part_cur       dd      0
  821. extended_parent         dd      0
  822.  
  823. ; uninitialized data follows
  824. drive_size              dd      ?       ; in sectors
  825. heads                   dw      ?
  826. sectors                 dw      ?
  827. cyls                    dw      ?
  828. partition_start         dd      ?
  829. free                    dw      ?
  830. cur_obj                 dw      ?
  831. data_start              dd      ?
  832. img_data_start          dw      ?
  833. sect_per_clust          dw      ?
  834. kernel_mnt_in_img       dw      ?
  835. kernel_mnt_1st          dd      ?
  836. ; NTFS data
  837. cluster_size            dd      ?       ; in bytes
  838. frs_size                dd      ?       ; in bytes
  839. frs_sectors             dw      ?       ; in sectors
  840. mft_data_attr           dw      ?
  841. index_root              dw      ?
  842. index_alloc             dw      ?
  843. ofs                     dw      ?
  844. dir                     dw      ?
  845. ; FAT32 data
  846. fat_start               dd      ?
  847. cur_cluster             dd      ?
  848. ; file must be 16 sectors long
  849.  
  850.         repeat  0F000h - $
  851.                 db      2
  852.         end     repeat
  853.