Subversion Repositories Kolibri OS

Rev

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

  1. GREEDY_KERNEL  equ 0
  2.  
  3.  
  4. struc APP_HEADER_00
  5. { .banner      dq ?
  6.   .version     dd ?    ;+8
  7.   .start       dd ?    ;+12
  8.   .i_end       dd ?    ;+16
  9.   .mem_size    dd ?    ;+20
  10.   .i_param     dd ?    ;+24
  11. }
  12.  
  13. struc APP_HEADER_01
  14. { .banner      dq ?
  15.   .version     dd ?    ;+8
  16.   .start       dd ?    ;+12
  17.   .i_end       dd ?    ;+16
  18.   .mem_size    dd ?    ;+20
  19.   .stack_top   dd ?    ;+24
  20.   .i_param     dd ?    ;+28
  21.   .i_icon      dd ?    ;+32
  22. }
  23.  
  24. struc TSS
  25. {
  26.   ._back   rw 2
  27.   ._esp0   rd 1
  28.   ._ss0    rw 2
  29.   ._esp1   rd 1
  30.   ._ss1    rw 2
  31.   ._esp2   rd 1
  32.   ._ss2    rw 2
  33.   ._cr3    rd 1
  34.   ._eip    rd 1
  35.   ._eflags rd 1
  36.   ._eax    rd 1
  37.   ._ecx    rd 1
  38.   ._edx    rd 1
  39.   ._ebx    rd 1
  40.   ._esp    rd 1
  41.   ._ebp    rd 1
  42.   ._esi    rd 1
  43.   ._edi    rd 1
  44.   ._es     rw 2
  45.   ._cs     rw 2
  46.   ._ss     rw 2
  47.   ._ds     rw 2
  48.   ._fs     rw 2
  49.   ._gs     rw 2
  50.   ._ldt    rw 2
  51.   ._trap   rw 1
  52.   ._io     rw 1
  53. }
  54.  
  55. virtual at 0
  56.   TSS  TSS
  57. end virtual
  58.  
  59. struc APP_PARAMS
  60. { .app_cmdline   ;0x00
  61.   .app_path      ;0x04
  62.   .app_eip       ;0x08
  63.   .app_esp       ;0x0C
  64.   .app_mem       ;0x10
  65. }
  66.  
  67. macro _clear_ op
  68. {  mov ecx, op/4
  69.    xor eax, eax
  70.    cld
  71.    rep stosd
  72. }
  73.  
  74.  
  75. align 4
  76. proc fs_execute
  77.  
  78. ;fn_read:dword, file_size:dword, cluster:dword
  79.  
  80. ; ebx - cmdline
  81. ; edx - flags
  82. ; ebp - full filename
  83. ; [esp+4] = procedure DoRead, [esp+8] = filesize & [esp+12]... - arguments for it
  84.  
  85.            locals
  86.              cmdline       rd 64        ;256/4
  87.              filename      rd 256       ;1024/4
  88.              flags         dd ?
  89.  
  90.              save_cr3      dd ?
  91.              slot          dd ?
  92.              slot_base     dd ?
  93.              file_base     dd ?
  94.              file_size     dd ?
  95.                                           ;app header data
  96.              hdr_cmdline   dd ? ;0x00
  97.              hdr_path      dd ? ;0x04
  98.              hdr_eip       dd ? ;0x08
  99.              hdr_esp       dd ? ;0x0C
  100.              hdr_mem       dd ? ;0x10
  101.              hdr_i_end     dd ? ;0x14
  102.            endl
  103.  
  104.            pushad
  105.  
  106.            mov [cmdline], ebx
  107.            mov [flags], edx
  108.  
  109. ; [ebp]  pointer to filename
  110.  
  111.            lea eax, [filename]
  112.            mov dword [eax+1020],0              ;force terminate
  113.                                                ;string
  114.            stdcall k_strncpy, eax, [ebp], 1023
  115.  
  116.            lea eax, [cmdline]
  117.            mov dword [eax+252], 0
  118.            stdcall k_strncpy, eax, [cmdline], 255
  119.  
  120.            lea eax, [filename]
  121.            stdcall load_file, eax
  122.            mov  ecx, -ERROR_FILE_NOT_FOUND
  123.            test eax, eax
  124.            jz .err_file
  125.  
  126.            mov [file_base], eax
  127.            mov [file_size], ebx
  128.  
  129.            lea ebx, [hdr_cmdline]
  130.            call test_app_header
  131.            mov ecx, -0x1F
  132.            test eax, eax
  133.            jz .err_hdr
  134.  
  135.            mov esi, new_process_loading
  136.            call sys_msg_board_str       ; write message to message board
  137.  
  138. .wait_lock:
  139.            cmp [application_table_status],0
  140.            je .get_lock
  141.            call   change_task
  142.            jmp .wait_lock
  143.  
  144. .get_lock:
  145.            mov eax, 1
  146.            xchg eax, [application_table_status]
  147.            cmp eax, 0
  148.            jne .wait_lock
  149.  
  150. ;           pushfd
  151. ;           cli
  152.  
  153.            call set_application_table_status
  154.  
  155.            call get_new_process_place
  156.            test eax, eax
  157.            mov ecx, -0x20      ; too many processes
  158.            jz .err
  159.  
  160.            mov [slot], eax
  161.            shl eax, 8
  162.            add eax, SLOT_BASE
  163.            mov [slot_base], eax
  164.            mov edi, eax
  165.            _clear_ 256     ;clean extended information about process
  166.  
  167. ; write application name
  168.            lea edi, [filename]
  169.            mov al, '/'
  170.            call k_strrchr  ; now eax points to name without path
  171.  
  172.            lea esi, [eax+1]
  173.            test eax, eax
  174.            jnz @F
  175.            lea esi, [filename]
  176. @@:
  177.            mov ecx, 8  ; 8 chars for name
  178.            mov edi, [slot_base]
  179. .copy_process_name_loop:
  180.            lodsb
  181.            cmp al, '.'
  182.            jz .copy_process_name_done
  183.            test al, al
  184.            jz .copy_process_name_done
  185.            stosb
  186.            loop .copy_process_name_loop
  187. .copy_process_name_done:
  188.  
  189.            mov ebx, cr3
  190.            mov [save_cr3], ebx
  191.  
  192.            stdcall create_app_space,[hdr_mem],[file_base],[file_size]
  193.            mov ecx, -30  ; no memory
  194.            test eax, eax
  195.            jz .failed
  196.  
  197.            mov   ebx,[slot_base]
  198.            mov   [ebx+APPDATA.dir_table],eax
  199.            mov   eax,[hdr_mem]
  200.            mov   [ebx+APPDATA.mem_size],eax
  201.  
  202. if GREEDY_KERNEL
  203. else
  204.            mov ecx, [hdr_mem]
  205.            mov edi, [file_size]
  206.            add edi, 4095
  207.            and edi, not 4095
  208.            sub ecx, edi
  209.            jna @F
  210.  
  211.            xor eax, eax
  212.            add edi, new_app_base
  213.            cld
  214.            rep stosb
  215. @@:
  216. end if
  217.  
  218. ; release only virtual space, not phisical memory
  219.  
  220.            stdcall free_kernel_space, [file_base]
  221.            lea eax, [hdr_cmdline]
  222.            lea ebx, [cmdline]
  223.            lea ecx, [filename]
  224.            stdcall set_app_params ,[slot],eax,ebx,ecx,[flags]
  225.  
  226.            mov eax, [save_cr3]
  227.            call set_cr3
  228.  
  229.  ;          popfd
  230.            xor ebx, ebx
  231.            mov [application_table_status],ebx ;unlock application_table_status mutex
  232.            mov eax,[process_number]  ;set result
  233.            ret
  234. .failed:
  235.            mov eax, [save_cr3]
  236.            call set_cr3
  237. .err:
  238.  ;          popfd
  239. .err_hdr:
  240.            stdcall kernel_free,[file_base]
  241. .err_file:
  242.            xor eax, eax
  243.            mov [application_table_status],eax
  244.            mov eax, ecx
  245.            ret
  246. endp
  247.  
  248. align 4
  249. test_app_header:
  250.            virtual at eax
  251.              APP_HEADER_00 APP_HEADER_00
  252.            end virtual
  253.            virtual at eax
  254.              APP_HEADER_01 APP_HEADER_01
  255.            end virtual
  256.  
  257.            cmp dword [eax], 'MENU'
  258.            jne .fail
  259.            cmp word [eax+4],'ET'
  260.            jne .fail
  261.  
  262.            cmp [eax+6], word '00'
  263.            jne  .check_01_header
  264.  
  265.            mov  ecx,[APP_HEADER_00.start]
  266.            mov  [ebx+0x08], ecx                ;app_eip
  267.            mov  edx,[APP_HEADER_00.mem_size]
  268.            mov  [ebx+0x10], edx                ;app_mem
  269.            shr  edx,1
  270.            sub  edx,0x10
  271.            mov  [ebx+0x0C], edx                ;app_esp
  272.            mov  ecx,[APP_HEADER_00.i_param]
  273.            mov  [ebx], ecx                     ;app_cmdline
  274.            mov  [ebx+4], dword 0               ;app_path
  275.            mov  edx, [APP_HEADER_00.i_end]
  276.            mov  [ebx+0x14], edx
  277.            ret
  278.  
  279.  .check_01_header:
  280.  
  281.            cmp  [eax+6],word '01'
  282.            jne  .fail
  283.  
  284.            mov  ecx,[APP_HEADER_01.start]
  285.            mov  [ebx+0x08], ecx                ;app_eip
  286.            mov  edx,[APP_HEADER_01.mem_size]
  287.  
  288. ; \begin{diamond}[20.08.2006]
  289. ; sanity check (functions 19,58 load app_i_end bytes and that must
  290. ; fit in allocated memory to prevent kernel faults)
  291.            cmp  edx,[APP_HEADER_01.i_end]
  292.            jb   .fail
  293. ; \end{diamond}[20.08.2006]
  294.  
  295.            mov  [ebx+0x10], edx                ;app_mem
  296.            mov  ecx,[APP_HEADER_01.stack_top]
  297.            mov  [ebx+0x0C], ecx                ;app_esp
  298.            mov  edx,[APP_HEADER_01.i_param]
  299.            mov  [ebx], edx                     ;app_cmdline
  300.            mov  ecx,[APP_HEADER_01.i_icon]
  301.            mov  [ebx+4], ecx                   ;app_path
  302.            mov  edx, [APP_HEADER_01.i_end]
  303.            mov  [ebx+0x14], edx
  304.            ret
  305. .fail:
  306.            xor eax, eax
  307.            ret
  308.  
  309. align 4
  310. proc get_new_process_place
  311. ;input:
  312. ;  none
  313. ;result:
  314. ;  eax=[new_process_place]<>0 - ok
  315. ;      0 - failed.
  316. ;This function find least empty slot.
  317. ;It doesn't increase [TASK_COUNT]!
  318.            mov    eax,CURRENT_TASK
  319.            mov    ebx,[TASK_COUNT]
  320.            inc    ebx
  321.            shl    ebx,5
  322.            add    ebx,eax               ;ebx - address of process information for (last+1) slot
  323. .newprocessplace:
  324. ;eax = address of process information for current slot
  325.            cmp    eax,ebx
  326.            jz     .endnewprocessplace   ;empty slot after high boundary
  327.            add    eax,0x20
  328.            cmp    word [eax+0xa],9      ;check process state, 9 means that process slot is empty
  329.            jnz    .newprocessplace
  330. .endnewprocessplace:
  331.            mov    ebx,eax
  332.            sub    eax,CURRENT_TASK
  333.            shr    eax,5                 ;calculate slot index
  334.            cmp    eax,256
  335.            jge    .failed               ;it should be <256
  336.            mov    word [ebx+0xa],9      ;set process state to 9 (for slot after hight boundary)
  337.         ;   mov [new_process_place], eax
  338.            ret
  339.  
  340. .failed:
  341.            xor    eax,eax
  342.            ret
  343. endp
  344.  
  345. align 4
  346. proc create_app_space stdcall, app_size:dword,img_base:dword,img_size:dword
  347.            locals
  348.              app_pages   dd ?
  349.              img_pages   dd ?
  350.              dir_addr    dd ?
  351.              app_tabs    dd ?
  352.            endl
  353.  
  354.            mov ebx, pg_data.pg_mutex
  355.            call wait_mutex   ;ebx
  356.  
  357.            xor eax, eax
  358.            mov [dir_addr], eax
  359.  
  360.            mov eax, [app_size]
  361.            add eax, 4095
  362.            and eax, NOT(4095)
  363.            mov [app_size], eax
  364.            mov ebx, eax
  365.            shr eax, 12
  366.            mov [app_pages], eax
  367.  
  368.            add ebx, 0x3FFFFF
  369.            and ebx, NOT(0x3FFFFF)
  370.            shr ebx, 22
  371.            mov [app_tabs], ebx
  372.  
  373.            mov ecx, [img_size]
  374.            add ecx, 4095
  375.            and ecx, NOT(4095)
  376.  
  377.            mov [img_size], ecx
  378.            shr ecx, 12
  379.            mov [img_pages], ecx
  380.  
  381.      if GREEDY_KERNEL
  382.            lea eax, [ecx+ebx+2]    ;only image size
  383.      else
  384.            lea eax, [eax+ebx+2]    ;all requested memory
  385.      end if
  386.            cmp eax, [pg_data.pages_free]
  387.            ja .fail
  388.  
  389.            call alloc_page
  390.            test eax, eax
  391.            jz .fail
  392.            mov [dir_addr], eax
  393.            stdcall map_page,[tmp_task_pdir],eax,dword PG_SW
  394.  
  395.            mov esi, sys_pgdir
  396.            mov edi, [tmp_task_pdir]
  397.            mov ecx, (page_tabs shr 20)/4
  398.            cld
  399.            rep movsd
  400.  
  401.            mov eax, [dir_addr]
  402.            or eax, PG_SW
  403.            stosd                 ; [(page_tabs shr 20)]= eax
  404.  
  405.            mov ecx, 0x800/4
  406.            xor eax, eax
  407.            rep stosd
  408.  
  409.            mov eax, [dir_addr]
  410.            call set_cr3
  411.  
  412.            mov edx, [app_tabs]
  413.            mov edi, new_app_base
  414. @@:
  415.            call alloc_page
  416.            test eax, eax
  417.            jz .fail
  418.  
  419.            stdcall map_page_table, edi, eax
  420.            add edi, 0x00400000
  421.            dec edx
  422.            jnz @B
  423.  
  424.            mov edi, new_app_base
  425.            shr edi, 10
  426.            add edi, page_tabs
  427.  
  428.            mov ecx, [app_tabs]
  429.            shl ecx, 10
  430.            xor eax, eax
  431.            rep stosd
  432.  
  433.            mov ecx, [img_pages]
  434.            mov ebx, PG_UW
  435.            mov edx, new_app_base
  436.            mov esi, [img_base]
  437.            mov edi, new_app_base
  438.            shr esi, 10
  439.            shr edi, 10
  440.            add esi, page_tabs
  441.            add edi, page_tabs
  442. .remap:
  443.            lodsd
  444.            or eax, ebx      ; force user level r/w access
  445.            stosd
  446.            add edx, 0x1000
  447.            dec [app_pages]
  448.            dec ecx
  449.            jnz .remap
  450.  
  451.            mov ecx, [app_pages]
  452.            test ecx, ecx
  453.            jz .done
  454.  
  455. if GREEDY_KERNEL
  456.            mov eax, 0x02
  457. .reserve:
  458.            stosd
  459.            invlpg [edx]
  460.            add edx, 4096
  461.            dec ecx
  462.            jnz .reserve
  463. else
  464.  
  465. .alloc:
  466.            call alloc_page
  467.            test eax, eax
  468.            jz .fail
  469.  
  470.            stdcall map_page,edx,eax,dword PG_UW
  471.            add edx, 0x1000
  472.            dec [app_pages]
  473.            jnz .alloc
  474.  
  475. end if
  476.  
  477. .done:
  478.            stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP
  479.  
  480.            dec [pg_data.pg_mutex]
  481.            mov eax, [dir_addr]
  482.            ret
  483. .fail:
  484.            dec [pg_data.pg_mutex]
  485.            cmp [dir_addr], 0
  486.            je @f
  487.            stdcall destroy_app_space, [dir_addr]
  488. @@:
  489.            xor eax, eax
  490.            ret
  491. endp
  492.  
  493. align 4
  494. set_cr3:
  495.            mov esi, [CURRENT_TASK]
  496.            mov ebx, esi
  497.            shl esi,8
  498.            mov [SLOT_BASE+esi+0xB8],eax
  499.            imul   ebx,tss_step
  500.            add    ebx,tss_data
  501.            mov [ebx+28], eax
  502.            mov cr3, eax
  503.            ret
  504.  
  505. align 4
  506. proc destroy_page_table stdcall, pg_tab:dword
  507.  
  508.            push esi
  509.  
  510.            mov esi, [pg_tab]
  511.            mov ecx, 1024
  512. .free:
  513.            mov eax, [esi]
  514.            test eax, 1
  515.            jz .next
  516.            call free_page
  517. .next:
  518.            add esi, 4
  519.            dec ecx
  520.            jnz .free
  521.            pop esi
  522.            ret
  523. endp
  524.  
  525. align 4
  526. proc destroy_app_space stdcall, pg_dir:dword
  527.  
  528.            mov ebx, pg_data.pg_mutex
  529.            call wait_mutex   ;ebx
  530.  
  531.            xor   edx,edx
  532.            mov   eax,0x2
  533.            mov ebx, [pg_dir]
  534.  
  535. .loop:
  536. ;eax = current slot of process
  537.            mov   ecx,eax
  538.            shl   ecx,5
  539.            cmp   byte [CURRENT_TASK+ecx+0xa],9  ;if process running?
  540.            jz    @f                              ;skip empty slots
  541.            shl   ecx,3
  542.            cmp   [SLOT_BASE+ecx+0xB8],ebx       ;compare page directory addresses
  543.            jnz   @f
  544.            inc   edx                            ;thread found
  545. @@:
  546.            inc   eax
  547.            cmp   eax,[TASK_COUNT]               ;exit loop if we look through all processes
  548.            jle   .loop
  549.  
  550. ;edx = number of threads
  551. ;our process is zombi so it isn't counted
  552.            cmp   edx,1
  553.            jg    .exit
  554. ;if there isn't threads then clear memory.
  555.  
  556.            mov eax, [pg_dir]
  557.            and eax, not 0xFFF
  558.            stdcall map_page,[tmp_task_pdir],eax,dword PG_SW
  559.            mov esi, [tmp_task_pdir]
  560.            add esi, 0x800
  561.            mov edi, 0x800/4
  562. .destroy:
  563.            mov eax, [esi]
  564.            test eax, 1
  565.            jz .next
  566.            and eax, not 0xFFF
  567.            stdcall map_page,[tmp_task_ptab],eax,dword PG_SW
  568.            stdcall destroy_page_table, [tmp_task_ptab]
  569.            mov eax, [esi]
  570.            call free_page
  571. .next:
  572.            add esi, 4
  573.            dec edi
  574.            jnz .destroy
  575.  
  576.            mov eax, [pg_dir]
  577.            call free_page
  578. .exit:
  579.            stdcall map_page,[tmp_task_ptab],dword 0,dword PG_UNMAP
  580.            stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP
  581.            dec [pg_data.pg_mutex]
  582.            ret
  583. endp
  584.  
  585. pid_to_slot:
  586. ;Input:
  587. ;  eax - pid of process
  588. ;Output:
  589. ;  eax - slot of process or 0 if process don't exists
  590. ;Search process by PID.
  591.     push   ebx
  592.     push   ecx
  593.     mov    ebx,[TASK_COUNT]
  594.     shl    ebx,5
  595.     mov    ecx,2*32
  596.  
  597. .loop:
  598. ;ecx=offset of current process info entry
  599. ;ebx=maximum permitted offset
  600.     cmp    byte [CURRENT_TASK+ecx+0xa],9
  601.     jz     .endloop              ;skip empty slots
  602.     cmp    [CURRENT_TASK+ecx+0x4],eax ;check PID
  603.     jz     .pid_found
  604. .endloop:
  605.     add    ecx,32
  606.     cmp    ecx,ebx
  607.     jle    .loop
  608.  
  609.     pop    ecx
  610.     pop    ebx
  611.     xor    eax,eax
  612.     ret
  613.  
  614. .pid_found:
  615.     shr    ecx,5
  616.     mov    eax,ecx               ;convert offset to index of slot
  617.     pop    ecx
  618.     pop    ebx
  619.     ret
  620.  
  621. check_region:
  622. ;input:
  623. ;  ebx - start of buffer
  624. ;  ecx - size of buffer
  625. ;result:
  626. ;  eax = 1 region lays in app memory
  627. ;  eax = 0 region don't lays in app memory
  628.      mov  eax,[CURRENT_TASK]
  629.      jmp  check_process_region
  630. ;-----------------------------------------------------------------------------
  631. check_process_region:
  632. ;input:
  633. ;  eax - slot
  634. ;  ebx - start of buffer
  635. ;  ecx - size of buffer
  636. ;result:
  637. ;  eax = 1 region lays in app memory
  638. ;  eax = 0 region don't lays in app memory
  639.  
  640.      test ecx,ecx
  641.      jle  .ok
  642.      shl  eax,5
  643.      cmp  word [CURRENT_TASK+eax+0xa],0
  644.      jnz  .failed
  645.      shl  eax,3
  646.      mov  eax,[SLOT_BASE+eax+0xb8]
  647.      test eax,eax
  648.      jz   .failed
  649.  
  650.      mov  eax,1
  651.      ret
  652.  
  653.  
  654. ;    call MEM_Get_Linear_Address
  655. ;    push ebx
  656. ;    push ecx
  657. ;    push edx
  658. ;    mov  edx,ebx
  659. ;    and  edx,not (4096-1)
  660. ;    sub  ebx,edx
  661. ;    add  ecx,ebx
  662. ;    mov  ebx,edx
  663. ;    add  ecx,(4096-1)
  664. ;    and  ecx,not (4096-1)
  665. ;.loop:
  666. ;;eax - linear address of page directory
  667. ;;ebx - current page
  668. ;;ecx - current size
  669. ;    mov  edx,ebx
  670. ;    shr  edx,22
  671. ;    mov  edx,[eax+4*edx]
  672. ;    and  edx,not (4096-1)
  673. ;    test edx,edx
  674. ;    jz   .failed1
  675. ;    push eax
  676. ;    mov  eax,edx
  677. ;    call MEM_Get_Linear_Address
  678. ;    mov  edx,ebx
  679. ;    shr  edx,12
  680. ;    and  edx,(1024-1)
  681. ;    mov  eax,[eax+4*edx]
  682. ;    and  eax,not (4096-1)
  683. ;    test eax,eax
  684. ;    pop  eax
  685. ;    jz   .failed1
  686. ;    add  ebx,4096
  687. ;    sub  ecx,4096
  688. ;    jg   .loop
  689. ;    pop  edx
  690. ;    pop  ecx
  691. ;    pop  ebx
  692. .ok:
  693.     mov  eax,1
  694.     ret
  695. ;
  696. ;.failed1:
  697. ;    pop  edx
  698. ;    pop  ecx
  699. ;    pop  ebx
  700. .failed:
  701.     xor  eax,eax
  702.     ret
  703.  
  704. align 4
  705. proc read_process_memory
  706. ;Input:
  707. ;  eax - process slot
  708. ;  ebx - buffer address
  709. ;  ecx - buffer size
  710. ;  edx - start address in other process
  711. ;Output:
  712. ;  eax - number of bytes read.
  713.            locals
  714.              slot       dd ?
  715.              buff       dd ?
  716.              r_count    dd ?
  717.              offset     dd ?
  718.              tmp_r_cnt  dd ?
  719.            endl
  720.  
  721.            mov [slot], eax
  722.            mov [buff], ebx
  723.            mov [r_count], ecx
  724.            mov [tmp_r_cnt], ecx
  725.            mov [offset], edx
  726.  
  727.            pushad
  728. .read_mem:
  729.            mov edx, [offset]
  730.            mov ebx, [tmp_r_cnt]
  731.  
  732.            mov ecx, 0x400000
  733.            and edx, 0x3FFFFF
  734.            sub ecx, edx
  735.            cmp ecx, ebx
  736.            jbe @f
  737.            mov ecx, ebx
  738. @@:
  739.            cmp ecx, 0x8000
  740.            jna @F
  741.            mov ecx, 0x8000
  742. @@:
  743.            mov eax, [slot]
  744.            shl  eax,8
  745.            mov ebx, [offset]
  746.            add ebx, new_app_base
  747.            push ecx
  748.            stdcall map_memEx, [proc_mem_map],\
  749.                               [SLOT_BASE+eax+0xB8],\
  750.                               ebx, ecx
  751.            pop ecx
  752.  
  753.            mov esi, [offset]
  754.            and esi, 0xfff
  755.            add esi, [proc_mem_map]
  756.            mov edi, [buff]
  757.            mov edx, ecx
  758.            rep movsb
  759.  
  760.            add [offset], edx
  761.            sub [tmp_r_cnt], edx
  762.            jnz .read_mem
  763.  
  764.            popad
  765.            mov eax, [r_count]
  766.            ret
  767. endp
  768.  
  769. align 4
  770. proc write_process_memory
  771. ;Input:
  772. ;  eax - process slot
  773. ;  ebx - buffer address
  774. ;  ecx - buffer size
  775. ;  edx - start address in other process
  776. ;Output:
  777. ;  eax - number of bytes written
  778.  
  779.            locals
  780.              slot       dd ?
  781.              buff       dd ?
  782.              w_count    dd ?
  783.              offset     dd ?
  784.              tmp_w_cnt  dd ?
  785.            endl
  786.  
  787.            mov [slot], eax
  788.            mov [buff], ebx
  789.            mov [w_count], ecx
  790.            mov [tmp_w_cnt], ecx
  791.            mov [offset], edx
  792.  
  793.            pushad
  794. .read_mem:
  795.            mov edx, [offset]
  796.            mov ebx, [tmp_w_cnt]
  797.  
  798.            mov ecx, 0x400000
  799.            and edx, 0x3FFFFF
  800.            sub ecx, edx
  801.            cmp ecx, ebx
  802.            jbe @f
  803.            mov ecx, ebx
  804. @@:
  805.            cmp ecx, 0x8000
  806.            jna @F
  807.            mov ecx, 0x8000
  808. @@:
  809.            mov eax, [slot]
  810.            shl  eax,8
  811.            mov ebx, [offset]
  812.            add ebx, new_app_base
  813.            push ecx
  814.            stdcall map_memEx, [proc_mem_map],\
  815.                               [SLOT_BASE+eax+0xB8],\
  816.                               ebx, ecx
  817.            pop ecx
  818.  
  819.            mov edi, [offset]
  820.            and edi, 0xfff
  821.            add edi, [proc_mem_map]
  822.            mov esi, [buff]
  823.            mov edx, ecx
  824.            rep movsb
  825.  
  826.            add [offset], edx
  827.            sub [tmp_w_cnt], edx
  828.            jnz .read_mem
  829.  
  830.            popad
  831.            mov eax, [w_count]
  832.            ret
  833. endp
  834.  
  835. align 4
  836. proc new_sys_threads
  837.            locals
  838.              slot          dd ?
  839.              app_cmdline   dd ? ;0x00
  840.              app_path      dd ? ;0x04
  841.              app_eip       dd ? ;0x08
  842.              app_esp       dd ? ;0x0C
  843.              app_mem       dd ? ;0x10
  844.            endl
  845.  
  846.            cmp eax,1
  847.            jne .failed                  ;other subfunctions
  848.  
  849.            xor  eax,eax
  850.            mov [app_cmdline], eax
  851.            mov [app_path], eax
  852.            mov [app_eip], ebx
  853.            mov [app_esp], ecx
  854.  
  855.            mov    esi,new_process_loading
  856.            call   sys_msg_board_str
  857. .wait_lock:
  858.            cmp [application_table_status],0
  859.            je .get_lock
  860.            call   change_task
  861.            jmp .wait_lock
  862.  
  863. .get_lock:
  864.            mov eax, 1
  865.            xchg eax, [application_table_status]
  866.            cmp eax, 0
  867.            jne .wait_lock
  868.  
  869.            call   set_application_table_status
  870.  
  871.            call get_new_process_place
  872.            test eax, eax
  873.            jz .failed
  874.  
  875.            mov [slot], eax
  876.  
  877.            mov    esi,[CURRENT_TASK]
  878.            shl    esi,8
  879.            add    esi,SLOT_BASE
  880.            mov    ebx,esi             ;ebx=esi - pointer to extended information about current thread
  881.  
  882.            mov    edi, eax
  883.            shl    edi,8
  884.            add    edi,SLOT_BASE
  885.            mov    edx,edi             ;edx=edi - pointer to extended infomation about new thread
  886.            mov    ecx,256/4
  887.            xor eax, eax
  888.            cld
  889.            rep    stosd               ;clean extended information about new thread
  890.            mov    esi,ebx
  891.            mov    edi,edx
  892.            mov    ecx,11
  893.            rep    movsb               ;copy process name
  894.  
  895.            mov eax,[ebx+APPDATA.heap_base]
  896.            mov [edx+APPDATA.heap_base], eax
  897.  
  898.            mov ecx,[ebx+APPDATA.heap_top]
  899.            mov [edx+APPDATA.heap_top], ecx
  900.  
  901.            mov eax,[ebx+APPDATA.mem_size]
  902.            mov [edx+APPDATA.mem_size], eax
  903.  
  904.            mov ecx,[ebx+APPDATA.dir_table]
  905.            mov [edx+APPDATA.dir_table],ecx      ;copy page directory
  906.  
  907.            lea eax, [app_cmdline]
  908.            stdcall set_app_params ,[slot],eax,dword 0,\
  909.                                          dword 0,dword 0
  910.  
  911.            mov    esi,new_process_running
  912.            call   sys_msg_board_str     ;output information about succefull startup
  913.  
  914.            mov    [application_table_status],0 ;unlock application_table_status mutex
  915.            mov    eax,[process_number]  ;set result
  916.            ret
  917. .failed:
  918.            mov    [application_table_status],0
  919.            mov    eax,-1
  920.            ret
  921. endp
  922.  
  923. ; param
  924. ;  ebx=mutex
  925.  
  926. align 4
  927. wait_mutex:
  928.            push eax
  929.            push ebx
  930. .do_wait:
  931.            cmp dword [ebx],0
  932.            je .get_lock
  933.            call change_task
  934.            jmp .do_wait
  935. .get_lock:
  936.            mov eax, 1
  937.            xchg eax, [ebx]
  938.            test eax, eax
  939.            jnz .do_wait
  940.            pop ebx
  941.            pop eax
  942.            ret
  943.  
  944. align 4
  945. proc set_app_params stdcall,slot:dword, params:dword,\
  946.                         cmd_line:dword, app_path:dword, flags:dword
  947.  
  948.            locals
  949.              pl0_stack dd ?
  950.            endl
  951.  
  952.            stdcall kernel_alloc, 0x2000
  953.            mov [pl0_stack], eax
  954.  
  955.            lea edi, [eax+0x2000-512]
  956.  
  957.            mov eax, [slot]
  958.            mov ebx, eax
  959.  
  960.            shl eax, 8
  961.            mov [eax+SLOT_BASE+APPDATA.fpu_state], edi
  962.            mov [eax+SLOT_BASE+APPDATA.fpu_handler], 0
  963.            mov [eax+SLOT_BASE+APPDATA.sse_handler], 0
  964.  
  965.            mov esi, fpu_data
  966.            mov ecx, 512/4
  967.            rep movsd
  968.  
  969.            cmp    ebx,[TASK_COUNT]
  970.            jle    .noinc
  971.            inc    dword [TASK_COUNT]       ;update number of processes
  972. .noinc:
  973.            shl ebx,8
  974.            lea edx, [ebx+SLOT_BASE+APP_EV_OFFSET]
  975.            mov [SLOT_BASE+APPDATA.fd_ev+ebx],edx
  976.            mov [SLOT_BASE+APPDATA.bk_ev+ebx],edx
  977.  
  978.            add edx, APP_OBJ_OFFSET-APP_EV_OFFSET
  979.            mov [SLOT_BASE+APPDATA.fd_obj+ebx],edx
  980.            mov [SLOT_BASE+APPDATA.bk_obj+ebx],edx
  981.  
  982.            mov ecx, [def_cursor]
  983.            mov [SLOT_BASE+APPDATA.cursor+ebx],ecx
  984.            mov eax, [pl0_stack]
  985.            mov [SLOT_BASE+APPDATA.pl0_stack+ebx],eax
  986.  
  987.            shr ebx,3
  988.            mov eax, new_app_base
  989.            mov dword [CURRENT_TASK+ebx+0x10],eax
  990.  
  991. .add_command_line:
  992.            mov edx,[params]
  993.            mov edx,[edx]           ;app_cmdline
  994.            test edx,edx
  995.            jz @F                   ;application don't need parameters
  996.  
  997.            mov     eax, edx
  998.            add     eax, 256
  999.            jc      @f
  1000.  
  1001.            cmp     eax, [SLOT_BASE+APPDATA.mem_size+ebx*8]
  1002.            ja      @f
  1003.  
  1004.            add edx, new_app_base
  1005.            stdcall k_strncpy, edx, [cmd_line], 256
  1006. @@:
  1007.            mov edx,[params]
  1008.            mov edx, [edx+4]        ;app_path
  1009.            test edx,edx
  1010.            jz @F                   ;application don't need path of file
  1011.         mov     eax, edx
  1012.         add     eax, 1024
  1013.         jc      @f
  1014.         cmp     eax, [SLOT_BASE+APPDATA.mem_size+ebx*8]
  1015.         ja      @f
  1016.            add edx, new_app_base
  1017.            stdcall k_strncpy, edx, [app_path], 1024
  1018. @@:
  1019.            mov    ebx,[slot]
  1020.            mov    eax,ebx
  1021.            shl    ebx,5
  1022. ; set window state to 'normal' (non-minimized/maximized/rolled-up) state
  1023.            mov     [ebx+window_data+WDATA.fl_wstate], WSTATE_NORMAL
  1024.            mov     [ebx+window_data+WDATA.fl_redraw], 1
  1025.            add    ebx,CURRENT_TASK            ;ebx - pointer to information about process
  1026.            mov    [ebx+TASKDATA.wnd_number],al;set window number on screen = process slot
  1027.  
  1028.            mov    [ebx+TASKDATA.event_mask],dword 1+2+4 ;set default event flags (see 40 function)
  1029.  
  1030.            inc    dword [process_number]
  1031.            mov    eax,[process_number]
  1032.            mov    [ebx+4],eax           ;set PID
  1033.  
  1034.            mov    ecx,ebx
  1035.            add    ecx,(draw_data-CURRENT_TASK)  ;ecx - pointer to draw data
  1036. ;set draw data to full screen
  1037.  
  1038.            mov    [ecx+0],dword 0
  1039.            mov    [ecx+4],dword 0
  1040.            mov    eax,[ScreenWidth]
  1041.            mov    [ecx+8],eax
  1042.            mov    eax,[ScreenHeight]
  1043.            mov    [ecx+12],eax
  1044.  
  1045.            mov edi,[slot]
  1046.            imul edi,tss_step
  1047.            add edi,tss_data
  1048.            mov ecx,128/4
  1049.            xor eax, eax
  1050.            cld
  1051.            rep stosd
  1052. ;Add IO access table - bit array of permitted ports
  1053.            not eax
  1054.            mov ecx,2048
  1055.            rep stosd                 ; access to 4096*8=65536 ports
  1056.            sub edi, tss_step
  1057.  
  1058. ;set cr3 register in TSS of application
  1059.            mov ecx, [slot]
  1060.            shl ecx, 8
  1061.            mov eax,[SLOT_BASE+ecx+APPDATA.dir_table]
  1062.            mov [edi+TSS._cr3],eax
  1063.  
  1064.            mov esi,[params]
  1065.            mov eax, [esi+0x08]       ;app_eip
  1066.            mov [edi+TSS._eip],eax    ;set eip in TSS
  1067.            mov eax, [esi+0x0C]       ;app_esp
  1068.            mov [edi+TSS._esp],eax    ;set stack in TSS
  1069.            mov [edi+TSS._eflags],dword 0x1202
  1070.  
  1071.            mov [edi+TSS._cs],app_code  ;selector of code segment
  1072.            mov [edi+TSS._ss],app_data
  1073.            mov [edi+TSS._ds],app_data
  1074.            mov [edi+TSS._es],app_data
  1075.            mov [edi+TSS._fs],app_data
  1076.            mov [edi+TSS._gs],graph_data ;selector of graphic segment
  1077.            mov [edi+TSS._io],word 128
  1078.            mov [edi+TSS._ss0], os_data
  1079.            mov ebx, [pl0_stack]
  1080.            add ebx, 0x2000-512
  1081.            mov [edi+TSS._esp0],ebx
  1082.  
  1083.            mov ecx, edi    ;ecx - address of application TSS
  1084.            mov ebx,[slot]
  1085.            shl ebx,3
  1086. ;set TSS descriptor
  1087.            mov [ebx+gdts+tss0+0],word tss_step ;limit (size)
  1088.            mov [ebx+gdts+tss0+2],cx  ;part of offset
  1089.            shr ecx,16
  1090.            mov [ebx+gdts+tss0+4],cl  ;part of offset
  1091.            mov [ebx+gdts+tss0+7],ch  ;part of offset
  1092.            mov [ebx+gdts+tss0+5],word 01010000b*256+11101001b ;system flags
  1093.  
  1094. ;flush keyboard and buttons queue
  1095.            mov    [KEY_COUNT],byte 0
  1096.            mov    [BTN_COUNT],byte 0
  1097.  
  1098.            mov    edi,[slot]
  1099.            shl    edi,5
  1100.            add    edi,window_data
  1101.            mov    ebx,[slot]
  1102.            movzx  esi,word [WIN_STACK+ebx*2]
  1103.            lea    esi,[WIN_POS+esi*2]
  1104.            call   windowactivate        ;gui initialization
  1105.  
  1106.            mov    ebx,[slot]
  1107.            shl    ebx,5
  1108.            mov    [CURRENT_TASK+ebx+0xa],byte 0 ;set process state - running
  1109. ; set if debuggee
  1110.            mov eax, [flags]
  1111.            test byte [flags], 1
  1112.            jz   .no_debug
  1113.            mov  [CURRENT_TASK+ebx+0xa],byte 1 ;set process state - suspended
  1114.            mov  eax,[CURRENT_TASK]
  1115.            mov  [SLOT_BASE+ebx*8+0xac],eax ;set debugger PID - current
  1116. .no_debug:
  1117.            mov    esi,new_process_running
  1118.            call   sys_msg_board_str     ;output information about succefull startup
  1119.            ret
  1120. endp
  1121.  
  1122.  
  1123.  
  1124. include "debug.inc"
  1125.  
  1126. iglobal
  1127.     new_process_loading db 'K : New Process - loading',13,10,0
  1128.     new_process_running db 'K : New Process - done',13,10,0
  1129.     start_not_enough_memory db 'K : New Process - not enough memory',13,10,0
  1130. endg
  1131.  
  1132.