Subversion Repositories Kolibri OS

Rev

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

  1. if ~defined newprocess_inc
  2. newprocess_inc_fix:
  3. newprocess_inc fix newprocess_inc_fix
  4. include "mem.inc"
  5. include "memmanag.inc"
  6. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  7. ;;Working with new types of processes.
  8. ;;Author: Khalyavin Andrey halyavin@land.ru
  9. ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
  10. iglobal
  11.     new_process_loading db 'K : New Process - loading',13,10,0
  12.     new_process_running db 'K : New Process - done',13,10,0
  13.     start_not_enough_memory db 'K : New Process - not enough memory',13,10,0
  14. endg
  15. ;-----------------------------------------------------------------------------
  16.  
  17. find_new_process_place:
  18. ;input:
  19. ;  none
  20. ;result:
  21. ;  eax=[new_process_place]<>0 - ok
  22. ;      0 - failed.
  23. ;This function find least empty slot.
  24. ;It doesn't increase [0x3004]!
  25.     mov    eax,0x3000+second_base_address
  26.     push   ebx
  27.     mov    ebx,[0x3004]
  28.     inc    ebx
  29.     shl    ebx,5
  30.     add    ebx,eax               ;ebx - address of process information for (last+1) slot
  31. .newprocessplace:
  32. ;eax = address of process information for current slot
  33.     cmp    eax,ebx
  34.     jz     .endnewprocessplace   ;empty slot after high boundary
  35.     add    eax,0x20
  36.     cmp    word [eax+TASKDATA.state],9      ;check process state, 9 means that process slot is empty
  37.     jnz    .newprocessplace
  38. .endnewprocessplace:
  39.     mov    ebx,eax
  40.     sub    eax,0x3000+second_base_address
  41.     shr    eax,5                 ;calculate slot index
  42.     cmp    eax,256
  43.     jge    .failed               ;it should be <256
  44.     mov    word [ebx+TASKDATA.state],9      ;set process state to 9 (for slot after hight boundary)
  45.     mov    [new_process_place],eax ;save process slot
  46.     pop    ebx
  47.     ret    
  48. .failed:
  49.     xor    eax,eax
  50.     pop    ebx
  51.     ret
  52. ;-----------------------------------------------------------------------------
  53. safe_sti:
  54.     cmp    byte [0xe000], 1
  55.     jne    @f
  56.     sti
  57.  @@:ret
  58.        
  59. ;-----------------------------------------------------------------------------    
  60. new_sys_threads:
  61. ;eax=1 - create thread
  62. ;   ebx=thread start
  63. ;   ecx=thread stack value
  64. ;result:
  65. ;   eax=pid
  66.     xor    edx,edx      ; flags=0
  67.     pushad
  68.    
  69.     cmp    eax,1
  70.     jnz    .ret                  ;other subfunctions
  71.     mov    esi,new_process_loading
  72.     call   sys_msg_board_str
  73. ;lock application_table_status mutex
  74. .table_status:    
  75.     cli
  76.     cmp    [application_table_status],0
  77.     je     .stf
  78.     sti
  79.     call   change_task
  80.     jmp    .table_status
  81. .stf:
  82.     call   set_application_table_status
  83. ;find free process slot
  84.  
  85.     call   find_new_process_place
  86.     test   eax,eax
  87.     jz     .failed
  88.    
  89. ;set parameters for thread
  90.     xor    eax,eax
  91.     mov    [app_i_param],eax
  92.     mov    [app_i_icon],eax
  93.     mov    [app_start],ebx
  94.     mov    [app_esp],ecx
  95.  
  96.     mov    esi,[0x3000]
  97.     shl    esi,8
  98.     add    esi,0x80000+APPDATA.app_name
  99.     mov    ebx,esi               ;ebx=esi - pointer to extended information about current thread
  100.    
  101.     mov    edi,[new_process_place]
  102.     shl    edi,8
  103.     add    edi,0x80000
  104.     lea    edx, [edi+APPDATA.app_name] ;edx=edi - pointer to extended infomation about new thread
  105.     mov    ecx,256/4
  106.     rep    stosd                 ;clean extended information about new thread
  107.     mov    edi,edx
  108.     mov    ecx,11
  109.     rep    movsb                 ;copy process name
  110.     mov    eax,[ebx+APPDATA.mem_size]
  111.     mov    [app_mem],eax         ;set memory size
  112.     mov    eax,[ebx+APPDATA.dir_table]
  113.     mov    dword [edx-APPDATA.app_name+APPDATA.dir_table],eax        ;copy page directory
  114. ;    mov    eax,[new_process_place]
  115. ;    mov    ebx,[0x3000]
  116. ;    call   addreference_app_cr3_table
  117.  
  118.     push   0                     ;no parameters
  119.     call   fs_execute.add_app_parameters ;start thread
  120.     mov    [esp+28],eax
  121.     popad
  122.     ret
  123.    
  124. .failed:
  125.     sti
  126.     popad
  127.     mov    eax,-1
  128.     ret    
  129. .ret:
  130.     popad
  131.     ret
  132. ;-----------------------------------------------------------------------------    
  133. new_mem_resize:
  134. ;input:
  135. ;  ebx - new size
  136. ;result:
  137. ;  [esp+36]:=0 - normal
  138. ;  [esp+36]:=1 - error
  139. ;This function set new application memory size.
  140.     mov    esi,ebx               ;save new size
  141.     add    ebx,4095
  142.     and    ebx,not (4096-1)      ;round up size
  143.     mov    ecx,[0x3000]
  144.     shl    ecx,8
  145.     mov    edx,[0x80000 + APPDATA.mem_size +ecx]    
  146.     add    edx,4095
  147.     and    edx,not (4096-1)      ;old size
  148.     mov    eax,[0x80000 + APPDATA.dir_table+ecx]
  149.     call   MEM_Get_Linear_Address
  150. ;eax - linear address of page directory    
  151.     call   MEM_Heap_Lock         ;guarantee that two threads willn't
  152.                                  ;change memory size simultaneously
  153.     cmp    ebx,edx
  154. ;    mov    esi,ebx               ;save new size
  155.     jg     .expand
  156.    
  157. .free:
  158.     sub    edx,ebx
  159.     jz     .unlock               ;do nothing
  160.     mov    ecx,edx
  161.     shr    ecx,12
  162.     add    ebx,std_application_base_address
  163.     call   mem_free_specified_region  ;free unnecessary pages
  164.     jmp    .unlock
  165.  
  166. .expand:
  167.     sub    ebx,edx
  168.     mov    ecx,ebx
  169.     shr    ecx,12
  170.     mov    ebx,edx
  171.     add    ebx,std_application_base_address
  172.     call   mem_alloc_specified_region ;alloc necessary pages
  173.     test   eax,eax
  174.     jz     .failed               ;not enough memory
  175.    
  176. .unlock:
  177.     mov    ebx,esi
  178.     mov    eax,[0x3000]
  179.     shl    eax,8
  180.     mov    [eax+0x80000 + APPDATA.mem_size],ebx     ;write new memory size
  181. ;search threads and update
  182. ;application memory size infomation    
  183.     mov    ecx,[eax+0x80000 + APPDATA.dir_table]
  184.     mov    eax,2
  185.    
  186. .search_threads:
  187. ;eax = current slot
  188. ;ebx = new memory size
  189. ;ecx = page directory
  190.     cmp    eax,[0x3004]
  191.     jg     .search_threads_end
  192.     mov    edx,eax
  193.     shl    edx,5
  194.     cmp    word [0x3000+edx+TASKDATA.state],9 ;if slot empty?
  195.     jz     .search_threads_next
  196.     shl    edx,3
  197.     cmp    [edx+0x80000+APPDATA.dir_table],ecx     ;if it is our thread?
  198.     jnz    .search_threads_next
  199.     mov    [edx+0x80000+APPDATA.mem_size],ebx     ;update memory size
  200. .search_threads_next:
  201.     inc    eax
  202.     jmp    .search_threads
  203. .search_threads_end:
  204.  
  205.     call   MEM_Heap_UnLock
  206.     mov    dword [esp+36],0
  207.     ret
  208.    
  209. .failed:
  210.     call   MEM_Heap_UnLock
  211.     mov    dword [esp+36],1
  212.     ret    
  213. ;-----------------------------------------------------------------------------
  214. pid_to_slot:
  215. ;Input:
  216. ;  eax - pid of process
  217. ;Output:
  218. ;  eax - slot of process or 0 if process don't exists
  219. ;Search process by PID.
  220.     push   ebx
  221.     push   ecx
  222.     mov    ebx,[0x3004]
  223.     shl    ebx,5
  224.     mov    ecx,2*32
  225.    
  226. .loop:
  227. ;ecx=offset of current process info entry
  228. ;ebx=maximum permitted offset
  229.     cmp    byte [second_base_address+0x3000+ecx+TASKDATA.state],9
  230.     jz     .endloop              ;skip empty slots
  231.     cmp    [second_base_address+0x3000+ecx+TASKDATA.pid],eax ;check PID
  232.     jz     .pid_found
  233. .endloop:
  234.     add    ecx,32
  235.     cmp    ecx,ebx
  236.     jle    .loop
  237.    
  238.     pop    ecx
  239.     pop    ebx
  240.     xor    eax,eax
  241.     ret
  242.    
  243. .pid_found:
  244.     shr    ecx,5
  245.     mov    eax,ecx               ;convert offset to index of slot
  246.     pop    ecx
  247.     pop    ebx
  248.     ret
  249. ;-----------------------------------------------------------------------------    
  250. is_new_process:
  251. ;Input:
  252. ;  eax - process slot
  253. ;Output:
  254. ;  eax=1 - it is new process
  255. ;  eax=0 - it is old process
  256. ;    shl   eax,5
  257. ;    mov   eax,[second_base_address+0x3000+eax+0x10]
  258. ;    cmp   eax,std_application_base_address  ;check base address of application
  259. ;    jz    .new_process
  260. ;    xor   eax,eax
  261. ;    ret
  262.    
  263. ;.new_process:
  264.     mov   eax,1
  265.     ret
  266. ;-----------------------------------------------------------------------------    
  267. write_process_memory:
  268. ;Input:
  269. ;  eax - process slot
  270. ;  ebx - buffer address
  271. ;  ecx - buffer size
  272. ;  edx - start address in other process
  273. ;Output:
  274. ;  eax - number of bytes written
  275.     pushad
  276.     shl  eax,8
  277.     mov  eax,[0x80000+eax+APPDATA.dir_table]
  278.     call MEM_Get_Linear_Address
  279.     mov  ebp,eax
  280. ;ebp=linear address of page directory of other process.    
  281.     add  edx,std_application_base_address  ;convert to linear address
  282.     test ecx,ecx
  283.     jle  .ret
  284.    
  285. .write_loop:
  286. ;ebx = current buffer address
  287. ;ecx>0 = current size
  288. ;edx = current address in other process
  289. ;ebp = linear address of page directory
  290.  
  291.     call MEM_Heap_Lock           ;cli
  292.     mov  esi,edx
  293.     shr  esi,22
  294.     mov  eax,[ebp+4*esi]         ;find page directory entry
  295.     and  eax,not (4096-1)        ;clear flags
  296.     test eax,eax
  297.     jz   .page_not_found
  298.     call MEM_Get_Linear_Address  ;calculate linear address of page table
  299.     test eax,eax
  300.     jz   .page_not_found
  301.     mov  esi,edx
  302.     shr  esi,12
  303.     and  esi,1023                
  304.     mov  eax,[eax+4*esi]         ;find page table entry
  305.     and  eax,not (4096-1)
  306.     test eax,eax
  307.     jz   .page_not_found
  308.     call MEM_Get_Linear_Address  ;calculate linear address of page
  309.     test eax,eax
  310.     jz   .page_not_found
  311.     mov  edi,eax
  312.     call MEM_Add_Reference_Linear;guarantee that page willn't disappear
  313.     call MEM_Heap_UnLock         ;sti
  314.    
  315.     mov  esi,edx
  316.     and  esi,4095
  317.     add  edi,esi                 ;add offset in page
  318. ;edi = linear address corresponding edx in other process
  319.     sub  esi,4096
  320.     neg  esi                     ;esi - number of remaining bytes in page
  321.     cmp  esi,ecx
  322.     jl   .min_ecx
  323.     mov  esi,ecx
  324. .min_ecx:                        ;esi=min(ecx,esi) - number of bytes to write
  325.     sub  ecx,esi
  326.     push ecx
  327.     mov  ecx,esi                 ;ecx - number of bytes to write
  328.     mov  esi,ebx                 ;esi - source, edi - destination
  329.     add  edx,ecx                 ;move pointer in address space of other process
  330.     push edi
  331.    
  332. ;move ecx bytes    
  333.     test ecx,3
  334.     jnz  .not_aligned
  335.     shr  ecx,2
  336.     rep  movsd
  337.     jmp  .next_iter
  338. .not_aligned:
  339.     rep  movsb
  340. .next_iter:
  341.  
  342.     pop  eax                    
  343.     and  eax,not (4096-1)        ;eax - linear address of current page
  344.     call MEM_Free_Page_Linear    ;free reference
  345.     mov  ebx,esi                 ;new pointer to buffer - movsb automaticaly advance it.
  346.     pop  ecx                     ;restore number of remaining bytes
  347.     test ecx,ecx
  348.     jnz  .write_loop
  349. .ret:    
  350.     popad
  351.     mov  eax,ecx
  352.     ret
  353.    
  354. .page_not_found:
  355.     call MEM_Heap_UnLock         ;error has appeared in critical region
  356.     sub  ecx,[esp+24]            ;[esp+24]<-->ecx
  357.     neg  ecx                     ;ecx=number_of_written_bytes
  358.     mov  [esp+28],ecx            ;[esp+28]<-->eax
  359.     popad
  360.     ret    
  361. ;-----------------------------------------------------------------------------    
  362. syscall_test:
  363. ;for testing memory manager from applications.
  364.     mov  edx,ecx
  365.     mov  ecx,ebx
  366.     call trans_address
  367.     mov  ebx,eax
  368.     mov  eax,[0x3000]
  369.     call read_process_memory
  370.     ret
  371. ;-----------------------------------------------------------------------------    
  372. read_process_memory:
  373. ;Input:
  374. ;  eax - process slot
  375. ;  ebx - buffer address
  376. ;  ecx - buffer size
  377. ;  edx - start address in other process
  378. ;Output:
  379. ;  eax - number of bytes read.
  380.     pushad
  381.     shl  eax,8
  382.     mov  eax,[0x80000+eax+APPDATA.dir_table]
  383.     call MEM_Get_Linear_Address
  384.     mov  ebp,eax
  385.     add  edx,std_application_base_address
  386. .read_loop:
  387. ;ebx = current buffer address
  388. ;ecx>0 = current size
  389. ;edx = current address in other process
  390. ;ebp = linear address of page directory
  391.  
  392.     call MEM_Heap_Lock           ;cli
  393.     mov  esi,edx
  394.     shr  esi,22
  395.     mov  eax,[ebp+4*esi]         ;find page directory entry
  396.     and  eax,not (4096-1)
  397.     test eax,eax
  398.     jz   .page_not_found
  399.     call MEM_Get_Linear_Address
  400.     test eax,eax
  401.     jz   .page_not_found
  402.     mov  esi,edx
  403.     shr  esi,12
  404.     and  esi,1023
  405.     mov  eax,[eax+4*esi]         ;find page table entry
  406.     and  eax,not (4096-1)
  407.     test eax,eax
  408.     jz   .page_not_found
  409.     call MEM_Get_Linear_Address  ;calculate linear address of page
  410.     test eax,eax
  411.     jz   .page_not_found
  412.     mov  esi,eax
  413.     call MEM_Add_Reference_Linear;guarantee that page willn't disappear
  414.     call MEM_Heap_UnLock         ;sti
  415.    
  416.     mov  edi,edx
  417.     and  edi,4095                
  418.     add  esi,edi                 ;add offset in page
  419. ;esi = linear address corresponding edx in other process
  420.     sub  edi,4096
  421.     neg  edi
  422.    
  423. ;edi=min(edi,ecx) - number of bytes to copy  
  424.     cmp  edi,ecx
  425.     jl   .min_ecx
  426.     mov  edi,ecx
  427. .min_ecx:
  428.  
  429.     sub  ecx,edi                 ;update size of remaining bytes
  430.     add  edx,edi                 ;update current pointer in other address space.
  431.     push ecx
  432.     mov  ecx,edi                 ;ecx - number of bytes to read
  433.     mov  edi,ebx                 ;esi - source, edi - destination
  434.     push esi
  435. ;move ecx bytes    
  436.     test ecx,3
  437.     jnz  .not_aligned
  438.     shr  ecx,2
  439.     rep  movsd
  440.     jmp  .next_iter
  441. .not_aligned:
  442.     rep  movsb
  443. .next_iter:
  444.     pop  eax
  445.     and  eax,not (4096-1)        ;eax - linear address of current page
  446.     call MEM_Free_Page_Linear    ;free reference
  447.     mov  ebx,edi                 ;new pointer to buffer - movsb automaticaly advance it.
  448.     pop  ecx                     ;restore number of remaining bytes
  449.     test ecx,ecx
  450.     jnz  .read_loop
  451.    
  452.     popad
  453.     mov  eax,ecx
  454.     ret
  455.    
  456. .page_not_found:
  457.     call MEM_Heap_UnLock         ;error has appeared in critical region
  458.     sub  ecx,[esp+24]            ;[esp+24]<-->ecx
  459.     neg  ecx                     ;ecx=number_of_read_bytes
  460.     mov  [esp+28],ecx            ;[esp+28]<-->eax
  461.     popad
  462.     ret
  463. ;-----------------------------------------------------------------------------
  464. check_region:
  465. ;input:
  466. ;  ebx - start of buffer
  467. ;  ecx - size of buffer
  468. ;result:
  469. ;  eax = 1 region lays in app memory
  470. ;  eax = 0 region don't lays in app memory
  471.     mov  eax,[0x3000]
  472.     jmp  check_process_region
  473. ;-----------------------------------------------------------------------------    
  474. check_process_region:
  475. ;input:
  476. ;  eax - slot
  477. ;  ebx - start of buffer
  478. ;  ecx - size of buffer
  479. ;result:
  480. ;  eax = 1 region lays in app memory
  481. ;  eax = 0 region don't lays in app memory
  482.     test ecx,ecx
  483.     jle  .ok
  484.     shl  eax,5
  485.     cmp  word [0x3000+eax+TASKDATA.state],0
  486.     jnz  .failed
  487.     shl  eax,3
  488.     mov  eax,[0x80000+eax+APPDATA.dir_table]
  489.     test eax,eax
  490.     jz   .failed
  491.     call MEM_Get_Linear_Address
  492.     push ebx
  493.     push ecx
  494.     push edx
  495.     mov  edx,ebx
  496.     and  edx,not (4096-1)
  497.     sub  ebx,edx
  498.     add  ecx,ebx
  499.     mov  ebx,edx
  500.     add  ecx,(4096-1)
  501.     and  ecx,not (4096-1)
  502. .loop:
  503. ;eax - linear address of page directory    
  504. ;ebx - current page
  505. ;ecx - current size
  506.     mov  edx,ebx
  507.     shr  edx,22
  508.     mov  edx,[eax+4*edx]
  509.     and  edx,not (4096-1)
  510.     test edx,edx
  511.     jz   .failed1
  512.     push eax
  513.     mov  eax,edx
  514.     call MEM_Get_Linear_Address
  515.     mov  edx,ebx
  516.     shr  edx,12
  517.     and  edx,(1024-1)
  518.     mov  eax,[eax+4*edx]
  519.     and  eax,not (4096-1)
  520.     test eax,eax
  521.     pop  eax
  522.     jz   .failed1
  523.     add  ebx,4096
  524.     sub  ecx,4096
  525.     jg   .loop
  526.     pop  edx
  527.     pop  ecx
  528.     pop  ebx
  529. .ok:
  530.     mov  eax,1
  531.     ret
  532.    
  533. .failed1:
  534.     pop  edx
  535.     pop  ecx
  536.     pop  ebx
  537. .failed:
  538.     xor  eax,eax
  539.     ret
  540. ;-----------------------------------------------------------------------------
  541. new_sys_ipc:
  542. ;input:
  543. ;  eax=1 - set ipc buffer area
  544. ;    ebx=address of buffer
  545. ;    ecx=size of buffer
  546. ;  eax=2 - send message
  547. ;    ebx=PID
  548. ;    ecx=address of message
  549. ;    edx=size of message
  550.     cmp  eax,1
  551.     jnz  .no_ipc_def
  552. ;set ipc buffer area    
  553.     mov  edi,[0x3000]
  554.     shl  edi,8
  555.     add  edi,0x80000
  556.     cli
  557.     mov  [edi+APPDATA.ipc_start],ebx          ;set fields in extended information area
  558.     mov  [edi+APPDATA.ipc_size],ecx
  559.     sti
  560.     mov  [esp+36],dword 0        ;success
  561.     ret
  562.        
  563. .no_ipc_def:
  564.     cmp  eax,2
  565.     jnz  .no_ipc_send
  566. ;send message    
  567.     cli
  568. ;obtain slot from PID    
  569.     mov  eax,ebx
  570.     call pid_to_slot
  571.     test eax,eax
  572.     jz   .no_pid
  573.     mov  ebp,eax
  574. ;ebp = slot of other process    
  575.     shl  eax,8
  576.     mov  edi,[eax+0x80000+APPDATA.ipc_start]  ;is ipc area defined?
  577.     test edi,edi
  578.     jz   .no_ipc_area
  579.     mov  esi,[eax+0x80000+APPDATA.ipc_size]  ;esi - size of buffer
  580.     push dword -1                ;temp variable for read_process_memory
  581.     mov  ebx,esp
  582.     push ecx
  583.     push edx
  584.     mov  ecx,4                   ;read 4 bytes
  585.     mov  eax,ebp
  586.     mov  edx,edi                 ;from beginning of buffer.
  587.     call read_process_memory
  588.     mov  eax,[esp+8]
  589.     test eax,eax
  590.     jnz  .ipc_blocked            ;if dword [buffer]<>0 - ipc blocked now
  591.     add  edx,4                   ;move to next 4 bytes
  592.     mov  eax,ebp
  593.     call read_process_memory     ;read size of occupied space in buffer
  594.     sub  esi,8
  595.     sub  esi,[esp]
  596.     sub  esi,[esp+8]             ;esi=(buffer size)-(occupied size)-(message size)-(header of message size)
  597.     js   .buffer_overflow        ;esi<0 - not enough memory in buffer
  598.     mov  esi,[esp+8]             ;previous offset
  599.     add  dword [esp+8],8
  600.     mov  edi,[esp]
  601.     add  [esp+8],edi             ;add (size of message)+(size of header of message) to [buffer+4]
  602.     mov  eax,ebp
  603.     call write_process_memory
  604.     add  edx,esi                
  605.     sub  edx,4                   ;move to beginning of place for our message
  606.     mov  eax,[second_base_address+0x3010]
  607.     mov  eax,[eax+TASKDATA.pid]           ;eax - our PID
  608.     mov  [esp+8],eax
  609.     mov  eax,ebp
  610.     call write_process_memory    ;write PID
  611.     mov  ebx,esp                 ;address of size of message
  612.     mov  eax,ebp
  613.     add  edx,4
  614.     call write_process_memory    ;write size of message
  615.     add  edx,4
  616.     pop  ecx                     ;ecx - size of message
  617.     pop  eax
  618.     call trans_address
  619.     mov  ebx,eax                 ;ebx - linear address of message
  620.     add  esp,4                   ;pop temporary variable
  621.     mov  eax,ebp
  622.     call write_process_memory    ;write message
  623.     sti
  624. ;awake other process    
  625.     shl  ebp,8
  626.     mov  eax,ebp
  627.     or   [eax+0x80000+APPDATA.event_mask],dword 0x40
  628.    
  629.     cmp  dword [check_idle_semaphore],20
  630.     jge  .ipc_no_cis
  631.     mov  dword [check_idle_semaphore],5
  632. .ipc_no_cis:
  633.     mov  dword [esp+36],0
  634.     ret
  635. .no_ipc_send:
  636.     mov  dword [esp+36],-1
  637.     ret
  638. .no_pid:
  639.     sti
  640.     mov  dword [esp+36],4
  641.     ret
  642. .no_ipc_area:
  643.     sti
  644.     mov  dword [esp+36],1
  645.     ret
  646. .ipc_blocked:
  647.     sti
  648.     add  esp,12
  649.     mov  dword [esp+36],2
  650.     ret
  651. .buffer_overflow:
  652.     sti
  653.     add  esp,12
  654.     mov  dword [esp+36],3
  655.     ret
  656. ;-----------------------------------------------------------------------------    
  657. trans_address:
  658. ;Input
  659. ;  eax - application address
  660. ;Output
  661. ;  eax - linear address for kernel      
  662.     add   eax,std_application_base_address
  663.     ret
  664. ;-----------------------------------------------------------------------------    
  665.  
  666. ; \begin{diamond}
  667.         include 'debug.inc'
  668.  
  669. fs_execute:
  670. ; ebx - cmdline
  671. ; edx - flags
  672. ; ebp - full filename
  673. ; [esp+4] = procedure DoRead, [esp+8] = filesize & [esp+12]... - arguments for it
  674.         pushad
  675. ; check filename length - with terminating NULL must be no more than 1024 symbols
  676.         mov     edi, ebp
  677.         mov     ecx, 1024
  678.         xor     eax, eax
  679.         repnz   scasb
  680.         jz      @f
  681.         popad
  682.         mov     eax, -ERROR_FILE_NOT_FOUND
  683.         ret
  684. @@:
  685.  
  686.         mov     esi, new_process_loading
  687.         call    sys_msg_board_str       ; write message to message board
  688.  
  689. ; lock application_table_status mutex
  690. .table_status:
  691.         cli
  692.         cmp     [application_table_status], 0
  693.         jz      .stf
  694.         sti
  695.         call    change_task
  696.         jmp     .table_status
  697. .stf:
  698.         call    set_application_table_status
  699.         push    ebx     ; save command line pointer for add_app_parameters
  700.  
  701.         call    find_new_process_place  ; find new process slot
  702.         call    safe_sti
  703.         test    eax, eax
  704.         mov     ecx, -0x20      ; too many processes
  705.         jz      .failed
  706.  
  707. ; write application name
  708.         push    edi
  709.         mov     ecx, edi
  710.         sub     ecx, ebp
  711.         mov     [appl_path], ebp
  712.         mov     [appl_path_size], ecx
  713.         dec     edi
  714.         std
  715.         mov     al, '/'
  716.         repnz   scasb
  717.         cld
  718.         jnz     @f
  719.         inc     edi
  720. @@:
  721.         inc     edi
  722. ; now edi points to name without path
  723.         mov     esi, edi
  724.         mov     ecx, 8  ; 8 chars for name
  725.         mov     edi, [new_process_place]
  726.         shl     edi, cl
  727.         add     edi, 0x80000+APPDATA.app_name
  728. .copy_process_name_loop:
  729.         lodsb
  730.         cmp     al, '.'
  731.         jz      .copy_process_name_done
  732.         test    al, al
  733.         jz      .copy_process_name_done
  734.         stosb
  735.         loop    .copy_process_name_loop
  736. .copy_process_name_done:
  737.         mov     al, ' '
  738.         rep     stosb
  739.         pop     eax
  740.         mov     cl, 3   ; 3 chars for extension
  741.         dec     esi
  742. @@:
  743.         dec     eax
  744.         cmp     eax, esi
  745.         jbe     .copy_process_ext_done
  746.         cmp     byte [eax], '.'
  747.         jnz     @b
  748.         lea     esi, [eax+1]
  749. .copy_process_ext_loop:
  750.         lodsb
  751.         test    al, al
  752.         jz      .copy_process_ext_done
  753.         stosb
  754.         loop    .copy_process_ext_loop
  755. .copy_process_ext_done:
  756.         mov     al, ' '
  757.         rep     stosb
  758.  
  759. ; read header
  760.         lea     eax, [esp+8+36]
  761.         mov     edi, 0x90000
  762.         call    dword [eax-4]
  763.         mov     ecx, eax
  764.         neg     ecx
  765.         jnz     .cleanfailed
  766. ; check menuet signature
  767.         mov     ecx, -0x1F
  768.         cmp     dword [0x90000], 'MENU'
  769.         jnz     .cleanfailed
  770.         cmp     word [0x90004], 'ET'
  771.         jnz     .cleanfailed
  772.         call    get_app_params
  773.         mov     ecx, -0x1F
  774.         jc      .cleanfailed
  775. ; sanity check - because we will load all file,
  776. ; file size must be not greater than memory size
  777.         mov     eax, [esp+8+36]
  778.         cmp     [app_mem], eax
  779.         jb      .cleanfailed
  780.  
  781.         mov     eax, [new_process_place]
  782.         inc     ecx     ; -0x1E = no memory
  783.         call    create_app_cr3_table
  784.         test    eax, eax
  785.         jz      .cleanfailed_mem
  786.  
  787.         call    MEM_Get_Linear_Address
  788.  
  789.         mov     ebx, std_application_base_address
  790.         mov     ecx, [app_mem]
  791.         add     ecx, 4095
  792.         shr     ecx, 12
  793.         mov     edx, eax        ; edx - linear address of page directory
  794.         call    mem_alloc_specified_region
  795.         mov     ecx, -0x1E      ; no memory
  796.         test    eax, eax
  797.         jz      .cleanfailed_mem1
  798.  
  799.         add     edx, std_application_base_address shr 20
  800.         mov     eax, [edx]
  801.         and     eax, not 4095
  802.         call    MEM_Get_Linear_Address
  803.         push    edx             ; save pointer to first page table
  804.         mov     edx, eax
  805. ; read file
  806. ; first block is already read to 0x90000
  807.         mov     eax, [edx]
  808.         and     eax, not 0xFFF
  809.         call    MEM_Get_Linear_Address
  810.         mov     esi, 0x90000
  811.         mov     edi, eax
  812.         mov     ecx, 512/4
  813.         rep     movsd
  814.         sub     edi, eax
  815. .loop1:
  816. ; [esp] = pointer to current page directory entry
  817. ; edx = pointer to current page table
  818. ; edi = offset in page
  819.         mov     eax, [edx]
  820.         and     eax, not 0xFFF
  821.         call    MEM_Get_Linear_Address
  822.         push    edi
  823.         add     edi, eax
  824.         lea     eax, [esp+8+36+8]
  825.         call    dword [eax-4]
  826.         pop     edi
  827.         test    eax, eax
  828.         jnz     .endloop1
  829.         add     edi, 512        ; new offset
  830.         cmp     edi, 4096
  831.         jb      .loop1
  832.         xor     edi, edi
  833.         add     edx, 4          ; go to next page
  834.         test    edx, 4096-1
  835.         jnz     .loop1
  836.         pop     eax
  837.         add     eax, 4          ; go to next directory entry
  838.         push    eax
  839.         mov     eax, [eax]
  840.         and     eax, not 0xFFF
  841.         call    MEM_Get_Linear_Address
  842.         mov     edx, eax
  843.         jmp     .loop1
  844. .endloop1:
  845.         pop     edx
  846.         cmp     eax, 6
  847.         jnz     .cleanfailed_mem2
  848.         call    .add_app_parameters
  849.         mov     [esp+28], eax
  850.         popad
  851.         ret
  852.  
  853. .cleanfailed_mem2:
  854. ; file read error; free all allocated mem
  855.         mov     ecx, eax
  856.         neg     ecx
  857.         mov     eax, [new_process_place]
  858.         call    dispose_app_cr3_table
  859.         jmp     .cleanfailed
  860. .cleanfailed_mem1:
  861. ; there is mem for directory entry, but there is no mem for pages
  862. ; so free directory entry
  863.         mov     eax, [new_process_place]
  864.         shl     eax, 8
  865.         mov     eax, [0x80000+eax+0xB8]
  866.         call    MEM_Free_Page
  867. .cleanfailed_mem:
  868. ; there is no mem for directory entry, display message
  869.         mov     esi, start_not_enough_memory
  870.         call    sys_msg_board_str
  871. .cleanfailed:
  872.         push    ecx
  873. ; clean process name, this avoid problems with @panel
  874.         mov     edi, [new_process_place]
  875.         shl     edi, 8
  876.         add     edi, 0x80000+APPDATA.app_name
  877.         mov     ecx, 11
  878.         mov     al, ' '
  879.         rep     stosb
  880.         pop     eax
  881. .failed:
  882.         pop     ebx
  883.         mov     [esp+28], eax
  884.         popad
  885.         mov     [application_table_status], 0
  886.         call    safe_sti
  887.         ret
  888. ; \end{diamond}
  889. .add_app_parameters:
  890. ;input:
  891. ;  [esp] - pointer to parameters
  892. ;  [esp+4]-[esp+36] pushad registers.
  893. ;result
  894. ;  eax - pid of new process
  895. ;        or zero if failed
  896.     cli
  897.     mov    ebx,[new_process_place]
  898.     cmp    ebx,[0x3004]
  899.     jle    .noinc
  900.     inc    dword [0x3004]        ;update number of processes
  901. .noinc:
  902.  
  903. ;   mov    ebx,[new_process_place]
  904. ;set 0x8c field of extended information about process
  905. ;(size of application memory)
  906.     shl    ebx,8
  907.     mov    eax,[app_mem]
  908.     mov    [second_base_address+0x80000+APPDATA.mem_size+ebx],eax            
  909. ;set 0x10 field of information about process
  910. ;(application base address)    
  911. ;    mov    ebx,[new_process_place]
  912. ;    shl    ebx,5
  913.     shr    ebx,3
  914.     mov    dword [second_base_address+0x3000+ebx+TASKDATA.mem_start],std_application_base_address
  915.  
  916. ;add command line parameters
  917. .add_command_line:
  918.     mov    edx,[app_i_param]
  919.     test   edx,edx
  920.     jz     .no_command_line      ;application don't need parameters
  921.     mov    eax,[esp+4]
  922.     test   eax,eax
  923.     jz     .no_command_line      ;no parameters specified
  924. ;calculate parameter length    
  925.     mov    esi,eax
  926.     xor    ecx,ecx
  927.     inc    ecx          ; include terminating null
  928. .command_line_len:
  929.     cmp    byte [esi],0
  930.     jz     .command_line_len_end
  931.     inc    esi
  932.     inc    ecx
  933.     cmp    ecx,256
  934.     jl     .command_line_len
  935.    
  936. .command_line_len_end:
  937. ;ecx - parameter length
  938. ;edx - address of parameters in new process address space
  939.     mov    ebx,eax               ;ebx - address of parameters in our address space
  940.     mov    eax,[new_process_place]
  941.     call   write_process_memory  ;copy parameters to new process address space
  942.    
  943. .no_command_line:
  944. ;******************************************************************
  945.     mov    edx,[app_i_icon]
  946.     test   edx,edx
  947.     jz     .no_command_line_1      ;application don't need path of file
  948.     mov    ebx,[appl_path]
  949.     mov    ecx,[appl_path_size]
  950.     mov    eax,[new_process_place]
  951.     call   write_process_memory  ;copy path of file to new process address space
  952. .no_command_line_1:
  953. ;******************************************************************
  954.     mov    ebx,[new_process_place]
  955.     mov    eax,ebx
  956.     shl    ebx,5
  957.     mov    [ebx+window_data+WDATA.fl_wstate],WSTATE_NORMAL
  958.     mov    [ebx+window_data+WDATA.fl_redraw],1
  959.     add    ebx,0x3000            ;ebx - pointer to information about process
  960.     mov    [ebx+TASKDATA.wnd_number],al  ;set window number on screen = process slot
  961.    
  962.     mov    [ebx+TASKDATA.event_mask],dword 1+2+4     ;set default event flags (see 40 function)
  963.    
  964.     inc    dword [process_number]
  965.     mov    eax,[process_number]
  966.     mov    [ebx+TASKDATA.pid],eax           ;set PID
  967.    
  968.     mov    ecx,ebx
  969.     add    ecx,draw_data-0x3000  ;ecx - pointer to draw data
  970. ;set draw data to full screen    
  971.     mov    [ecx+RECT.left],dword 0      
  972.     mov    [ecx+RECT.top],dword 0
  973.     mov    eax,[0xfe00]
  974.     mov    [ecx+RECT.right],eax
  975.     mov    eax,[0xfe04]
  976.     mov    [ecx+RECT.bottom],eax
  977. ;set cr3 register in TSS of application    
  978.     mov    ecx,[new_process_place]    
  979.     shl    ecx,8
  980.     mov    eax,[0x80000+APPDATA.dir_table+ecx]
  981.     add    eax,8+16              ;add flags
  982.     mov    [l.cr3],eax
  983.    
  984.     mov    eax,[app_start]
  985.     mov    [l.eip],eax           ;set eip in TSS
  986.     mov    eax,[app_esp]
  987.     mov    [l.esp],eax           ;set stack in TSS
  988.    
  989. ;gdt
  990.     ;mov    ebx,[new_process_place]
  991.     ;shl    ebx,3
  992.     mov    ax,app_code           ;ax - selector of code segment
  993.     ;add    ax,bx
  994.     mov    [l.cs],ax
  995.     mov    ax,app_data
  996.     ;add    ax,bx                 ;ax - selector of data segment
  997.     mov    [l.ss],ax
  998.     mov    [l.ds],ax
  999.     mov    [l.es],ax
  1000.     mov    [l.fs],ax
  1001.     mov    ax,graph_data         ;ax - selector of graphic segment
  1002.     mov    [l.gs],ax
  1003.     mov    [l.io],word 128
  1004.     mov    [l.eflags],dword 0x11202
  1005.     mov    [l.ss0],os_data
  1006.     mov    ebx,[new_process_place]
  1007.     shl    ebx,12
  1008.     add    ebx,sysint_stack_data+4096
  1009.     mov    [l.esp0],ebx
  1010.  
  1011. ;copy tss to it place
  1012.     mov    eax,tss_sceleton
  1013.     mov    ebx,[new_process_place]
  1014.     imul   ebx,tss_step
  1015.     add    ebx,tss_data          ;ebx - address of application TSS
  1016.     mov    ecx,120              
  1017.     call   memmove
  1018.    
  1019. ;Add IO access table - bit array of permitted ports
  1020.     or     eax,-1
  1021.     mov    edi,[new_process_place]
  1022.     imul   edi,tss_step
  1023.     add    edi,tss_data+128
  1024.     mov    ecx,2048
  1025.     cld
  1026.     rep    stosd                 ;full access to 2048*8=16384 ports
  1027.    
  1028.     mov    ecx,ebx               ;ecx - address of application TSS
  1029.     mov    edi,[new_process_place]
  1030.     shl    edi,3
  1031. ;set TSS descriptor
  1032.     mov    [edi+gdts+tss0+0],word tss_step ;limit (size)
  1033.     mov    [edi+gdts+tss0+2],cx  ;part of offset
  1034.     mov    eax,ecx
  1035.     shr    eax,16
  1036.     mov    [edi+gdts+tss0+4],al  ;part of offset
  1037.     mov    [edi+gdts+tss0+7],ah  ;part of offset
  1038.     mov    [edi+gdts+tss0+5],word 01010000b*256+11101001b ;system flags
  1039.      
  1040.  
  1041. ;flush keyboard and buttons queue
  1042.     mov    [0xf400],byte 0
  1043.     mov    [0xf500],byte 0
  1044.  
  1045.     mov    edi,[new_process_place]
  1046.     shl    edi,5
  1047.     add    edi,window_data
  1048.     mov    ebx,[new_process_place]
  1049.     movzx  esi,word [0xC000+ebx*2]
  1050.     lea    esi,[0xC400+esi*2]
  1051.     call   windowactivate        ;gui initialization
  1052.  
  1053.     mov    ebx,[new_process_place]
  1054.     shl    ebx,5
  1055. ; set if debuggee
  1056.         test    byte [esp+28], 1
  1057.         jz      .no_debug
  1058.         mov     [0x3000+ebx+TASKDATA.state], 1        ; set process state - suspended
  1059.         mov     eax, [0x3000]
  1060.         mov     [0x80000+ebx*8+APPDATA.debugger_slot], eax ;set debugger PID - current
  1061.         jmp     .debug
  1062. .no_debug:
  1063.         mov     [0x3000+ebx+TASKDATA.state], 0        ; set process state - running
  1064. .debug:
  1065.    
  1066.     mov    esi,new_process_running
  1067.     call   sys_msg_board_str     ;output information about succefull startup
  1068.    
  1069. ;    add    esp,4                 ;pop pointer to parameters
  1070. ;    popad
  1071.     mov    eax,[process_number]  ;set result
  1072.     mov    [application_table_status],0 ;unlock application_table_status mutex
  1073.     call   safe_sti
  1074.     ret    4
  1075.  
  1076. end if
  1077.