kolibrios/kernel/trunk/core/taskman.inc

1059 lines
27 KiB
PHP
Raw Normal View History

;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; ;;
;; Copyright (C) KolibriOS team 2004-2021. All rights reserved. ;;
;; Distributed under terms of the GNU General Public License. ;;
;; ;;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
$Revision$
GREEDY_KERNEL = 0
struct APP_HEADER_00_
banner dq ?
version dd ? ;+8
start dd ? ;+12
i_end dd ? ;+16
mem_size dd ? ;+20
i_param dd ? ;+24
ends
struct APP_HEADER_01_
banner dq ?
version dd ? ;+8
start dd ? ;+12
i_end dd ? ;+16
mem_size dd ? ;+20
stack_top dd ? ;+24
i_param dd ? ;+28
i_icon dd ? ;+32
ends
struct APP_HDR
cmdline rd 1 ;0x00
path rd 1 ;0x04
eip rd 1 ;0x08
esp rd 1 ;0x0C
_edata rd 1 ;0x10
_emem rd 1 ;0x14
img_base rd 1 ;0x18
img_size rd 1
filename_size rd 1
cmdline_size rd 1
path_string rd 1
ends
macro _clear_ op
{ mov ecx, op/4
xor eax, eax
cld
rep stosd
}
align 4
_strnlen:
mov edx, ecx
xor eax, eax
repne scasb
jne @F
inc ecx
@@:
mov eax, edx
sub eax, ecx
retn
fs_execute_from_sysdir:
xor ebx, ebx
fs_execute_from_sysdir_param:
stdcall kernel_alloc, maxPathLength
push eax ebx
mov esi, ebp
mov edi, eax
xor eax, eax
call getFullPath
pop ecx ebx
xor edx, edx
proc fs_execute
; edx = flags
; ecx -> cmdline
; ebx -> absolute file path
; eax = string length
locals
cmdline rd 1
flags rd 1
slot rd 1 ; index of new thread slot
slot_base rd 1 ; base address of it
; app header data
hdr_cmdline rd 1
hdr_path rd 1
hdr_eip rd 1
hdr_esp rd 1
hdr_edata rd 1
hdr_emem rd 1
file_base rd 1
file_size rd 1
filename_size rd 1
cmdline_size rd 1
path_string rd 1
endl
mov [flags], edx
mov [cmdline], ecx
mov [path_string], ebx
mov [filename_size], eax
mov esi, -ERROR_FILE_NOT_FOUND
test eax, eax
jz .err_file
stdcall load_file, ebx
test eax, eax
jz .err_file
mov [file_base], eax
mov [file_size], ebx
lea ebx, [hdr_cmdline]
call test_app_header ; fill our app header data locals with values from header of given program (if its correct)
mov esi, -0x1F
test eax, eax
jz .err_hdr
call lock_application_table
call alloc_thread_slot ; create a slot for new thread
mov esi, -0x20 ; too many processes
test eax, eax
jz .err_0
mov [slot], eax
shl eax, 8
lea edi, [SLOT_BASE+eax]
mov [slot_base], edi
; clean extended information about process
mov ecx, sizeof.APPDATA/4
xor eax, eax
cld
rep stosd
; write application name ( APPDATA.appname )
stdcall strrchr, [path_string], '/'
lea esi, [eax+1] ; -> name without path
mov ecx, 11
mov edi, [slot_base]
@@:
call utf8to16
call uni2ansi_char
cmp al, '.'
jz @f
test al, al
jz @f
stosb
loop @b
@@:
mov edi, [cmdline]
xor eax, eax
test edi, edi
jz @f
mov ecx, 65535
call _strnlen
cmp eax, 256
jb @f
; if cmdline length >= 256 then increase needed memory size by this length
lea ebx, [eax+1]
add [hdr_emem], ebx
@@:
mov [cmdline_size], eax
stdcall create_process, [hdr_emem] ; create a new process
mov esi, -30 ; no memory
test eax, eax
jz .err_hdr
; add new process to the list
mov ebx, [sys_proc+LHEAD.prev]
__list_add eax, ebx, sys_proc
; fill the structure fields:
mov ebx, [hdr_emem]
mov [eax+PROC.mem_used], ebx
; write that main thread of app belongs to new process
mov ebx, [slot_base]
mov [ebx+APPDATA.process], eax
; initialize the thread list of process: at this moment it consists only of one main thread
lea edx, [ebx+APPDATA.list]
lea ecx, [eax+PROC.thr_list]
list_add_tail edx, ecx
; allocate space and copy app header data locals and cmdline string there, put pointer to exec_params of new thread
mov eax, [cmdline_size]
add eax, sizeof.APP_HDR
stdcall kernel_alloc, eax
mov [ebx+APPDATA.exec_params], eax
mov edi, eax
lea esi, [hdr_cmdline]
mov ecx, sizeof.APP_HDR/4
rep movsd
mov ecx, [cmdline_size]
mov esi, [cmdline]
rep movsb
; set other parameters of application
lea eax, [hdr_cmdline]
stdcall set_app_params , [slot], eax, [flags]
mov eax, [process_number] ; return process number
call unlock_application_table
ret
.err_0:
call unlock_application_table
.err_hdr:
stdcall kernel_free, [file_base]
.err_file:
stdcall kernel_free, [path_string]
mov eax, esi
ret
endp
align 4
test_app_header:
virtual at eax
APP_HEADER_00 APP_HEADER_00_
end virtual
virtual at eax
APP_HEADER_01 APP_HEADER_01_
end virtual
cmp dword [eax], 'MENU'
jne .fail
cmp word [eax+4], 'ET'
jne .fail
cmp [eax+6], word '00'
jne .check_01_header
mov ecx, [APP_HEADER_00.start]
mov [ebx+APP_HDR.eip], ecx
mov edx, [APP_HEADER_00.mem_size]
mov [ebx+APP_HDR._emem], edx
shr edx, 1
sub edx, 0x10
mov [ebx+APP_HDR.esp], edx
mov ecx, [APP_HEADER_00.i_param]
mov [ebx+APP_HDR.cmdline], ecx
mov [ebx+APP_HDR.path], 0
mov edx, [APP_HEADER_00.i_end]
mov [ebx+APP_HDR._edata], edx
ret
.check_01_header:
cmp [eax+6], word '01'
je @f
cmp [eax+6], word '02'
jne .fail
@@:
mov ecx, [APP_HEADER_01.start]
mov [ebx+0x08], ecx
mov edx, [APP_HEADER_01.mem_size]
; \begin{diamond}[20.08.2006]
; sanity check (functions 19,58 load app_i_end bytes and that must
; fit in allocated memory to prevent kernel faults)
cmp edx, [APP_HEADER_01.i_end]
jb .fail
; \end{diamond}[20.08.2006]
mov [ebx+APP_HDR._emem], edx
mov ecx, [APP_HEADER_01.stack_top]
mov [ebx+APP_HDR.esp], ecx
mov edx, [APP_HEADER_01.i_param]
mov [ebx+APP_HDR.cmdline], edx
mov ecx, [APP_HEADER_01.i_icon]
mov [ebx+APP_HDR.path], ecx
mov edx, [APP_HEADER_01.i_end]
mov [ebx+APP_HDR._edata], edx
ret
.fail:
xor eax, eax
ret
align 4
alloc_thread_slot:
;input:
; none
;result:
; eax=[new_thread_slot]<>0 - ok
; 0 - failed.
;This function find least empty slot.
;It doesn't increase [TASK_COUNT]!
mov edx, thr_slot_map
pushfd
cli
.l1:
bsf eax, [edx]
jnz .found
add edx, 4
cmp edx, thr_slot_map+32
jb .l1
popfd
xor eax, eax
ret
.found:
btr [edx], eax
sub edx, thr_slot_map
lea eax, [eax+edx*8]
popfd
ret
align 4
proc create_process stdcall, app_size:dword
locals
process dd ?
app_tabs dd ?
endl
push ebx
push esi
push edi
xor eax, eax
mov [process], eax
mov eax, [app_size]
add eax, 0x3FFFFF
shr eax, 22
mov [app_tabs], eax
stdcall kernel_alloc, 0x2000
test eax, eax
jz .fail
mov [process], eax
lea edi, [eax+PROC.heap_lock]
mov ecx, (PROC.ht_free-PROC.heap_lock)/4
list_init eax
add eax, PROC.thr_list
list_init eax
xor eax, eax
cld
rep stosd
mov [edi], dword (PROC.pdt_0 - PROC.htab)/4 - 3
mov [edi+4], dword 3 ;reserve handles for stdin stdout and stderr
mov ecx, (PROC.pdt_0 - PROC.htab)/4
add edi, 8
inc eax
@@:
stosd
inc eax
cmp eax, ecx
jbe @B
mov eax, edi
call get_pg_addr
mov [edi-4096+PROC.pdt_0_phys], eax
mov ecx, (OS_BASE shr 20)/4
xor eax, eax
rep stosd
mov ecx, (OS_BASE shr 20)/4
mov esi, sys_proc+PROC.pdt_0+(OS_BASE shr 20)
rep movsd
mov eax, [edi-8192+PROC.pdt_0_phys]
or eax, PG_SWR
mov [edi-4096+(page_tabs shr 20)], eax
lea edx, [edi-4096]
mov esi, [app_tabs]
.alloc_page_dir:
call alloc_page
test eax, eax
jz .fail
or eax, PG_UWR
mov [edx], eax
mov edi, [tmp_task_ptab]
stdcall map_page, edi, eax, PG_SWR
mov ecx, 1024
xor eax, eax
rep stosd
add edx, 4
dec esi
jnz .alloc_page_dir
stdcall map_page, [tmp_task_ptab], 0, PG_UNMAP
mov eax, [process]
pop edi
pop esi
pop ebx
ret
.fail:
mov ecx, [process]
jcxz @F
call destroy_process
@@:
xor eax, eax
pop edi
pop esi
pop ebx
ret
endp
align 4
proc destroy_page_table stdcall, pg_tab:dword
push esi
mov esi, [pg_tab]
mov ecx, 1024
.free:
mov eax, [esi]
test eax, 1
jz .next
test eax, 2
jz .next
test eax, 1 shl 9
jnz .next ;skip shared pages
call free_page
.next:
add esi, 4
dec ecx
jnz .free
pop esi
ret
endp
align 4
destroy_process: ;fastcall ecx= ptr to process
lea eax, [ecx+PROC.thr_list]
cmp eax, [eax+LHEAD.next]
jne .exit
align 4
.internal:
push ecx
mov esi, ecx
list_del esi
mov esi, [esi+PROC.dlls_list_ptr]
call destroy_all_hdlls
mov esi, [esp]
add esi, PROC.pdt_0
mov edi, (0x80000000 shr 20)/4
.destroy:
mov eax, [esi]
test eax, 1
jz .next
and eax, not 0xFFF
stdcall map_page, [tmp_task_ptab], eax, PG_SWR
stdcall destroy_page_table, [tmp_task_ptab]
mov eax, [esi]
call free_page
.next:
add esi, 4
dec edi
jnz .destroy
call kernel_free ;ecx still in stack
stdcall map_page, [tmp_task_ptab], 0, PG_UNMAP
.exit:
ret
align 4
get_pid:
mov eax, [TASK_BASE]
mov eax, [eax+TASKDATA.pid]
ret
pid_to_slot:
;Input:
; eax - pid of process
;Output:
; eax - slot of process or 0 if process don't exists
;Search process by PID.
push ebx
push ecx
mov ebx, [TASK_COUNT]
shl ebx, BSF sizeof.TASKDATA ; multiply by size
; add 2*32 cause:
; [TASK_TABLE; TASK_TABLE + 32) isnt a task actually
; skip first process in the task table
mov ecx, 2*32
.loop:
;ecx = offset of current process info entry
;ebx = maximum permitted offset
; state 9 means "not used"
cmp byte [TASK_TABLE+ecx+TASKDATA.state], 9
jz .endloop ;skip empty slots
cmp [TASK_TABLE+ecx+TASKDATA.pid], eax;check PID
jz .pid_found
.endloop:
add ecx, 32
cmp ecx, ebx
jle .loop
pop ecx
pop ebx
xor eax, eax
ret
.pid_found:
shr ecx, BSF sizeof.TASKDATA ; divide by size
mov eax, ecx ;convert offset to index of slot
pop ecx
pop ebx
ret
align 4
proc read_process_memory
;Input:
; eax - process slot
; ecx - buffer address
; edx - buffer size
; esi - start address in other process
;Output:
; eax - number of bytes read.
locals
slot dd ?
buff dd ?
r_count dd ?
offset dd ?
tmp_r_cnt dd ?
endl
mov [slot], eax
mov [buff], ecx
and [r_count], 0
mov [tmp_r_cnt], edx
mov [offset], esi
pushad
.read_mem:
mov edx, [offset]
mov ebx, [tmp_r_cnt]
mov ecx, 0x400000
and edx, 0x3FFFFF
sub ecx, edx
cmp ecx, ebx
jbe @f
mov ecx, ebx
@@:
cmp ecx, 0x8000
jna @F
mov ecx, 0x8000
@@:
mov ebx, [offset]
push ecx
stdcall map_memEx, [proc_mem_map], \
[slot], ebx, ecx, PG_READ
pop ecx
mov esi, [offset]
and esi, 0xfff
sub eax, esi
jbe .ret
cmp ecx, eax
jbe @f
mov ecx, eax
mov [tmp_r_cnt], eax
@@:
add esi, [proc_mem_map]
mov edi, [buff]
mov edx, ecx
rep movsb
add [r_count], edx
add [offset], edx
sub [tmp_r_cnt], edx
jnz .read_mem
.ret:
popad
mov eax, [r_count]
ret
endp
align 4
proc write_process_memory
;Input:
; eax - process slot
; ecx - buffer address
; edx - buffer size
; esi - start address in other process
;Output:
; eax - number of bytes written
locals
slot dd ?
buff dd ?
w_count dd ?
offset dd ?
tmp_w_cnt dd ?
endl
mov [slot], eax
mov [buff], ecx
and [w_count], 0
mov [tmp_w_cnt], edx
mov [offset], esi
pushad
.read_mem:
mov edx, [offset]
mov ebx, [tmp_w_cnt]
mov ecx, 0x400000
and edx, 0x3FFFFF
sub ecx, edx
cmp ecx, ebx
jbe @f
mov ecx, ebx
@@:
cmp ecx, 0x8000
jna @F
mov ecx, 0x8000
@@:
mov ebx, [offset]
push ecx
stdcall map_memEx, [proc_mem_map], \
[slot], ebx, ecx, PG_SWR
pop ecx
mov edi, [offset]
and edi, 0xfff
sub eax, edi
jbe .ret
cmp ecx, eax
jbe @f
mov ecx, eax
mov [tmp_w_cnt], eax
@@:
add edi, [proc_mem_map]
mov esi, [buff]
mov edx, ecx
rep movsb
add [w_count], edx
add [offset], edx
sub [tmp_w_cnt], edx
jnz .read_mem
.ret:
popad
mov eax, [w_count]
ret
endp
;ebx = 1 - kernel thread
;ecx=thread entry point
;edx=thread stack pointer
;creation flags 0x01 - debugged
; 0x02 - kernel
align 4
proc new_sys_threads
locals
slot dd ?
flags dd ?
app_cmdline dd ? ;0x00
app_path dd ? ;0x04
app_eip dd ? ;0x08
app_esp dd ? ;0x0C
app_mem dd ? ;0x10
endl
shl ebx, 1
mov [flags], ebx
xor eax, eax
mov [app_eip], ecx
mov [app_cmdline], eax
mov [app_esp], edx
mov [app_path], eax
call lock_application_table
call alloc_thread_slot
test eax, eax
jz .failed
mov [slot], eax
mov esi, [current_slot]
mov ebx, esi ;ebx=esi - pointer to extended information about current thread
mov edi, eax
shl edi, 8
add edi, SLOT_BASE
mov edx, edi ;edx=edi - pointer to extended infomation about new thread
mov ecx, sizeof.APPDATA/4
xor eax, eax
cld
rep stosd ;clean extended information about new thread
mov esi, ebx
mov edi, edx
mov ecx, 11
rep movsb ;copy process name
mov eax, [ebx+APPDATA.tls_base]
test eax, eax
jz @F
push edx
stdcall user_alloc, 4096
pop edx
test eax, eax
jz .failed1;eax=0
@@:
mov [edx+APPDATA.tls_base], eax
mov eax, [ebx+APPDATA.process]
mov [edx+APPDATA.process], eax
lea ebx, [edx+APPDATA.list]
lea ecx, [eax+PROC.thr_list]
list_add_tail ebx, ecx ;add thread to process child's list
lea eax, [app_cmdline]
stdcall set_app_params , [slot], eax, [flags]
mov eax, [process_number] ;set result
call unlock_application_table
ret
.failed:
xor eax, eax
.failed1:
call unlock_application_table
dec eax ;-1
ret
endp
proc map_process_image stdcall, img_size:dword, file_base:dword, file_size:dword
mov edx, [img_size]
mov esi, [file_base]
mov ecx, [file_size]
add edx, 4095
add ecx, 4095
shr edx, 12 ; total pages
shr ecx, 12 ; image pages
mov edi, page_tabs
shr esi, 10
add esi, edi
.map_image:
lodsd
and eax, -4096
or eax, PG_UWR
stosd
dec edx
loop .map_image
test edx, edx
jz .done
.map_bss:
call alloc_page
test eax, eax
jz .fail
or eax, PG_UWR
stosd
dec edx
jnz .map_bss
mov edi, [file_size]
mov ecx, [img_size]
add edi, 4095
and edi, -4096
add ecx, 4095
and ecx, -4096
sub ecx, edi
shr ecx, 2
xor eax, eax
rep stosd
.done:
.fail:
ret
endp
align 4
common_app_entry:
mov ebp, [current_slot]
mov ebp, [ebp+APPDATA.exec_params]
test ebp, ebp
jz .exit
; APPDATA.exec_params have first thread only,
; so second and next threads don't get here (they jump to .exit)
stdcall map_process_image, [ebp+APP_HDR._emem],\
[ebp+APP_HDR.img_base], [ebp+APP_HDR.img_size]
mov esi, [ebp+APP_HDR.path_string]
mov edi, [ebp+APP_HDR.path]
mov ecx, [ebp+APP_HDR.filename_size]
cmp ecx, 1023
jc @f
mov ecx, 1022
@@:
push esi
test edi, edi
jz @f
stdcall is_region_userspace, edi, [ebp+APP_HDR.filename_size]
jz @f
mov al, '/'
stosb
rep movsb
mov byte [edi], 0
@@:
call kernel_free
mov edi, [ebp+APP_HDR.cmdline]
test edi, edi
jz .check_tls_header
lea esi, [ebp+sizeof.APP_HDR]
mov ecx, [ebp+APP_HDR.cmdline_size]
cmp ecx, 256
jb .copy_cmdline
mov edi, [ebp+APP_HDR._emem]
add edi, 4095
and edi, -4096
sub edi, ecx
dec edi
cmp word [6], '00'
jne @f
mov [APP_HEADER_00_.i_param], edi
jmp .copy_cmdline
@@:
mov [APP_HEADER_01_.i_param], edi
.copy_cmdline:
inc ecx ; keep in mind about 0 in the end
stdcall is_region_userspace, edi, ecx
jz .check_tls_header
dec ecx
rep movsb
mov byte [edi], 0
.check_tls_header:
cmp word [6], '02'
jne .try_load_dll ;.cleanup
call init_heap
stdcall user_alloc, 4096
mov edx, [current_slot]
mov [edx+APPDATA.tls_base], eax
mov [tls_data_l+2], ax
shr eax, 16
mov [tls_data_l+4], al
mov [tls_data_l+7], ah
mov dx, app_tls
mov fs, dx
; { Patch by Coldy, For DLL autoload
.try_load_dll:
; Test app header version
mov ecx, dword[ebp+APP_HDR.img_base]
cmp dword[ecx+8], 2
jne .cleanup
;if APP_HEADER.version = 2 => load lib/dll.obj & change eip to APP_STARTUP_THUNK
DEBUGF 1, 'K : App header version 2\n'
stdcall load_library, dll_lib_path, 0
cmp eax, 0
jne @f
; Something went wrong (TODO: Next 2 line is code copy after .cleanup)
stdcall free_kernel_space, [ebp+APP_HDR.img_base]
stdcall kernel_free, ebp
DEBUGF 1, 'K : DLL.OBJ not found! Terminate application!\n'
mov ebx, dll_error_msg
mov ebp, notifyapp
call fs_execute_from_sysdir_param
; Terminate process (TODO: Need jump to .cleanup after sys_end ?)
call sys_end
@@:
; Find APP_STARTUP_THUNK in DLL.OBJ
sub eax, 4
mov eax, [eax]
;.change_eip:
mov ecx, [current_slot]
mov ecx, [ecx+APPDATA.pl0_stack]
mov [ecx+REG_EIP], eax
; } End patch by Coldy, For DLL autoload
.cleanup:
stdcall free_kernel_space, [ebp+APP_HDR.img_base]
stdcall kernel_free, ebp
mov ebx, [current_slot]
cmp [ebx+APPDATA.debugger_slot], 0
je .exit
mov eax, [TASK_BASE]
mov [eax+TASKDATA.state], 1
call change_task
.exit:
popad
iretd
EFL_IF = 0x0200
EFL_IOPL1 = 0x1000
EFL_IOPL2 = 0x2000
EFL_IOPL3 = 0x3000
align 4
proc set_app_params stdcall,slot:dword, params:dword, flags:dword
locals
pl0_stack dd ?
endl
mov eax, [xsave_area_size]
add eax, RING0_STACK_SIZE
stdcall kernel_alloc, eax
mov [pl0_stack], eax
lea edi, [eax+RING0_STACK_SIZE]
mov eax, [slot]
mov ebx, eax
shl eax, 8
mov [eax+SLOT_BASE+APPDATA.fpu_state], edi
mov [eax+SLOT_BASE+APPDATA.exc_handler], 0
mov [eax+SLOT_BASE+APPDATA.except_mask], 0
mov [eax+SLOT_BASE+APPDATA.terminate_protection], 80000001h
;set default io permission map
mov ecx, [SLOT_BASE+sizeof.APPDATA+APPDATA.io_map]
mov [eax+SLOT_BASE+APPDATA.io_map], ecx
mov ecx, [SLOT_BASE+sizeof.APPDATA+APPDATA.io_map+4]
mov [eax+SLOT_BASE+APPDATA.io_map+4], ecx
mov esi, fpu_data
mov ecx, [xsave_area_size]
add ecx, 3
shr ecx, 2
rep movsd
cmp [TASK_COUNT], ebx
adc dword [TASK_COUNT], 0 ; update number of processes
shl ebx, 8
lea edx, [ebx+SLOT_BASE+APP_EV_OFFSET]
mov [SLOT_BASE+APPDATA.fd_ev+ebx], edx
mov [SLOT_BASE+APPDATA.bk_ev+ebx], edx
add edx, APP_OBJ_OFFSET-APP_EV_OFFSET
mov [SLOT_BASE+APPDATA.fd_obj+ebx], edx
mov [SLOT_BASE+APPDATA.bk_obj+ebx], edx
mov ecx, [def_cursor]
mov [SLOT_BASE+APPDATA.cursor+ebx], ecx
mov eax, [pl0_stack]
mov [SLOT_BASE+APPDATA.pl0_stack+ebx], eax
add eax, RING0_STACK_SIZE
mov [SLOT_BASE+APPDATA.saved_esp0+ebx], eax
push ebx
stdcall kernel_alloc, maxPathLength
pop ebx
mov esi, [current_slot]
mov esi, [esi+APPDATA.cur_dir]
mov ecx, maxPathLength/4
mov edi, eax
mov [ebx+SLOT_BASE+APPDATA.cur_dir], eax
rep movsd
shr ebx, 3
mov dword [CURRENT_TASK+ebx+0x10], 0
mov ebx, [slot]
mov eax, ebx
shl ebx, 5
lea ecx, [draw_data+ebx];ecx - pointer to draw data
; set window state to 'normal' (non-minimized/maximized/rolled-up) state
mov [ebx+window_data+WDATA.fl_wstate], WSTATE_NORMAL
mov [ebx+window_data+WDATA.fl_redraw], 1
add ebx, CURRENT_TASK ;ebx - pointer to information about process
mov [ebx+TASKDATA.wnd_number], al;set window number on screen = process slot
mov [ebx+TASKDATA.event_mask], dword 1+2+4;set default event flags (see 40 function)
inc dword [process_number]
mov eax, [process_number]
mov [ebx+4], eax ;set PID
;set draw data to full screen
xor eax, eax
mov [ecx+0], dword eax
mov [ecx+4], dword eax
mov eax, [screen_workarea.right]
mov [ecx+8], eax
mov eax, [screen_workarea.bottom]
mov [ecx+12], eax
mov ebx, [pl0_stack]
mov esi, [params]
lea ecx, [ebx+REG_EIP]
xor eax, eax
mov [ebx+REG_RET], dword common_app_entry
mov [ebx+REG_EDI], eax
mov [ebx+REG_ESI], eax
mov [ebx+REG_EBP], eax
mov [ebx+REG_ESP], ecx;ebx+REG_EIP
mov [ebx+REG_EBX], eax
mov [ebx+REG_EDX], eax
mov [ebx+REG_ECX], eax
mov [ebx+REG_EAX], eax
mov eax, [esi+APP_HDR.eip]
mov [ebx+REG_EIP], eax
mov [ebx+REG_CS], dword app_code
mov ecx, USER_PRIORITY
test byte [flags], 2
jz @F
mov [ebx+REG_CS], dword os_code ; kernel thread
mov ecx, MAX_PRIORITY
@@:
mov [ebx+REG_EFLAGS], dword EFL_IOPL1+EFL_IF
mov eax, [esi+APP_HDR.esp]
mov [ebx+REG_APP_ESP], eax
mov [ebx+REG_SS], dword app_data
lea edx, [ebx+REG_RET]
mov ebx, [slot]
shl ebx, 5
mov [ebx*8+SLOT_BASE+APPDATA.saved_esp], edx
xor edx, edx; process state - running
; set if debuggee
test byte [flags], 1
jz .no_debug
mov eax, [CURRENT_TASK]
mov [SLOT_BASE+ebx*8+APPDATA.debugger_slot], eax
.no_debug:
mov [CURRENT_TASK+ebx+TASKDATA.state], dl
lea edx, [SLOT_BASE+ebx*8]
call scheduler_add_thread
ret
endp
align 4
get_stack_base:
mov eax, [current_slot]
mov eax, [eax+APPDATA.pl0_stack]
ret
include "debug.inc"