/kernel/trunk/core/dll.inc |
---|
0,0 → 1,616 |
; |
; This file is part of the Infinity sound AC97 driver. |
; (C) copyright Serge 2006 |
; email: infinity_sound@mail.ru |
; |
; This program is free software; you can redistribute it and/or modify |
; it under the terms of the GNU General Public License as published by |
; the Free Software Foundation; either version 2 of the License, or |
; (at your option) any later version. |
; |
; This program is distributed in the hope that it will be useful, |
; but WITHOUT ANY WARRANTY; without even the implied warranty of |
; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the |
; GNU General Public License for more details. |
align 4 |
proc attach_int_handler stdcall, irq:dword, handler:dword |
mov ebx, [irq] ;irq num |
test ebx, ebx |
jz .err |
mov eax, [handler] |
test eax, eax |
jz .err |
mov [irq_tab+ebx*4], eax |
stdcall enable_irq, [irq] |
ret |
.err: |
xor eax, eax |
ret |
endp |
align 4 |
proc detach_int_handler |
ret |
endp |
align 4 |
proc enable_irq stdcall, irq_line:dword |
mov ebx, [irq_line] |
mov edx, 0x21 |
cmp ebx, 8 |
jb @F |
mov edx, 0xA1 |
sub ebx,8 |
@@: |
in al,dx |
btr eax, ebx |
out dx, al |
ret |
endp |
align 16 |
;; proc irq_serv |
irq_serv: |
.irq_1: |
push eax |
mov eax, 1 |
jmp .main |
align 4 |
.irq_2: |
push eax |
mov eax, 2 |
jmp .main |
align 4 |
.irq_3: |
push eax |
mov eax, 3 |
jmp .main |
align 4 |
.irq_4: |
push eax |
mov eax, 4 |
jmp .main |
align 4 |
.irq_5: |
push eax |
mov eax, 5 |
jmp .main |
align 4 |
.irq_6: |
push eax |
mov eax, 6 |
jmp .main |
align 4 |
.irq_7: |
push eax |
mov eax, 7 |
jmp .main |
align 4 |
.irq_8: |
push eax |
mov eax, 8 |
jmp .main |
align 4 |
.irq_9: |
push eax |
mov eax, 9 |
jmp .main |
align 4 |
.irq_10: |
push eax |
mov eax, 10 |
jmp .main |
align 4 |
.irq_11: |
push eax |
mov eax, 11 |
jmp .main |
align 4 |
.irq_12: |
push eax |
mov eax, 12 |
jmp .main |
align 4 |
.irq_13: |
push eax |
mov eax, 13 |
jmp .main |
align 4 |
.irq_14: |
push eax |
mov eax, 14 |
jmp .main |
align 4 |
.irq_15: |
push eax |
mov eax, 15 |
jmp .main |
align 16 |
.main: |
save_ring3_context |
mov bx, os_data |
mov ds, bx |
mov es, bx |
mov ebx, [irq_tab+eax*4] |
test ebx, ebx |
jz .exit |
call ebx |
.exit: |
restore_ring3_context |
cmp eax, 8 |
mov al, 0x20 |
jb @f |
out 0xa0, al |
@@: |
out 0x20, al |
pop eax |
iret |
align 4 |
proc get_notify stdcall, p_ev:dword |
.wait: |
mov ebx,[CURRENT_TASK] |
shl ebx,8 |
test dword [ebx+PROC_BASE+0xA8],EVENT_NOTIFY |
jz @f |
and dword [ebx+PROC_BASE+0xA8], not EVENT_NOTIFY |
mov edi, [p_ev] |
mov dword [edi], EV_INTR |
mov eax, [ebx+PROC_BASE+APPDATA.event] |
mov dword [edi+4], eax |
ret |
@@: |
call change_task |
jmp .wait |
endp |
align 4 |
proc pci_read32 stdcall, bus:dword, devfn:dword, reg:dword |
xor eax, eax |
xor ebx, ebx |
mov ah, byte [bus] |
mov al, 6 |
mov bh, byte [devfn] |
mov bl, byte [reg] |
call pci_read_reg |
ret |
endp |
align 4 |
proc pci_read8 stdcall, bus:dword, devfn:dword, reg:dword |
xor eax, eax |
xor ebx, ebx |
mov ah, byte [bus] |
mov al, 4 |
mov bh, byte [devfn] |
mov bl, byte [reg] |
call pci_read_reg |
ret |
endp |
align 4 |
proc pci_write8 stdcall, bus:dword, devfn:dword, reg:dword, val:dword |
xor eax, eax |
xor ebx, ebx |
mov ah, byte [bus] |
mov al, 8 |
mov bh, byte [devfn] |
mov bl, byte [reg] |
mov ecx, [val] |
call pci_write_reg |
ret |
endp |
handle equ IOCTL.handle |
io_code equ IOCTL.io_code |
input equ IOCTL.input |
inp_size equ IOCTL.inp_size |
output equ IOCTL.output |
out_size equ IOCTL.out_size |
align 4 |
proc srv_handler stdcall, ioctl:dword |
mov esi, [ioctl] |
test esi, esi |
jz .err |
mov edi, [esi+handle] |
cmp [edi+SRV.magic], ' SRV' |
jne .fail |
cmp [edi+SRV.size], SRV_SIZE |
jne .fail |
stdcall [edi+SRV.srv_proc], esi |
ret |
.fail: |
xor eax, eax |
not eax |
mov [esi+output], eax |
mov [esi+out_size], 4 |
ret |
.err: |
xor eax, eax |
not eax |
ret |
endp |
align 4 |
proc srv_handlerEx stdcall, ioctl:dword |
mov esi, [ioctl] |
test esi, esi |
jz .err |
add esi, new_app_base |
mov edi, [esi+handle] |
cmp [edi+SRV.magic], ' SRV' |
jne .fail |
cmp [edi+SRV.size], SRV_SIZE |
jne .fail |
add [esi+input], new_app_base |
add [esi+output], new_app_base |
stdcall [edi+SRV.srv_proc], esi |
ret |
.fail: |
xor eax, eax |
not eax |
mov [esi+output], eax |
mov [esi+out_size], 4 |
ret |
.err: |
xor eax, eax |
not eax |
ret |
endp |
restore handle |
restore io_code |
restore input |
restore inp_size |
restore output |
restore out_size |
align 4 |
proc get_service stdcall, sz_name:dword |
locals |
srv_ptr dd ? |
counter dd ? |
endl |
mov eax, [sz_name] |
test eax, eax |
jz .fail |
mov [srv_ptr], srv_tab |
mov [counter], 16 |
@@: |
stdcall strncmp, [srv_ptr], [sz_name], 16 |
test eax, eax |
je .ok |
add [srv_ptr], SRV_SIZE |
dec [counter] |
jnz @B |
.not_load: |
stdcall find_service, [sz_name] |
test eax, eax |
jz .fail |
stdcall load_lib, eax |
test eax, eax |
jz .fail |
mov [srv_ptr], srv_tab |
mov [counter], 16 |
@@: |
stdcall strncmp, [srv_ptr], [sz_name], 16 |
test eax, eax |
je .ok |
add [srv_ptr], SRV_SIZE |
dec [counter] |
jnz @B |
.fail: |
xor eax, eax |
ret |
.ok: |
mov eax, [srv_ptr] |
ret |
endp |
align 4 |
proc find_service stdcall ,sz_name:dword |
mov eax, [sz_name] |
test eax, eax |
jz .fail |
mov esi, services |
@@: |
mov eax, [esi] |
test eax, eax |
jz .fail |
push esi |
stdcall strncmp, eax, [sz_name], 16 |
pop esi |
test eax, eax |
je .ok |
add esi, 8 |
jmp @B |
.ok: |
mov eax, [esi+4] |
ret |
.fail: |
xor eax, eax |
ret |
endp |
align 4 |
proc reg_service stdcall, sz_name:dword, handler:dword |
locals |
srv dd ? |
endl |
mov eax, [sz_name] |
test eax, eax |
jz .fail |
mov ebx, [handler] |
test ebx, ebx |
jz .fail |
call alloc_service |
test eax, eax |
jz .fail |
mov [srv], eax |
mov edi, eax |
mov esi, [sz_name] |
mov ecx, 16 |
rep movsb |
mov edi, eax |
mov [edi+SRV.magic], ' SRV' |
mov [edi+SRV.size], SRV_SIZE |
mov ebx, [handler] |
mov [edi+SRV.srv_proc], ebx |
mov eax, [srv] |
ret |
.fail: |
xor eax, eax |
ret |
endp |
align 4 |
proc get_proc stdcall, exp:dword, sz_name:dword |
mov edx, [exp] |
.next: |
mov eax, [edx] |
test eax, eax |
jz .end |
push edx |
stdcall strncmp, eax, [sz_name], 16 |
pop edx |
test eax, eax |
jz .ok |
add edx,8 |
jmp .next |
.ok: |
mov eax, [edx+4] |
.end: |
ret |
endp |
align 4 |
proc link_dll stdcall, exp:dword, imp:dword |
mov esi, [imp] |
.next: |
mov eax, [esi] |
test eax, eax |
jz .end |
push esi |
stdcall get_proc, [exp], eax |
pop esi |
test eax, eax |
jz @F |
mov [esi], eax |
@@: |
add esi, 4 |
jmp .next |
.end: |
ret |
endp |
align 4 |
proc get_coff_sym stdcall, pSym:dword,count:dword, sz_sym:dword |
@@: |
stdcall strncmp, [pSym], [sz_sym], 8 |
test eax,eax |
jz .ok |
add [pSym], 18 |
dec [count] |
jnz @b |
xor eax, eax |
ret |
.ok: |
mov ebx, [pSym] |
mov eax, [ebx+8] |
ret |
endp |
align 4 |
proc load_lib stdcall, name:dword |
locals |
lib dd ? |
base dd ? |
pSym dd ? |
endl |
mov eax, [name] |
mov ebx, 1 ;index of first block |
mov ecx, 32 ;number of blocks |
mov edx, TMP_BUFF ;temp area |
mov esi, 12 ;file name length |
call fileread ;read file from RD |
cmp eax,0 |
jne .err |
; mov eax, [TMP_BUFF+CFH.pSymTable] |
; add eax, TMP_BUFF |
; mov [pSym], eax |
; mov [TMP_BUFF+20+CFS.VirtualAddress], eax |
stdcall kernel_alloc, [TMP_BUFF+20+CFS.SizeOfRawData] |
mov [base], eax |
test eax, eax |
jnz @f |
@@: |
mov [TMP_BUFF+20+CFS.VirtualAddress], eax |
mov ebx, [TMP_BUFF+CFH.pSymTable] |
add ebx, TMP_BUFF |
mov [pSym], ebx |
stdcall LinkSection, TMP_BUFF, TMP_BUFF+20, ebx |
mov edi, [base] |
test edi, edi |
jnz @f |
@@: |
mov esi, [TMP_BUFF+20+CFS.PtrRawData] |
add esi, TMP_BUFF |
mov ecx, [TMP_BUFF+20+CFS.SizeOfRawData] |
rep movsb |
call alloc_dll |
test eax, eax |
jnz @f |
@@: |
mov [lib], eax |
mov edi, eax |
mov esi, [name] |
mov ecx, 16 |
rep movsb |
stdcall get_coff_sym,[pSym],[TMP_BUFF+CFH.nSymbols],szSTART |
mov edi, [lib] |
add eax, [base] |
mov [edi+LIB.lib_start], eax |
mov ebx, [base] |
mov [edi+LIB.lib_base], ebx |
stdcall get_coff_sym,[pSym],[TMP_BUFF+CFH.nSymbols], szEXPORTS |
mov edi, [lib] |
add eax, [base] |
mov [edi+LIB.export], eax |
stdcall get_coff_sym,[pSym],[TMP_BUFF+CFH.nSymbols], szIMPORTS |
mov edi, [lib] |
add eax, [base] |
mov [edi+LIB.import], eax |
stdcall link_dll, kernel_export, eax |
mov edi, [lib] |
call [edi+LIB.lib_start] |
mov eax, [lib] |
ret |
.err: |
xor eax, eax |
ret |
endp |
align 4 |
proc LinkSection stdcall, pCoff:dword, pSec:dword, pSym:dword |
locals |
pCode dd ? |
endl |
mov esi, [pSec] |
mov eax, [esi+CFS.PtrRawData] |
add eax, [pCoff] |
mov [pCode], eax |
mov edi, [esi+CFS.PtrReloc] |
add edi, [pCoff] |
movzx edx, [esi+CFS.NumReloc] |
mov eax, edx |
lea edx, [edx+edx*8] |
add edx, eax |
add edx, edi |
.l_0: |
cmp edi, edx |
jae .exit |
mov ebx, [edi+CRELOC.SymIndex] |
add ebx,ebx |
lea ebx,[ebx+ebx*8] |
add ebx, [pSym] |
mov ecx, [ebx+CSYM.Value] |
add ecx, [esi+CFS.VirtualAddress] |
mov eax, [edi+CRELOC.VirtualAddress] |
add eax, [pCode] |
add [eax], ecx |
add edi, 10 |
jmp .l_0 |
.exit: |
ret |
endp |
proc get_curr_task |
mov eax,[CURRENT_TASK] |
shl eax, 8 |
ret |
endp |
drv_sound db 'UNISOUNDOBJ', 0 |
drv_infinity db 'INFINITYOBJ', 0 |
szSound db 'SOUND',0 |
szInfinity db 'INFINITY',0 |
szSTART db 'START',0 |
szEXPORTS db 'EXPORTS',0 |
szIMPORTS db 'IMPORTS',0 |
align 16 |
services: |
dd szSound, drv_sound |
dd szInfinity, drv_infinity |
dd 0 |
/kernel/trunk/core/except.inc |
---|
0,0 → 1,64 |
reg_eip equ ebp+4 |
reg_cs equ ebp+8 |
reg_eflags equ ebp+12 |
reg_esp equ ebp+16 |
reg_ss equ ebp+20 |
fpu_ctrl equ ebp-28 |
align 4 |
except_16: |
push ebp |
mov ebp, esp |
sub esp, 28 |
push eax |
push ebx |
push ecx |
push edx |
mov ebx, [ss:CURRENT_TASK] |
shl ebx, 8 |
mov eax, [ss:ebx+PROC_BASE+APPDATA.fpu_handler] |
test eax, eax |
jz .default |
mov ecx, [reg_eip] |
mov edx, [reg_esp] |
sub edx, 4 |
mov [ss:edx+new_app_base], ecx |
mov [reg_esp], edx |
mov dword [reg_eip], eax |
pop edx |
pop ecx |
pop ebx |
pop eax |
leave |
iretd |
.default: |
fnstenv [fpu_ctrl] |
fnclex |
or word [fpu_ctrl], 0111111b |
fldenv [fpu_ctrl] |
pop edx |
pop ecx |
pop ebx |
pop eax |
leave |
iretd |
restore reg_eip |
restore reg_cs |
restore reg_eflags |
restore reg_esp |
restore reg_ss |
restore fpu_ctrl |
/kernel/trunk/core/exports.inc |
---|
0,0 → 1,45 |
iglobal |
align 16 |
kernel_export: |
dd szAttachIntHandler, attach_int_handler |
dd szSysMsgBoardStr , sys_msg_board_str |
dd szPciApi , pci_api |
dd szPciRead32 , pci_read32 |
dd szPciRead8 , pci_read8 |
dd szPciWrite8 , pci_write8 |
dd szAllocKernelSpace, alloc_kernel_space |
dd szMapPage , map_page |
dd szRegService , reg_service |
dd szKernelAlloc , kernel_alloc |
dd szKernelFree , kernel_free |
dd szGetPgAddr , get_pg_addr |
dd szGetCurrentTask , get_curr_task |
dd szGetService , get_service |
dd szServiceHandler , srv_handler |
dd szFpuSave , fpu_save |
dd szFpuRestore , fpu_restore |
dd 0 |
szKernel db 'KERNEL', 0 |
szAttachIntHandler db 'AttachIntHandler',0 |
szSysMsgBoardStr db 'SysMsgBoardStr', 0 |
szPciApi db 'PciApi', 0 |
szPciRead32 db 'PciRead32', 0 |
szPciRead8 db 'PciRead8', 0 |
szPciWrite8 db 'PciWrite8',0 |
szAllocKernelSpace db 'AllocKernelSpace',0 |
szMapPage db 'MapPage',0 |
szRegService db 'RegService',0 |
szKernelAlloc db 'KernelAlloc',0 |
szKernelFree db 'KernelFree',0 |
szGetPgAddr db 'GetPgAddr',0 |
szGetCurrentTask db 'GetCurrentTask ',0 |
szGetService db 'GetService',0 |
szServiceHandler db 'ServiceHandler',0 |
szFpuSave db 'FpuSave',0 |
szFpuRestore db 'FpuRestore',0 |
endg |
/kernel/trunk/core/heap.inc |
---|
0,0 → 1,1117 |
HEAP_BASE equ 0x01000000 |
;HEAP_SIZE equ 0x01000000 |
struc MEM_BLOCK |
{ .next_block dd ? |
.prev_block dd ? ;+4 |
.list_next dd ? ;+8 |
.list_prev dd ? ;+12 |
.base dd ? ;+16 |
.size dd ? ;+20 |
.flags dd ? ;+24 |
.handle dd ? ;+28 |
} |
FREE_BLOCK equ 4 |
USED_BLOCK equ 8 |
virtual at 0 |
MEM_BLOCK MEM_BLOCK |
end virtual |
MEM_BLOCK_SIZE equ 8*4 |
block_next equ MEM_BLOCK.next_block |
block_prev equ MEM_BLOCK.prev_block |
list_next equ MEM_BLOCK.list_next |
list_prev equ MEM_BLOCK.list_prev |
block_base equ MEM_BLOCK.base |
block_size equ MEM_BLOCK.size |
block_flags equ MEM_BLOCK.flags |
macro calc_index op |
{ shr op, 12 |
dec op |
cmp op, 63 |
jna @f |
mov op, 63 |
@@: |
} |
macro remove_from_list op |
{ mov edx, [op+list_next] |
mov ecx, [op+list_prev] |
test edx, edx |
jz @f |
mov [edx+list_prev], ecx |
@@: |
test ecx, ecx |
jz @f |
mov [ecx+list_next], edx |
@@: |
mov [op+list_next],0 |
mov [op+list_prev],0 |
} |
macro remove_from_free op |
{ |
remove_from_list op |
mov eax, [op+block_size] |
calc_index eax |
cmp [mem_block_list+eax*4], op |
jne @f |
mov [mem_block_list+eax*4], edx |
@@: |
cmp [mem_block_list+eax*4], 0 |
jne @f |
btr [mem_block_mask], eax |
@@: |
} |
macro remove_from_used op |
{ |
remove_from_list op |
cmp [mem_used_list], op |
jne @f |
mov [mem_used_list], edx |
@@: |
} |
align 4 |
proc init_kernel_heap |
mov ecx, 64/4 |
mov edi, mem_block_list |
xor eax, eax |
cld |
rep stosd |
mov ecx, 512/4 |
mov edi, mem_block_map |
not eax |
rep stosd |
mov [mem_block_start], mem_block_map |
mov [mem_block_end], mem_block_map+512 |
mov [mem_block_arr], HEAP_BASE |
stdcall alloc_pages, dword 32 |
mov ecx, 32 |
mov edx, eax |
mov edi, HEAP_BASE |
.l1: |
stdcall map_page,edi,edx,PG_SW |
add edi, 0x1000 |
add edx, 0x1000 |
dec ecx |
jnz .l1 |
mov edi, HEAP_BASE |
mov ebx, edi |
add ebx, MEM_BLOCK_SIZE |
xor eax, eax |
mov [edi+block_next], ebx |
mov [edi+block_prev], eax |
mov [edi+list_next], eax |
mov [edi+list_prev], eax |
mov [edi+block_base], HEAP_BASE |
mov [edi+block_size], 4096*MEM_BLOCK_SIZE |
mov [edi+block_flags], USED_BLOCK |
mov [ebx+block_next], eax |
mov [ebx+block_prev], eax |
mov [ebx+list_next], eax |
mov [ebx+block_base], HEAP_BASE+4096*MEM_BLOCK_SIZE |
mov ecx, [MEM_AMOUNT] |
sub ecx, 0x00C00000 + 4096*MEM_BLOCK_SIZE |
mov [ebx+block_size], ecx |
mov [ebx+block_flags], FREE_BLOCK |
mov [mem_block_mask], eax |
mov [mem_block_mask+4],0x80000000 |
mov [mem_used_list], eax |
mov [mem_block_list+63*4], ebx |
mov byte [mem_block_map], 0xFC |
ret |
endp |
align 4 |
proc get_block stdcall, index:dword |
mov eax, 63 |
mov ecx, [index] |
cmp ecx, eax |
jna @f |
;cmova ecx, eax |
mov ecx, eax |
@@: |
xor esi, esi |
xor ebx, ebx |
xor edx, edx |
not edx |
cmp ecx, 32 |
jb .bit_test |
sub ecx, 32 |
add ebx, 32 |
add esi, 4 |
.bit_test: |
shl edx, cl |
and edx, [mem_block_mask+esi] |
jz .high_mask |
bsf eax, edx |
add ebx, eax |
mov eax, [mem_block_list+ebx*4] |
ret |
.high_mask: |
add esi, 4 |
add ebx, 32 |
test esi, 0xFFFFFFF8 |
jnz .big_error |
mov edx, [mem_block_mask+esi] |
and edx, edx |
jz .high_mask |
bsf eax, edx |
add ebx, eax |
mov eax, [mem_block_list+ebx*4] |
ret |
.big_error: |
xor eax, eax |
ret |
endp |
align 4 |
proc alloc_mem_block |
pushfd |
cli |
mov ebx, [mem_block_start] |
mov ecx, [mem_block_end] |
.l1: |
bsf eax,[ebx]; |
jnz found |
add ebx,4 |
cmp ebx, ecx |
jb .l1 |
popfd |
xor eax,eax |
ret |
found: |
btr [ebx], eax |
mov [mem_block_start],ebx |
sub ebx, mem_block_map |
shl ebx, 3 |
add eax,ebx |
shl eax, 5 |
add eax, [mem_block_arr] |
popfd |
ret |
endp |
proc free_mem_block |
pushfd |
cli |
sub eax, [mem_block_arr] |
shr eax, 5 |
mov ebx, mem_block_map |
bts [ebx], eax |
shr eax, 3 |
and eax, not 3 |
add eax, ebx |
cmp [mem_block_start], eax |
ja @f |
popfd |
ret |
@@: |
mov [mem_block_start], eax |
popfd |
ret |
.err: |
xor eax, eax |
popfd |
ret |
endp |
align 4 |
proc alloc_kernel_space stdcall, size:dword |
local block_ind:DWORD |
pushfd |
cli |
mov eax, [size] |
add eax, 0xFFF |
and eax, 0xFFFFF000; |
mov [size], eax |
shr eax, 12 |
sub eax, 1 |
mov [block_ind], eax |
stdcall get_block, eax |
and eax, eax |
jz .error |
mov edi, eax ;edi - pBlock |
cmp [edi+block_flags], FREE_BLOCK |
jne .error |
mov [block_ind], ebx ;index of allocated block |
mov eax, [edi+block_size] |
cmp eax, [size] |
je .m_eq_size |
call alloc_mem_block |
and eax, eax |
jz .error |
mov esi, eax ;esi - splitted block |
mov [esi+block_next], edi |
mov eax, [edi+block_prev] |
mov [esi+block_prev], eax |
mov [edi+block_prev], esi |
mov [esi+list_next], 0 |
mov [esi+list_prev], 0 |
and eax, eax |
jz @f |
mov [eax+block_next], esi |
@@: |
mov ebx, [edi+block_base] |
mov [esi+block_base], ebx |
mov edx, [size] |
mov [esi+block_size], edx |
add [edi+block_base], edx |
sub [edi+block_size], edx |
mov eax, [edi+block_size] |
shr eax, 12 |
sub eax, 1 |
cmp eax, 63 |
jna @f |
mov eax, 63 |
@@: |
cmp eax, [block_ind] |
je .m_eq_ind |
mov ebx, [edi+list_next] |
test ebx, ebx |
jz @f |
mov [ebx+list_prev], edi |
@@: |
mov ecx, [block_ind] |
mov [mem_block_list+ecx*4], ebx |
and ebx, ebx |
jnz @f |
btr [mem_block_mask], ecx |
@@: |
mov edx, [mem_block_list+eax*4] |
mov [edi+list_next], edx |
test edx, edx |
jz @f |
mov [edx+list_prev], edi |
@@: |
mov [mem_block_list+eax*4], edi |
bts [mem_block_mask], eax |
.m_eq_ind: |
mov ebx, [mem_used_list] |
mov [esi+list_next], ebx |
test ebx, ebx |
jz @f |
mov [ebx+list_prev], esi |
@@: |
mov [esi+block_flags], USED_BLOCK |
mov [mem_used_list], esi |
mov eax, [esi+block_base] |
popfd |
ret |
.m_eq_size: |
remove_from_list edi |
mov [mem_block_list+ecx*4], edx |
and edx, edx |
jnz @f |
mov ecx, [block_ind] |
btr [mem_block_mask], ecx |
@@: |
mov ebx, [mem_used_list] |
mov [edi+list_next], ebx |
test ebx, ebx |
jnz @f |
mov [ebx+list_prev], edi |
@@: |
mov [mem_used_list], edi |
mov [edi+block_flags], USED_BLOCK |
mov eax, [edi+block_base] |
popfd |
ret |
.error: |
xor eax, eax |
popfd |
ret |
endp |
align 4 |
proc free_kernel_space stdcall, base:dword |
mov eax, [base] |
mov esi, [mem_used_list] |
@@: |
test esi, esi |
jz .fail |
cmp [esi+block_base], eax |
je .found |
mov esi, [esi+list_next] |
jmp @b |
.found: |
cmp [esi+block_flags], USED_BLOCK |
jne .fail |
mov edi, [esi+block_next] |
test edi, edi |
jz .prev |
cmp [edi+block_flags], FREE_BLOCK |
jne .prev |
remove_from_free edi |
mov edx, [edi+block_next] |
mov [esi+block_next], edx |
test edx, edx |
jz @f |
mov [edx+block_prev], esi |
@@: |
mov ecx, [edi+block_size] |
add [esi+block_size], ecx |
mov eax, edi |
call free_mem_block |
.prev: |
mov edi, [esi+block_prev] |
test edi, edi |
jz .insert |
cmp [edi+block_flags], FREE_BLOCK |
jne .insert |
remove_from_used esi |
mov edx, [esi+block_next] |
mov [edi+block_next], edx |
test edx, edx |
jz @f |
mov [edx+block_prev], edi |
@@: |
mov eax, esi |
call free_mem_block |
mov ecx, [edi+block_size] |
mov eax, [esi+block_size] |
add eax, ecx |
mov [edi+block_size], eax |
calc_index eax |
calc_index ecx |
cmp eax, ecx |
je .m_eq |
push ecx |
remove_from_list edi |
pop ecx |
cmp [mem_block_list+ecx*4], edi |
jne @f |
mov [mem_block_list+ecx*4], edx |
@@: |
cmp [mem_block_list+ecx*4], 0 |
jne @f |
btr [mem_block_mask], ecx |
@@: |
mov esi, [mem_block_list+eax*4] |
mov [mem_block_list+eax*4], edi |
mov [edi+list_next], esi |
test esi, esi |
jz @f |
mov [esi+list_prev], edi |
@@: |
bts [mem_block_mask], eax |
.m_eq: |
xor eax, eax |
not eax |
ret |
.insert: |
remove_from_used esi |
mov eax, [esi+block_size] |
calc_index eax |
mov edi, [mem_block_list+eax*4] |
mov [mem_block_list+eax*4], esi |
mov [esi+list_next], edi |
test edi, edi |
jz @f |
mov [edi+list_prev], esi |
@@: |
bts [mem_block_mask], eax |
mov [esi+block_flags],FREE_BLOCK |
xor eax, eax |
not eax |
ret |
.fail: |
xor eax, eax |
ret |
endp |
align 4 |
proc kernel_alloc stdcall, size:dword |
locals |
lin_addr dd ? |
pages_count dd ? |
endl |
mov eax, [size] |
add eax, 0xFFF |
and eax, 0xFFFFF000; |
mov [size], eax |
and eax, eax |
jz .error |
mov ebx, eax |
shr ebx, 12 |
mov [pages_count], ebx |
stdcall alloc_kernel_space, eax |
and eax, eax |
jz .error |
mov [lin_addr], eax |
mov ecx, [pages_count] |
mov edx, eax |
mov ebx, ecx |
shr ecx, 3 |
jz .next |
and ebx, not 7 |
push ebx |
stdcall alloc_pages, ebx |
pop ecx ; yes ecx!!! |
and eax, eax |
jz .error |
mov edi, eax |
mov edx, [lin_addr] |
@@: |
stdcall map_page,edx,edi,dword PG_SW |
add edx, 0x1000 |
add edi, 0x1000 |
dec ecx |
jnz @B |
.next: |
mov ecx, [pages_count] |
and ecx, 7 |
jz .end |
@@: push ecx |
call alloc_page |
pop ecx |
test eax, eax |
jz .error |
stdcall map_page,edx,eax,dword PG_SW |
add edx, 0x1000 |
dec ecx |
jnz @B |
.end: |
mov eax, [lin_addr] |
ret |
.error: |
xor eax, eax |
ret |
endp |
align 4 |
proc kernel_free stdcall, base:dword |
locals |
size dd ? |
endl |
mov eax, [base] |
mov esi, [mem_used_list] |
@@: |
test esi, esi |
jz .fail |
cmp [esi+block_base], eax |
je .found |
mov esi, [esi+list_next] |
jmp @b |
.found: |
cmp [esi+block_flags], USED_BLOCK |
jne .fail |
mov ecx, [esi+block_size]; |
mov [size], ecx |
stdcall free_kernel_space, [base] |
test eax, eax |
jz .fail |
mov ecx, [size] |
mov edi, [base] |
shr ecx, 12 |
mov esi, edi |
shr edi, 10 |
add edi, pages_tab |
xor edx, edx |
.release: |
mov eax, [edi] |
test eax, 1 |
jz .next |
call free_page |
mov [edi],edx |
.next: |
invlpg [esi] |
add esi, 0x1000 |
add edi, 4 |
dec ecx |
jnz .release |
.fail: |
ret |
endp |
restore block_next |
restore block_prev |
restore block_list |
restore block_base |
restore block_size |
restore block_flags |
;;;;;;;;;;;;;; USER ;;;;;;;;;;;;;;;;; |
align 4 |
proc init_heap stdcall, heap_size:dword |
locals |
tab_count dd ? |
endl |
mov edx, [heap_size] |
and edx, edx |
jz .exit |
add edx, 4095 |
and edx, not 4095 |
mov [heap_size], edx |
add edx, 0x003FFFFF |
and edx, not 0x003FFFFF |
shr edx, 22 |
mov [tab_count], edx |
mov ebx,[CURRENT_TASK] |
shl ebx,8 |
mov esi, [PROC_BASE+0x8c+ebx] |
add esi, 0x003FFFFF |
and esi, not 0x003FFFFF |
mov edi, esi |
mov [PROC_BASE+0x18+ebx], esi |
add esi, [heap_size] |
mov [PROC_BASE+0x1C+ebx], esi |
mov eax, cr3 |
and eax, not 0xFFF |
stdcall map_page,[current_pdir],eax,dword PG_SW |
add edi, new_app_base |
@@: |
call alloc_page |
test eax, eax |
jz .exit |
stdcall map_page_table, [current_pdir], edi, eax |
add edi, 0x00400000 |
dec edx |
jnz @B |
mov ecx, [tab_count] |
shl ecx, 12-2 |
mov ebx,[CURRENT_TASK] |
shl ebx,8 |
mov edi, [PROC_BASE+0x18+ebx] |
add edi, new_app_base |
shr edi, 10 |
mov esi, edi |
add edi, pages_tab |
xor eax, eax |
cld |
rep stosd |
stdcall map_page,[current_pdir],dword PG_UNMAP |
mov ebx, [heap_size] |
mov eax, ebx |
sub eax, 4096 |
or ebx, FREE_BLOCK |
mov [pages_tab+esi], ebx |
ret |
.exit: |
xor eax, eax |
ret |
endp |
align 4 |
proc user_alloc stdcall, alloc_size:dword |
mov ecx, [alloc_size] |
add ecx, (4095+4096) |
and ecx, not 4095 |
mov ebx, [CURRENT_TASK] |
shl ebx, 8 |
mov esi, dword [ebx+PROC_BASE+0x18]; heap_base |
mov edi, dword [ebx+PROC_BASE+0x1C]; heap_top |
add esi, new_app_base |
add edi, new_app_base |
l_0: |
cmp esi, edi |
jae m_exit |
mov ebx, esi |
shr ebx, 12 |
mov eax, [pages_tab+ebx*4] |
test eax, FREE_BLOCK |
jz test_used |
and eax, 0xFFFFF000 |
cmp eax, ecx ;alloc_size |
jb m_next |
mov edx, esi |
add edx, ecx |
sub eax, ecx; |
or eax, FREE_BLOCK |
shr edx, 12 |
mov [pages_tab+edx*4], eax |
or ecx, USED_BLOCK |
mov [pages_tab+ebx*4], ecx |
shr ecx, 12 |
dec ecx |
inc ebx |
@@: |
mov dword [pages_tab+ebx*4], 2 |
inc ebx |
dec ecx |
jnz @B |
mov eax, esi |
add eax, 4096 |
sub eax, new_app_base |
ret |
m_next: |
add esi, eax |
jmp l_0 |
test_used: |
test eax, USED_BLOCK |
jz m_exit |
and eax, 0xFFFFF000 |
add esi, eax |
jmp l_0 |
m_exit: |
xor eax, eax |
ret |
endp |
align 4 |
proc user_free stdcall, base:dword |
mov esi, [base] |
test esi, esi |
jz .exit |
sub esi, 4096 |
shr esi, 12 |
mov eax, [pages_tab+esi*4] |
test eax, USED_BLOCK |
jz @f |
and eax, not 4095 |
mov ecx, eax |
or eax, FREE_BLOCK |
mov [pages_tab+esi*4], eax |
inc esi |
sub ecx, 4096 |
shr ecx, 12 |
.release: |
mov eax, [pages_tab+esi*4] |
call free_page |
inc esi |
dec ecx |
jnz .release |
@@: |
mov ebx, [CURRENT_TASK] |
shl ebx, 8 |
mov esi, dword [ebx+PROC_BASE+0x18]; heap_base |
mov edi, dword [ebx+PROC_BASE+0x1C]; heap_top |
shr esi, 12 |
shr edi, 12 |
@@: |
mov eax, [pages_tab+esi*4] |
test eax, USED_BLOCK |
jz .test_free |
shr eax, 12 |
add esi, eax |
jmp @B |
.test_free: |
test eax, FREE_BLOCK |
jz .err |
mov edx, eax |
shr edx, 12 |
add edx, esi |
cmp edx, edi |
jae .exit |
mov ebx, [pages_tab+edx*4] |
test ebx, USED_BLOCK |
jz .next_free |
shr ebx, 12 |
add edx, ebx |
mov esi, edx |
jmp @B |
.next_free: |
test ebx, FREE_BLOCK |
jz .err |
and dword [pages_tab+edx*4], 0 |
add eax, ebx |
and eax, not 4095 |
or eax, FREE_BLOCK |
mov [pages_tab+esi*4], eax |
jmp @B |
.exit: |
xor eax, eax |
inc eax |
ret |
.err: |
xor eax, eax |
ret |
endp |
;proc new_mem_resize stdcall, new_size:dword |
; |
; stdcall wait_mutex, pg_data.pg_mutex |
; |
; mov edi, [new_size] |
; add edi,4095 |
; and edi,not 4095 |
; mov [new_size], edi |
; mov edx,[CURRENT_TASK] |
; shl edx,8 |
; mov esi, [PROC_BASE+0x8c+edx] |
; add esi, 4095 |
; and esi, not 4095 |
; cmp edi, esi |
; jae .expand |
; shr edi, 12 |
; shr esi, 12 |
; |
;@@: mov eax, [pages_tab+0x4000+edi*4] |
; test eax, 1 |
; jz .next |
; mov dword [pages_tab+0x4000+edi*4], 2 |
; mov ebx, edi |
; shl ebx, 12 |
; invlpg [ebx+std_application_base_address] |
; call free_page |
; |
;.next: add edi, 1 |
; cmp edi, esi |
; jb @B |
; |
;.update_size: |
; mov ebx, [new_size] |
; mov [PROC_BASE+0x8c+edx],ebx |
; |
;;search threads and update |
;;application memory size infomation |
; mov ecx,[PROC_BASE+0xb8+edx] |
; mov eax,2 |
;.search_threads: |
;;eax = current slot |
;;ebx = new memory size |
;;ecx = page directory |
; cmp eax,[TASK_COUNT] |
; jg .search_threads_end |
; mov edx,eax |
; shl edx,5 |
; cmp word [CURRENT_TASK+edx+0xa],9 ;if slot empty? |
; jz .search_threads_next |
; shl edx,3 |
; cmp [PROC_BASE+edx+0xb8],ecx ;if it is our thread? |
; jnz .search_threads_next |
; mov [PROC_BASE+edx+0x8c],ebx ;update memory size |
;.search_threads_next: |
; inc eax |
; jmp .search_threads |
;.search_threads_end: |
; xor eax, eax |
; dec [pg_data.pg_mutex] |
; ret |
; |
; |
;.expand: |
; add edi, new_app_base |
; add esi, new_app_base |
; |
;.grow: call alloc_page |
; test eax, eax |
; jz .exit |
; stdcall map_page,esi,eax,dword PG_UW |
; push edi |
; mov edi, esi |
; xor eax, eax |
; mov ecx, 1024 |
; cld |
; rep stosd |
; pop edi |
; add esi, 0x1000 |
; cmp esi, edi |
; jna .grow |
; jmp .update_size |
;.exit: |
; xor eax, eax |
; inc eax |
; dec [pg_data.pg_mutex] |
; ret |
;endp |
align 4 |
proc alloc_dll |
pushf |
cli |
bsf eax, [dll_map] |
jnz .find |
popf |
xor eax, eax |
ret |
.find: |
btr [dll_map], eax |
popf |
shl eax, 5 |
add eax, dll_tab |
ret |
endp |
align 4 |
proc alloc_service |
pushf |
cli |
bsf eax, [srv_map] |
jnz .find |
popf |
xor eax, eax |
ret |
.find: btr [srv_map], eax |
popf |
shl eax,5 |
add eax, srv_tab |
ret |
endp |
if NEW |
align 16 |
new_services: |
cmp eax, 10 |
jb .fail |
ja @f |
push dword [ebp+8+new_app_base] |
call get_mem_info |
mov [esp+36], eax |
ret |
@@: |
cmp eax, 11 |
ja @f |
push dword [ebp+8+new_app_base] |
call init_heap |
mov [esp+36], eax |
ret |
@@: |
cmp eax, 12 |
ja @f |
push dword [ebp+8+new_app_base] |
call user_alloc |
mov [esp+36], eax |
ret |
@@: |
cmp eax, 13 |
ja @f |
push dword [ebp+8+new_app_base] |
call user_free |
mov [esp+36], eax |
ret |
@@: |
cmp eax, 14 |
ja @f |
mov eax, [ebp+8+new_app_base] |
add eax,new_app_base |
stdcall get_notify, eax |
ret |
;@@: |
; cmp eax, 15 |
; ja @f |
; call set_notify |
; ret |
@@: |
cmp eax, 16 |
ja @f |
mov eax, [ebp+8+new_app_base] |
add eax, new_app_base |
stdcall get_service, eax |
mov [esp+36], eax |
ret |
@@: |
cmp eax, 17 |
ja @f |
stdcall srv_handler,[ebp+8+new_app_base],\ |
[ebp+12+new_app_base],\ |
[ebp+16+new_app_base] |
mov [esp+36], eax |
ret |
;@@: |
; cmp eax, 20 |
; ja @f |
; call CreateSound |
; mov [esp+36], eax |
; ret |
@@: |
.fail: |
xor eax, eax |
mov [esp+36], eax |
ret |
proc strncmp stdcall, str1:dword, str2:dword, count:dword |
mov ecx,[count] |
jecxz .end |
mov ebx,ecx |
mov edi,[str1] |
mov esi,edi |
xor eax,eax |
repne scasb |
neg ecx ; cx = count - strlen |
add ecx,ebx ; strlen + count - strlen |
.okay: |
mov edi,esi |
mov esi,[str2] |
repe cmpsb |
mov al,[esi-1] |
xor ecx,ecx |
cmp al,[edi-1] |
ja .str2_big |
je .end |
.str1_big: |
sub ecx,2 |
.str2_big: |
not ecx |
.end: |
mov eax,ecx |
ret |
endp |
proc get_proc stdcall, exp:dword, sz_name:dword |
mov edx, [exp] |
.next: |
mov eax, [edx] |
test eax, eax |
jz .end |
push edx |
stdcall strncmp, eax, [sz_name], 16 |
pop edx |
test eax, eax |
jz .ok |
add edx,8 |
jmp .next |
.ok: |
mov eax, [edx+4] |
.end: |
ret |
endp |
proc link_dll stdcall, exp:dword, imp:dword |
mov esi, [imp] |
.next: |
mov eax, [esi] |
test eax, eax |
jz .end |
push esi |
stdcall get_proc, [exp], eax |
pop esi |
test eax, eax |
jz @F |
mov [esi], eax |
@@: |
add esi, 4 |
jmp .next |
.end: |
ret |
endp |
end if |
/kernel/trunk/core/memory.inc |
---|
0,0 → 1,1417 |
tmp_page_tab equ 0x01000000 |
align 4 |
proc mem_test |
mov eax, cr0 |
or eax, 0x60000000 ;disable caching |
mov cr0, eax |
wbinvd ;invalidate cache |
xor edi, edi |
mov ebx, 'TEST' |
@@: |
add edi, 0x400000 |
xchg ebx, dword [edi] |
cmp dword [edi], 'TEST' |
xchg ebx, dword [edi] |
je @b |
and eax, 0x21 |
mov cr0, eax |
mov eax, edi |
ret |
endp |
align 4 |
proc init_memEx |
xor eax, eax |
mov edi, sys_pgdir |
mov ecx, 2048 |
rep stosd |
bt [cpu_caps], CAPS_PSE |
jnc .no_PSE |
mov ebx, cr4 |
or ebx, CR4_PSE |
mov eax, PG_LARGE+PG_SW |
bt [cpu_caps], CAPS_PGE |
jnc @F |
or eax, PG_GLOBAL |
or ebx, CR4_PGE |
@@: |
mov dword [sys_pgdir], eax |
add eax, 0x00400000 |
mov dword [sys_pgdir+4], eax |
add eax, 0x00400000 |
mov dword [sys_pgdir+8], eax |
add eax, 0x00400000 |
mov dword [sys_pgdir+12], eax |
mov dword [sys_pgdir+0x600], sys_master_tab+PG_SW |
mov dword [sys_master_tab+0x600], sys_master_tab+PG_SW |
mov cr4, ebx |
mov ecx, [pg_data.kernel_tables] |
sub ecx, 4 |
mov eax, tmp_page_tab+PG_SW |
mov edi, sys_pgdir+16 |
mov esi, sys_master_tab+16 |
jmp .map_kernel_tabs |
.no_PSE: |
mov eax, PG_SW |
mov esi, tmp_page_tab |
mov ecx, 4096/4 ;0x0 - 0x00FFFFFF |
.map_low: |
mov [esi], eax |
add eax, 0x1000 |
mov [esi+4], eax |
add eax, 0x1000 |
mov [esi+8], eax |
add eax, 0x1000 |
mov [esi+12], eax |
add eax, 0x1000 |
add esi, 16 |
dec ecx |
jnz .map_low ;ÿäðî |
mov ecx, [pg_data.kernel_tables] |
mov eax, tmp_page_tab+PG_SW |
mov edi, sys_pgdir |
mov esi, sys_master_tab |
.map_kernel_tabs: |
mov [edi], eax |
mov [esi], eax |
add eax, 0x1000 |
add edi, 4 |
add esi, 4 |
dec ecx |
jnz .map_kernel_tabs |
mov edi, tmp_page_tab |
bt [cpu_caps], CAPS_PSE |
jc @F |
add edi, 4096*4 ;skip low kernel memory |
@@: |
mov ecx, [pg_data.kernel_tables] |
sub ecx, 4 |
shl ecx, 10 |
xor eax, eax |
cld |
rep stosd |
mov dword [sys_pgdir+0x600], sys_master_tab+PG_SW |
mov dword [sys_master_tab+0x600], sys_master_tab+PG_SW |
ret |
endp |
;align 4 |
;proc init_mem |
; |
; xor eax, eax |
; mov edi, sys_pgdir |
; mov ecx, 2048 |
; rep stosd |
; |
; bt [cpu_caps], CAPS_PSE |
; jc .use_PSE |
; |
; mov eax, PG_SW |
; mov esi, tmp_page_tab |
; mov ecx, 4096/4 ;0x0 - 0x00FFFFFF |
; |
;.map_low: |
; mov [esi], eax |
; add eax, 0x1000 |
; mov [esi+4], eax |
; add eax, 0x1000 |
; mov [esi+8], eax |
; add eax, 0x1000 |
; mov [esi+12], eax |
; add eax, 0x1000 |
; add esi, 16 |
; dec ecx |
; jnz .map_low ;ÿäðî |
; mov eax, tmp_page_tab+PG_SW |
; mov ecx, 4 |
; xor ebx, ebx |
;.map_page_tables: |
; mov [sys_pgdir+ebx], eax |
; mov [sys_master_tab+ebx], eax |
; add eax, 0x1000 |
; add ebx, 4 |
; dec ecx |
; jnz .map_page_tables |
; mov dword [sys_pgdir+0x600], sys_master_tab+PG_SW |
; mov dword [sys_master_tab+0x600], sys_master_tab+PG_SW |
; ret |
;.use_PSE: |
; mov ebx, cr4 |
; or ebx, CR4_PSE |
; mov eax, PG_LARGE+PG_SW |
; bt [cpu_caps], CAPS_PGE |
; jnc @F |
; or eax, PG_GLOBAL |
; or ebx, CR4_PGE |
;@@: |
; mov dword [sys_pgdir], eax |
; add eax, 0x00400000 |
; mov dword [sys_pgdir+4], eax |
; add eax, 0x00400000 |
; mov dword [sys_pgdir+8], eax |
; add eax, 0x00400000 |
; mov dword [sys_pgdir+12], eax |
; |
; mov dword [sys_pgdir+0x600], sys_master_tab+PG_SW |
; mov dword [sys_master_tab+0x600], sys_master_tab+PG_SW |
; mov cr4, ebx |
; ret |
;endp |
align 4 |
proc init_page_map |
mov edi, sys_pgmap |
mov ecx, 512/4 |
xor eax,eax |
cld |
rep stosd |
not eax |
mov ecx, [pg_data.pagemap_size] |
sub ecx, 512 |
shr ecx, 2 |
rep stosd |
mov edi, sys_pgmap+512 |
mov edx, [pg_data.pages_count] |
mov ecx, [pg_data.kernel_tables] |
bt [cpu_caps], CAPS_PSE |
jnc @f |
sub ecx, 4 |
@@: |
sub edx, 4096 |
sub edx, ecx |
mov [pg_data.pages_free], edx |
xor eax, eax |
mov ebx, ecx |
shr ecx, 5 |
rep stosd |
not eax |
mov ecx, ebx |
and ecx, 31 |
shl eax, cl |
stosd |
mov [page_start], sys_pgmap+512 |
mov ebx, sys_pgmap |
add ebx, [pg_data.pagemap_size] |
mov [page_end], ebx |
mov [pg_data.pg_mutex], 0 |
ret |
endp |
;align 4 |
;proc init_pg_mem |
; |
; mov edi, sys_pgmap |
; mov ecx, 512/4 |
; xor eax,eax |
; cld |
; rep stosd |
; |
; not eax |
; mov ecx, [pg_data.pagemap_size] |
; sub ecx, 512 |
; shr ecx, 2 |
; rep stosd |
; |
; shl eax, PAGES_USED |
; mov [sys_pgmap+512], eax |
; |
; mov [page_start], sys_pgmap+512 |
; mov ebx, sys_pgmap |
; add ebx, [pg_data.pagemap_size] |
; mov [page_end], ebx |
; mov eax, [pg_data.pages_count] |
; sub eax, 4096+PAGES_USED |
; mov [pg_data.pages_free], eax |
; |
; mov [pg_data.pages_faults], 0 |
; |
; mov edi, OS_BASE+0x01000000 |
; mov esi, [pg_data.kernel_tables] |
; sub esi, 4 |
; ja @f |
; mov esi, 1 |
;@@: |
; call alloc_page |
; stdcall map_page_table, sys_pgdir, edi, eax |
; add edi, 0x00400000 |
; dec esi |
; jnz @B |
; |
; mov ecx, [pg_data.kernel_tables] |
; sub ecx, 4 |
; shl ecx, 10 |
; mov edi, OS_BASE+0x01000000 |
; shr edi, 10 |
; add edi, pages_tab |
; xor eax, eax |
; cld |
; rep stosd |
; |
; mov eax, cr3 |
; mov cr3, eax |
; |
; mov [pg_data.pg_mutex], 0 |
; ret |
;endp |
align 4 |
proc alloc_page |
pushfd |
cli |
mov ebx, [page_start] |
mov ecx, [page_end] |
.l1: |
bsf eax,[ebx]; |
jnz .found |
add ebx,4 |
cmp ebx, ecx |
jb .l1 |
popfd |
xor eax,eax |
ret |
.found: |
btr [ebx], eax |
mov [page_start],ebx |
sub ebx, sys_pgmap |
shl ebx, 3 |
add eax,ebx |
shl eax, 12 |
dec [pg_data.pages_free] |
popfd |
ret |
endp |
align 4 |
proc alloc_pages stdcall, count:dword |
pushfd |
cli |
mov eax, [count] |
add eax, 7 |
shr eax, 3 |
mov [count], eax |
cmp eax, [pg_data.pages_free] |
ja .fail |
mov ecx, [page_start] |
mov ebx, [page_end] |
.find: |
mov edx, [count] |
mov edi, ecx |
.match: |
cmp byte [ecx], 0xFF |
jne .next |
dec edx |
jz .ok |
inc ecx |
cmp ecx,ebx |
jb .match |
.fail: xor eax, eax |
popfd |
ret |
.next: |
inc ecx |
cmp ecx, ebx |
jb .find |
popfd |
xor eax, eax |
ret |
.ok: |
sub ecx, edi |
inc ecx |
mov esi, edi |
xor eax, eax |
rep stosb |
sub esi, sys_pgmap |
shl esi, 3+12 |
mov eax, esi |
mov ebx, [count] |
shl ebx, 3 |
sub [pg_data.pages_free], ebx |
popfd |
ret |
endp |
align 4 |
proc map_page stdcall,lin_addr:dword,phis_addr:dword,flags:dword |
mov eax, [phis_addr] |
and eax, not 0xFFF |
or eax, [flags] |
mov ebx, [lin_addr] |
shr ebx, 12 |
mov [pages_tab+ebx*4], eax |
mov eax, [lin_addr] |
invlpg [eax] |
ret |
endp |
align 4 |
proc free_page |
;arg: eax page address |
pushfd |
cli |
inc [pg_data.pages_free] |
shr eax, 12 ;page index |
mov ebx, sys_pgmap |
bts [ebx], eax ;that's all! |
shr eax, 3 |
and eax, not 3 ;dword offset from page_map |
add eax, ebx |
cmp [page_start], eax |
ja @f |
popfd |
ret |
@@: |
mov [page_start], eax |
popfd |
ret |
endp |
align 4 |
proc map_page_table stdcall,page_dir:dword, lin_addr:dword, phis_addr:dword |
mov ebx, [lin_addr] |
shr ebx, 22 |
mov eax, [phis_addr] |
and eax, not 0xFFF |
or eax, PG_UW ;+PG_NOCACHE |
mov ecx, [page_dir] |
mov dword [ecx+ebx*4], eax |
mov dword [master_tab+ebx*4], eax |
mov eax, [lin_addr] |
shr eax, 10 |
add eax, pages_tab |
invlpg [eax] |
ret |
endp |
align 4 |
proc init_LFB |
cmp dword [LFBAddress], -1 |
jne @f |
stdcall kernel_alloc, 0x280000 |
mov [LFBAddress], eax |
ret |
@@: |
test [SCR_MODE],word 0100000000000000b |
jz @f |
call map_LFB |
@@: |
ret |
endp |
align 4 |
proc map_LFB |
locals |
pg_count dd ? |
endl |
mov edi, [LFBSize] |
mov esi, [LFBAddress] |
shr edi, 12 |
mov [pg_count], edi |
shr edi, 10 |
bt [cpu_caps], CAPS_PSE |
jnc .map_page_tables |
mov ebx, esi |
or esi, PG_LARGE+PG_UW |
shr ebx, 20 |
mov ecx, ebx |
@@: |
mov [sys_pgdir+ebx], esi |
add ebx, 4 |
add esi, 0x00400000 |
dec edi |
jnz @B |
or dword [sys_pgdir+ecx], PG_GLOBAL |
mov eax, cr3 ;flush TLB |
mov cr3, eax |
ret |
.map_page_tables: |
@@: |
call alloc_page |
stdcall map_page_table,sys_pgdir, esi, eax |
add esi, 0x00400000 |
dec edi |
jnz @B |
mov eax, [LFBAddress] |
mov esi, eax |
shr esi, 10 |
add esi, pages_tab |
or eax, PG_UW |
mov ecx, [pg_count] |
shr ecx, 2 |
.map: |
mov [esi], eax |
add eax, 0x1000 |
mov [esi+4], eax |
add eax, 0x1000 |
mov [esi+8], eax |
add eax, 0x1000 |
mov [esi+12], eax |
add eax, 0x1000 |
add esi, 16 |
sub ecx, 1 |
jnz .map |
mov eax, cr3 ;flush TLB |
mov cr3, eax |
ret |
endp |
align 4 |
proc new_mem_resize stdcall, new_size:dword |
stdcall wait_mutex, pg_data.pg_mutex |
mov edi, [new_size] |
add edi,4095 |
and edi,not 4095 |
mov [new_size], edi |
mov edx,[CURRENT_TASK] |
shl edx,8 |
mov esi, [PROC_BASE+0x8c+edx] |
add esi, 4095 |
and esi, not 4095 |
cmp edi, esi |
jae .expand |
shr edi, 12 |
shr esi, 12 |
@@: |
mov eax, [pages_tab+0x00181000+edi*4] |
test eax, 1 |
jz .next |
mov dword [pages_tab+0x00181000+edi*4], 2 |
mov ebx, edi |
shl ebx, 12 |
invlpg [ebx+std_application_base_address] |
call free_page |
.next: add edi, 1 |
cmp edi, esi |
jb @B |
.update_size: |
mov ebx, [new_size] |
mov [PROC_BASE+0x8c+edx],ebx |
;search threads and update |
;application memory size infomation |
mov ecx,[PROC_BASE+0xb8+edx] |
mov eax,2 |
.search_threads: |
;eax = current slot |
;ebx = new memory size |
;ecx = page directory |
cmp eax,[TASK_COUNT] |
jg .search_threads_end |
mov edx,eax |
shl edx,5 |
cmp word [CURRENT_TASK+edx+0xa],9 ;if slot empty? |
jz .search_threads_next |
shl edx,3 |
cmp [PROC_BASE+edx+0xb8],ecx ;if it is our thread? |
jnz .search_threads_next |
mov [PROC_BASE+edx+0x8c],ebx ;update memory size |
.search_threads_next: |
inc eax |
jmp .search_threads |
.search_threads_end: |
xor eax, eax |
dec [pg_data.pg_mutex] |
ret |
.expand: |
add edi, new_app_base |
add esi, new_app_base |
push esi |
push edi |
add edi, 0x3FFFFF |
and edi, not(0x3FFFFF) |
add esi, 0x3FFFFF |
and esi, not(0x3FFFFF) |
cmp esi, edi |
jae .grow |
xchg esi, edi |
mov eax, cr3 |
stdcall map_page,[tmp_task_pdir],eax,dword PG_SW+PG_NOCACHE |
@@: |
call alloc_page |
test eax, eax |
jz .exit |
stdcall map_page_table,[tmp_task_pdir], edi, eax |
push edi |
shr edi, 10 |
add edi, pages_tab |
mov ecx, 1024 |
xor eax, eax |
cld |
rep stosd |
pop edi |
add edi, 0x00400000 |
cmp edi, esi |
jb @B |
stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP |
.grow: |
pop edi |
pop esi |
@@: |
call alloc_page |
test eax, eax |
jz .exit |
stdcall map_page,esi,eax,dword PG_UW |
push edi |
mov edi, esi |
xor eax, eax |
mov ecx, 1024 |
cld |
rep stosd |
pop edi |
add esi, 0x1000 |
cmp esi, edi |
jna @B |
jmp .update_size |
.exit: |
xor eax, eax |
inc eax |
dec [pg_data.pg_mutex] |
ret |
endp |
align 4 |
proc get_pg_addr stdcall, lin_addr:dword |
mov ebx, [lin_addr] |
shr ebx, 12 |
mov eax, [pages_tab+ebx*4] |
and eax, 0xFFFFF000 |
ret |
endp |
align 16 |
proc page_fault_handler |
pushad |
mov ebp, esp |
mov eax, cr2 |
sub esp, 4 |
mov [esp], eax |
push ds |
mov ax, 0x10 |
mov ds, ax |
; mov edx, 0x400 ;bocsh |
; mov al,0xff ;bocsh |
; out dx, al ;bocsh |
; nop ;bocsh fix |
mov ebx, [ebp-4] |
cmp ebx, 0xe0000000 |
jae .lfb_addr |
cmp ebx, 0x60400000 |
jae .user_space |
cmp ebx, 0x60000000 |
jae .tab_space |
jmp .kernel_space |
.user_space: |
inc [pg_data.pages_faults] |
shr ebx, 12 |
mov eax, [pages_tab+ebx*4] |
shr ebx, 10 |
mov edx, [master_tab+ebx*4] |
test eax, 2 |
jz .exit |
call alloc_page |
and eax, eax |
jz .exit |
stdcall map_page,[ebp-4],eax,dword PG_UW |
mov esi, [ebp-4] |
and esi, 0xFFFFF000 |
mov ecx, 1024 |
xor eax, eax |
@@: |
mov [esi], eax |
add esi, 4 |
dec ecx |
jnz @B |
.exit: |
pop ds |
mov esp, ebp |
popad |
add esp, 4 |
iretd |
.kernel_space: |
shr ebx, 12 |
mov eax, [pages_tab+ebx*4] |
shr ebx, 10 |
mov eax, [master_tab+ebx*4] |
pop ds |
mov esp, ebp |
popad |
add esp, 4 |
iretd |
.old_addr: |
shr ebx, 12 |
; mov eax, [pages_tab+ebx*4] |
shr ebx, 10 |
mov eax, [master_tab+ebx*4] |
pop ds |
mov esp, ebp |
popad |
add esp, 4 |
iretd |
.lfb_addr: |
shr ebx, 22 |
;mov ecx, [sys_page_dir] |
mov eax, [master_tab+ebx*4] |
pop ds |
mov esp, ebp |
popad |
add esp, 4 |
iretd |
.tab_space: |
shr ebx, 12 |
; mov eax, [pages_tab+ebx*4] |
shr ebx, 10 |
;mov ecx, [sys_page_dir] |
mov eax, [master_tab+ebx*4] |
pop ds |
mov esp, ebp |
popad |
add esp, 4 |
iretd |
endp |
align 4 |
proc map_mem stdcall, lin_addr:dword,pdir:dword,\ |
ofs:dword,buf_size:dword |
mov eax, [buf_size] |
test eax, eax |
jz .exit |
mov eax, [pdir] |
and eax, 0xFFFFF000 |
stdcall map_page,[ipc_pdir],eax,dword PG_UW |
mov ebx, [ofs] |
shr ebx, 22 |
mov esi, [ipc_pdir] |
mov edi, [ipc_ptab] |
mov eax, [esi+ebx*4] |
and eax, 0xFFFFF000 |
test eax, eax |
jz .exit |
stdcall map_page,edi,eax,dword PG_UW |
; inc ebx |
; add edi, 0x1000 |
; mov eax, [esi+ebx*4] |
; test eax, eax |
; jz @f |
; and eax, 0xFFFFF000 |
; stdcall map_page, edi, eax |
@@: mov edi, [lin_addr] |
and edi, 0xFFFFF000 |
mov ecx, [buf_size] |
add ecx, 4095 |
shr ecx, 12 |
inc ecx |
mov edx, [ofs] |
shr edx, 12 |
and edx, 0x3FF |
mov esi, [ipc_ptab] |
.map: mov eax, [esi+edx*4] |
and eax, 0xFFFFF000 |
test eax, eax |
jz .exit |
stdcall map_page,edi,eax,dword PG_UW |
add edi, 0x1000 |
inc edx |
dec ecx |
jnz .map |
.exit: |
ret |
endp |
align 4 |
proc map_memEx stdcall, lin_addr:dword,pdir:dword,\ |
ofs:dword,buf_size:dword |
mov eax, [buf_size] |
test eax, eax |
jz .exit |
mov eax, [pdir] |
and eax, 0xFFFFF000 |
stdcall map_page,[proc_mem_pdir],eax,dword PG_UW |
mov ebx, [ofs] |
shr ebx, 22 |
mov esi, [proc_mem_pdir] |
mov edi, [proc_mem_tab] |
mov eax, [esi+ebx*4] |
and eax, 0xFFFFF000 |
test eax, eax |
jz .exit |
stdcall map_page,edi,eax,dword PG_UW |
@@: mov edi, [lin_addr] |
and edi, 0xFFFFF000 |
mov ecx, [buf_size] |
add ecx, 4095 |
shr ecx, 12 |
inc ecx |
mov edx, [ofs] |
shr edx, 12 |
and edx, 0x3FF |
mov esi, [proc_mem_tab] |
.map: mov eax, [esi+edx*4] |
; and eax, 0xFFFFF000 |
; test eax, eax |
; jz .exit |
stdcall map_page,edi,eax,dword PG_UW |
add edi, 0x1000 |
inc edx |
dec ecx |
jnz .map |
.exit: |
ret |
endp |
sys_IPC: |
;input: |
; eax=1 - set ipc buffer area |
; ebx=address of buffer |
; ecx=size of buffer |
; eax=2 - send message |
; ebx=PID |
; ecx=address of message |
; edx=size of message |
cmp eax,1 |
jne @f |
call set_ipc_buff |
mov [esp+36], eax |
ret |
@@: |
cmp eax, 2 |
jne @f |
stdcall sys_ipc_send, ebx, ecx, edx |
mov [esp+36], eax |
ret |
@@: |
xor eax, eax |
not eax |
mov [esp+36], eax |
ret |
align 4 |
proc set_ipc_buff |
mov eax,[CURRENT_TASK] |
shl eax,8 |
add eax, PROC_BASE |
pushf |
cli |
mov [eax+0xA0],ebx ;set fields in extended information area |
mov [eax+0xA4],ecx |
add ebx, new_app_base |
add ecx, ebx |
add ecx, 4095 |
and ecx, not 4095 |
.touch: mov eax, [ebx] |
add ebx, 0x1000 |
cmp ebx, ecx |
jna .touch |
popf |
xor eax, eax |
ret |
endp |
proc sys_ipc_send stdcall, PID:dword, msg_addr:dword, msg_size:dword |
locals |
dst_slot dd ? |
dst_offset dd ? |
buf_size dd ? |
endl |
pushf |
cli |
mov eax, [PID] |
call pid_to_slot |
test eax,eax |
jz .no_pid |
mov [dst_slot], eax |
shl eax,8 |
mov edi,[eax+PROC_BASE+0xa0] ;is ipc area defined? |
test edi,edi |
jz .no_ipc_area |
mov ebx, edi |
add edi, new_app_base |
and ebx, 0xFFF |
mov [dst_offset], ebx |
mov esi, [eax+PROC_BASE+0xa4] |
mov [buf_size], esi |
stdcall map_mem, [ipc_tmp], [PROC_BASE+eax+0xB8],\ |
edi, esi |
mov edi, [dst_offset] |
add edi, [ipc_tmp] |
cmp dword [edi], 0 |
jnz .ipc_blocked ;if dword [buffer]<>0 - ipc blocked now |
mov ebx, dword [edi+4] |
mov edx, ebx |
add ebx, 8 |
add ebx, [msg_size] |
cmp ebx, [buf_size] |
ja .buffer_overflow ;esi<0 - not enough memory in buffer |
mov dword [edi+4], ebx |
mov eax,[TASK_BASE] |
mov eax, [eax+0x04] ;eax - our PID |
mov edi, [dst_offset] |
add edi, [ipc_tmp] |
add edi, edx |
mov [edi], eax |
mov ecx, [msg_size] |
mov [edi+4], ecx |
add edi, 8 |
mov esi, [msg_addr] |
add esi, new_app_base |
cld |
rep movsb |
mov ebx, [ipc_tmp] |
mov edx, ebx |
shr ebx, 12 |
xor eax, eax |
mov [pages_tab+ebx*4], eax |
invlpg [edx] |
mov ebx, [ipc_pdir] |
mov edx, ebx |
shr ebx, 12 |
xor eax, eax |
mov [pages_tab+ebx*4], eax |
invlpg [edx] |
mov ebx, [ipc_ptab] |
mov edx, ebx |
shr ebx, 12 |
xor eax, eax |
mov [pages_tab+ebx*4], eax |
invlpg [edx] |
mov eax, [dst_slot] |
shl eax, 8 |
or [eax+PROC_BASE+0xA8],dword 0x40 |
cmp dword [check_idle_semaphore],20 |
jge .ipc_no_cis |
mov dword [check_idle_semaphore],5 |
.ipc_no_cis: |
popf |
xor eax, eax |
ret |
.no_pid: |
popf |
mov eax, 4 |
ret |
.no_ipc_area: |
popf |
xor eax, eax |
inc eax |
ret |
.ipc_blocked: |
popf |
mov eax, 2 |
ret |
.buffer_overflow: |
popf |
mov eax, 3 |
ret |
endp |
align 4 |
proc get_mem_info stdcall, val:dword |
mov esi, [val] |
mov eax, [pg_data.pages_count] |
mov [esi], eax |
mov ebx, [pg_data.pages_free] |
mov [esi+4], ebx |
mov ecx, [pg_data.pages_faults] |
mov [esi+8], ecx |
ret |
endp |
align 4 |
new_services: |
cmp eax,4 |
jle sys_sheduler |
cmp eax, 10 |
jb .fail |
ja @f |
add ebx, new_app_base |
stdcall get_mem_info, ebx |
mov [esp+36], eax |
ret |
@@: |
cmp eax, 11 |
ja @f |
stdcall init_heap, ebx |
mov [esp+36], eax |
ret |
@@: |
cmp eax, 12 |
ja @f |
stdcall user_alloc, ebx |
mov [esp+36], eax |
ret |
@@: |
cmp eax, 13 |
ja @f |
stdcall user_free, ebx |
mov [esp+36], eax |
ret |
@@: |
cmp eax, 14 |
ja @f |
add ebx,new_app_base |
stdcall get_notify, ebx |
ret |
@@: |
cmp eax, 15 |
ja @f |
mov ecx, [CURRENT_TASK] |
shl ecx, 8 |
mov eax, [ecx+PROC_BASE+APPDATA.fpu_handler] |
mov [ecx+PROC_BASE+APPDATA.fpu_handler], ebx |
mov [esp+36], eax |
ret |
@@: |
cmp eax, 16 |
ja @f |
add ebx, new_app_base |
stdcall get_service, ebx |
mov [esp+36], eax |
ret |
@@: |
cmp eax, 17 |
ja @f |
stdcall srv_handlerEx, ebx |
mov [esp+36], eax |
ret |
@@: |
.fail: |
xor eax, eax |
mov [esp+36], eax |
ret |
align 4 |
proc strncmp stdcall, str1:dword, str2:dword, count:dword |
mov ecx,[count] |
jecxz .end |
mov ebx,ecx |
mov edi,[str1] |
mov esi,edi |
xor eax,eax |
repne scasb |
neg ecx ; cx = count - strlen |
add ecx,ebx ; strlen + count - strlen |
.okay: |
mov edi,esi |
mov esi,[str2] |
repe cmpsb |
mov al,[esi-1] |
xor ecx,ecx |
cmp al,[edi-1] |
ja .str2_big |
je .end |
.str1_big: |
sub ecx,2 |
.str2_big: |
not ecx |
.end: |
mov eax,ecx |
ret |
endp |
align 4 |
proc fpu_save |
clts |
mov ebx, [fpu_owner] |
shl ebx, 8 |
mov eax, [ebx+PROC_BASE+0x10] |
mov ebx, [CURRENT_TASK] |
mov [fpu_owner], ebx |
bt [cpu_caps], CAPS_FXSR |
jnc .no_SSE |
fxsave [eax] |
ret |
.no_SSE: |
fnsave [eax] |
ret |
endp |
align 4 |
proc fpu_restore |
mov ebx, [CURRENT_TASK] |
shl ebx, 8 |
mov eax, [ebx+PROC_BASE+0x10] |
bt [cpu_caps], CAPS_FXSR |
jnc .no_SSE |
fxrstor [eax] |
ret |
.no_SSE: |
frstor [eax] |
ret |
endp |
align 4 |
proc test_cpu |
locals |
cpu_type dd 0 |
cpu_id dd 0 |
cpu_Intel dd 0 |
cpu_AMD dd 0 |
endl |
mov [cpu_type], 0 |
pushfd |
pop eax |
mov ecx, eax |
xor eax, 0x40000 |
push eax |
popfd |
pushfd |
pop eax |
xor eax, ecx |
mov [cpu_type], CPU_386 |
jz .end_cpu |
push ecx |
popfd |
mov [cpu_type], CPU_486 |
mov eax, ecx |
xor eax, 0x200000 |
push eax |
popfd |
pushfd |
pop eax |
xor eax, ecx |
je .end_cpu |
mov [cpu_id], 1 |
xor eax, eax |
cpuid |
mov [cpu_vendor], ebx |
mov [cpu_vendor+4], edx |
mov [cpu_vendor+8], ecx |
cmp ebx, dword [intel_str] |
jne .check_AMD |
cmp edx, dword [intel_str+4] |
jne .check_AMD |
cmp ecx, dword [intel_str+8] |
jne .check_AMD |
mov [cpu_Intel], 1 |
cmp eax, 1 |
jl .end_cpuid |
mov eax, 1 |
cpuid |
mov [cpu_sign], eax |
mov [cpu_info], ebx |
mov [cpu_caps], edx |
mov [cpu_caps+4],ecx |
shr eax, 8 |
and eax, 0x0f |
mov [cpu_type], eax |
ret |
.end_cpuid: |
mov eax, [cpu_type] |
ret |
.check_AMD: |
cmp ebx, dword [AMD_str] |
jne .end_cpu |
cmp edx, dword [AMD_str+4] |
jne .end_cpu |
cmp ecx, dword [AMD_str+8] |
jne .end_cpu |
mov [cpu_AMD], 1 |
cmp eax, 1 |
jl .end_cpuid |
mov eax, 1 |
cpuid |
mov [cpu_sign], eax |
mov [cpu_info], ebx |
mov [cpu_caps], edx |
mov [cpu_caps+4],ecx |
shr eax, 8 |
and eax, 0x0f |
mov [cpu_type], eax |
.end_cpu: |
mov eax, [cpu_type] |
ret |
endp |
MEM_WB equ 6 ;write-back memory |
MEM_WC equ 1 ;write combined memory |
MEM_UC equ 0 ;uncached memory |
align 4 |
proc init_mtrr |
cmp [0x2f0000+0x901c],byte 2 |
je .exit |
mov eax, cr0 |
or eax, 0x60000000 ;disable caching |
mov cr0, eax |
wbinvd ;invalidate cache |
mov ecx, 0x2FF |
rdmsr ; |
push eax |
xor edx, edx |
xor eax, eax |
mov ecx, 0x2FF |
wrmsr ;disable all MTRR |
stdcall set_mtrr, dword 0,dword 0,[MEM_AMOUNT],MEM_WB |
stdcall set_mtrr, dword 1,[LFBAddress],[LFBSize],MEM_WC |
xor edx, edx |
xor eax, eax |
mov ecx, 0x204 |
mov ebx, 6 |
@@: |
wrmsr ;disable unused MTRR |
inc ecx |
wrmsr |
inc ecx |
dec ebx |
jnz @b |
wbinvd ;again invalidate |
pop eax |
or eax, 0x800 ;set default memtype to UC |
and al, 0xF0 |
mov ecx, 0x2FF |
wrmsr ;and enable MTRR |
mov eax, cr0 |
and eax, not 0x60000000 |
mov cr0, eax ; enable caching |
.exit: |
ret |
endp |
align 4 |
proc set_mtrr stdcall, reg:dword,base:dword,size:dword,mem_type:dword |
xor edx, edx |
mov eax, [base] |
or eax, [mem_type] |
mov ecx, [reg] |
lea ecx, [0x200+ecx*2] |
wrmsr |
mov ebx, [size] |
dec ebx |
mov eax, 0xFFFFFFFF |
mov edx, 0x0000000F |
sub eax, ebx |
sbb edx, 0 |
or eax, 0x800 |
inc ecx |
wrmsr |
ret |
endp |
iglobal |
align 4 |
intel_str db "GenuineIntel",0 |
AMD_str db "AuthenticAMD",0 |
endg |
uglobal |
align 16 |
irq_tab rd 16 |
MEM_FreeSpace rd 1 |
ipc_tmp rd 1 |
ipc_pdir rd 1 |
ipc_ptab rd 1 |
proc_mem_map rd 1 |
proc_mem_pdir rd 1 |
proc_mem_tab rd 1 |
tmp_task_pdir rd 1 |
tmp_task_ptab rd 1 |
tmp_task_data rd 1 |
current_pdir rd 1 |
fpu_data rd 1 |
fdd_buff rd 1 |
;;CPUID information |
cpu_vendor rd 3 |
cpu_sign rd 1 |
cpu_info rd 1 |
endg |
uglobal |
align 16 |
dll_tab rb 32*32 |
srv_tab rb 32*32 |
dll_map rd 1 |
srv_map rd 1 |
mem_used_list rd 1 |
mem_block_list rd 64 |
mem_block_map rb 512 |
mem_block_arr rd 1 |
mem_block_start rd 1 |
mem_block_end rd 1 |
mem_block_mask rd 2 |
page_start rd 1 |
page_end rd 1 |
sys_page_map rd 1 |
app_load rd 1 |
endg |
; push eax |
; push edx |
; mov edx, 0x400 ;bocsh |
; mov al,0xff ;bocsh |
; out dx, al ;bocsh |
; nop ;bocsh fix |
; pop edx |
; pop eax |
/kernel/trunk/core/sys32.inc |
---|
54,18 → 54,18 |
; ----------------------------------------- |
app_code_l: |
dw ((0x80000000-std_application_base_address) shr 12) and 0xffff |
dw 0xFFFF;((0x80000000-std_application_base_address) shr 12) and 0xffff |
dw 0 |
db 0 |
dw 11010000b*256+11111010b+256*((0x80000000-std_application_base_address) shr 28) |
db std_application_base_address shr 24 |
db 0x40 |
db cpl3 |
dw G32+D32+0x6000+0x7; |
app_data_l: |
dw (0x80000000-std_application_base_address) shr 12 and 0xffff |
dw 0xFFFF;(0x80000000-std_application_base_address) shr 12 and 0xffff |
dw 0 |
db 0 |
dw 11010000b*256+11110010b+256*((0x80000000-std_application_base_address) shr 28) |
db std_application_base_address shr 24 |
db 0x40 |
db drw3 |
dw G32+D32+0x6000+0x7; |
graph_data_l: |
81,11 → 81,10 |
gdte: |
idtreg: |
dw 8*0x41-1 |
dd idts+8 |
label idts at 0xB100-8 |
;label idts at 0xB100-8 |
166,16 → 165,20 |
ret |
iglobal |
sys_int: |
dd e0,debug_exc,e2,e3,e4,e5,e6,e7,e8,e9,e10,e11,e12,e13,e14,e15 |
dd e16,e17 |
dd e0,debug_exc,e2,e3 |
dd e4,e5,e6,e7 |
dd e8,e9,e10,e11 |
dd e12,e13,page_fault_handler,e15 |
dd except_16, e17 |
times 14 dd unknown_interrupt |
dd irq0 ,irq1 ,p_irq2 ,p_irq3 ,p_irq4 ,p_irq5,p_irq6 ,p_irq7 |
dd p_irq8,p_irq9,p_irq10,p_irq11,p_irq12,irqD ,p_irq14,p_irq15 |
dd irq0 , irq_serv.irq_1, p_irq2 ,irq_serv.irq_3 |
dd p_irq4 ,irq_serv.irq_5,p_irq6,irq_serv.irq_7 |
dd irq_serv.irq_8, irq_serv.irq_9, irq_serv.irq_10 |
dd irq_serv.irq_11,p_irq12,irqD ,p_irq14,p_irq15 |
times 16 dd unknown_interrupt |
216,7 → 219,7 |
jmp exc_c |
} |
exc_wo_code 0, 1, 2, 3, 4, 5, 6, 9, 15, 16 ; 18, 19 |
exc_wo_code 0, 1, 2, 3, 4, 5, 6, 9, 15 ; 18, 19 |
exc_w_code 8, 10, 11, 12, 13, 14, 17 |
exc_c: |
276,25 → 279,46 |
mov ds, ax |
mov es, ax |
mov eax, [prev_user_of_fpu] |
shl eax, 8 |
add eax, 0x80000 + APPDATA.fpu_save_area |
fsave [eax] |
mov ebx, [fpu_owner] |
cmp ebx, [CURRENT_TASK] |
je .exit |
mov eax, [0x3000] |
mov [prev_user_of_fpu], eax |
shl eax, 8 |
add eax, 0x80000 |
cmp [eax + APPDATA.is_fpu_saved], 0 |
je @f |
frstor [eax+APPDATA.fpu_save_area] |
@@: |
mov [eax + APPDATA.is_fpu_saved], 1 |
shl ebx, 8 |
mov eax, [ebx+PROC_BASE+APPDATA.fpu_state] |
bt [cpu_caps], CAPS_FXSR |
jnc .no_SSE |
fxsave [eax] |
mov ebx, [CURRENT_TASK] |
mov [fpu_owner], ebx |
shl ebx, 8 |
cmp dword [ebx+PROC_BASE+APPDATA.fpu_init], 0 |
je .init |
mov eax, [ebx+PROC_BASE+APPDATA.fpu_state] |
fxrstor [eax] |
restore_ring3_context |
iret |
.init: |
fninit ; ¬ ÂÂ¥ Âã¦Âë Â¥¬ áª¨à ®¢ ÂÂë¥ ¨áª«îç¥Â¨ï |
mov dword [ebx+PROC_BASE+APPDATA.fpu_init], 1 |
.exit: |
restore_ring3_context |
iret |
.no_SSE: |
fnsave [eax] |
mov ebx, [CURRENT_TASK] |
mov [fpu_owner], ebx |
shl ebx, 8 |
cmp dword [ebx+PROC_BASE+APPDATA.fpu_init], 0 |
je .init |
mov eax, [ebx+PROC_BASE+APPDATA.fpu_state] |
frstor [eax] |
restore_ring3_context |
iret |
iglobal |
prev_user_of_fpu dd 1 |
fpu_owner dd 1 |
endg |
611,11 → 635,11 |
cmp eax,1 |
jne .no_application_mem_resize |
jmp new_mem_resize ;resize for new type of processes |
stdcall new_mem_resize, ebx |
mov [esp+36], eax |
ret |
.no_application_mem_resize: |
ret |
732,11 → 756,16 |
call set_application_table_status |
mov eax,esi |
call dispose_app_cr3_table |
cmp [prev_user_of_fpu],esi ; if user fpu last -> fpu user = 1 |
pushad |
shl eax,8 |
mov eax,[PROC_BASE+eax+0xB8] |
stdcall destroy_app_space, eax |
popad |
cmp [fpu_owner],esi ; if user fpu last -> fpu user = 1 |
jne fpu_ok_1 |
mov [prev_user_of_fpu],1 |
mov [fpu_owner],1 |
fpu_ok_1: |
mov [0xf400],byte 0 ; empty keyboard buffer |
/kernel/trunk/core/syscall.inc |
---|
57,7 → 57,7 |
save_syscall_count dd 0x0 |
endg |
label save_syscall_data dword at 0x5000 |
;label save_syscall_data dword at 0x5000 |
iglobal |
132,7 → 132,7 |
dd undefined_syscall ; 57-reserved |
dd file_system ; 58-Common file system interface |
dd sys_trace ; 59-System call trace |
dd new_sys_ipc ; 60-Inter Process Communication |
dd sys_IPC ; 60-Inter Process Communication |
dd sys_gs ; 61-Direct graphics access |
dd sys_pci ; 62-PCI functions |
dd sys_msg_board ; 63-System message board |
140,7 → 140,7 |
dd undefined_syscall ; 65-UTF |
dd sys_process_def ; 66-Process definitions - keyboard |
dd sys_window_move ; 67-Window move or resize |
dd sys_internal_services ; 68-Some internal services |
dd new_services ; 68-Some internal services |
dd sys_debug_services ; 69-Debug |
dd file_system_lfn ; 70-Common file system interface, version 2 |
dd syscall_windowsettings ; 71-Window settings |
/kernel/trunk/core/taskman.inc |
---|
0,0 → 1,1173 |
struc APP_HEADER_00 |
{ .banner dq ? |
.version dd ? ;+8 |
.start dd ? ;+12 |
.i_end dd ? ;+16 |
.mem_size dd ? ;+20 |
.i_param dd ? ;+24 |
} |
struc 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 |
} |
align 4 |
proc test_app_header stdcall, header:dword |
virtual at ebx |
APP_HEADER_00 APP_HEADER_00 |
end virtual |
mov ebx, [header] |
cmp [ebx+6], word '00' |
jne .check_01_header |
mov eax,[APP_HEADER_00.start] |
mov [app_start],eax |
mov eax,[APP_HEADER_00.i_end] |
mov [app_i_end],eax |
mov eax,[APP_HEADER_00.mem_size] |
mov [app_mem],eax |
shr eax,1 |
sub eax,0x10 |
mov [app_esp],eax |
mov eax,[APP_HEADER_00.i_param] |
mov [app_i_param],eax |
mov [app_i_icon],dword 0 |
mov eax,1 |
ret |
.check_01_header: |
virtual at ebx |
APP_HEADER_01 APP_HEADER_01 |
end virtual |
cmp [ebx+6],word '01' |
jne .no_01_header |
mov eax,[APP_HEADER_01.start] |
mov [app_start],eax |
mov eax,[APP_HEADER_01.i_end] |
mov [app_i_end],eax |
mov eax,[APP_HEADER_01.mem_size] |
mov [app_mem],eax |
mov eax,[APP_HEADER_01.stack_top] |
mov [app_esp],eax |
mov eax,[APP_HEADER_01.i_param] |
mov [app_i_param],eax |
mov eax,[APP_HEADER_01.i_icon] |
mov [app_i_icon],eax |
mov eax,1 |
ret |
.no_01_header: |
xor eax, eax |
ret |
endp |
align 4 |
proc get_new_process_place |
;input: |
; none |
;result: |
; eax=[new_process_place]<>0 - ok |
; 0 - failed. |
;This function find least empty slot. |
;It doesn't increase [TASK_COUNT]! |
mov eax,CURRENT_TASK |
mov ebx,[TASK_COUNT] |
inc ebx |
shl ebx,5 |
add ebx,eax ;ebx - address of process information for (last+1) slot |
.newprocessplace: |
;eax = address of process information for current slot |
cmp eax,ebx |
jz .endnewprocessplace ;empty slot after high boundary |
add eax,0x20 |
cmp word [eax+0xa],9 ;check process state, 9 means that process slot is empty |
jnz .newprocessplace |
.endnewprocessplace: |
mov ebx,eax |
sub eax,CURRENT_TASK |
shr eax,5 ;calculate slot index |
cmp eax,256 |
jge .failed ;it should be <256 |
mov word [ebx+0xa],9 ;set process state to 9 (for slot after hight boundary) |
; mov [new_process_place], eax |
ret |
.failed: |
xor eax,eax |
ret |
endp |
align 4 |
proc create_app_space stdcall, app_size:dword,img_size:dword |
locals |
app_pages dd ? |
img_pages dd ? |
dir_addr dd ? |
master_addr dd ? |
app_tabs dd ? |
endl |
stdcall wait_mutex, pg_data.pg_mutex |
xor eax, eax |
mov [dir_addr], eax |
mov [master_addr], eax |
mov eax, [app_size] |
add eax, 4095+4096 |
and eax, NOT(4095) |
mov [app_size], eax |
mov ebx, eax |
shr eax, 12 |
mov [app_pages], eax |
add ebx, 0x3FFFFF |
and ebx, NOT(0x3FFFFF) |
shr ebx, 22 |
mov [app_tabs], ebx |
mov eax, [img_size] |
add eax, 4095 |
and eax, NOT(4095) |
mov [img_size], eax |
shr eax, 12 |
mov [img_pages], eax |
call alloc_page |
test eax, eax |
jz .fail |
mov [dir_addr], eax |
stdcall map_page,[tmp_task_pdir],eax,dword PG_SW |
mov esi, sys_pgdir |
mov edi, [tmp_task_pdir] |
mov ecx, 384 |
cld |
rep movsd |
mov ecx, 384 |
xor eax, eax |
cld |
rep stosd |
mov ecx, 256 |
mov esi, sys_pgdir+0xc00 |
rep movsd |
call alloc_page |
test eax, eax |
jz .fail |
mov [master_addr], eax |
stdcall map_page,[tmp_task_ptab],eax,dword PG_SW |
mov ecx, 384 |
mov edi, [tmp_task_ptab] |
mov esi, master_tab |
cld |
rep movsd |
mov ecx, 384 |
xor eax, eax |
rep stosd |
mov ecx, 256 |
mov esi, master_tab+0xc00 |
rep movsd |
mov eax, [master_addr] |
or eax, PG_SW |
mov ebx, [tmp_task_pdir] |
mov [ebx+0x600], eax |
mov ecx, [tmp_task_ptab] |
mov [ecx+0x600],eax |
mov eax, [dir_addr] |
call set_cr3 |
mov edx, [app_tabs] |
mov edi, new_app_base |
@@: |
call alloc_page |
test eax, eax |
jz .fail |
stdcall map_page_table,[tmp_task_pdir], edi, eax |
add edi, 0x00400000 |
dec edx |
jnz @B |
mov edi, new_app_base |
shr edi, 10 |
add edi, pages_tab |
mov ecx, [app_tabs] |
shl ecx, 10 |
xor eax, eax |
rep stosd |
mov edx, new_app_base |
.alloc: |
call alloc_page |
test eax, eax |
jz .fail |
stdcall map_page,edx,eax,dword PG_UW |
add edx, 0x1000 |
sub [app_pages], 1 |
sub [img_pages], 1 |
jnz .alloc |
mov ecx, [app_pages] |
and ecx, ecx |
jz .next |
mov ebx, edx |
shr edx, 12 |
.reserve: |
mov dword [pages_tab+edx*4], 0x02 |
invlpg [ebx] |
inc edx |
dec ecx |
jnz .reserve |
.next: |
mov edi, new_app_base |
mov ecx, [img_size] |
shr ecx, 2 |
xor eax, eax |
cld |
rep stosd |
stdcall map_page,[tmp_task_ptab],dword 0,dword PG_UNMAP |
stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP |
dec [pg_data.pg_mutex] |
mov eax, [dir_addr] |
ret |
.fail: |
dec [pg_data.pg_mutex] |
cmp [dir_addr], 0 |
jz @f |
stdcall destroy_app_space, [dir_addr] |
@@: |
xor eax, eax |
ret |
endp |
align 4 |
set_cr3: |
mov esi, [CURRENT_TASK] |
mov ebx, esi |
shl esi,8 |
mov [PROC_BASE+esi+0xB8],eax |
imul ebx,tss_step |
add ebx,tss_data |
mov [ebx+28], eax |
mov cr3, eax |
ret |
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 |
call free_page |
.next: |
add esi, 4 |
dec ecx |
jnz .free |
pop esi |
ret |
endp |
align 4 |
proc destroy_app_space stdcall, pg_dir:dword |
stdcall wait_mutex, pg_data.pg_mutex |
xor edx,edx |
mov eax,0x2 |
mov ebx, [pg_dir] |
.loop: |
;eax = current slot of process |
mov ecx,eax |
shl ecx,5 |
cmp byte [CURRENT_TASK+ecx+0xa],9 ;if process running? |
jz @f ;skip empty slots |
shl ecx,3 |
cmp [PROC_BASE+ecx+0xB8],ebx ;compare page directory addresses |
jnz @f |
inc edx ;thread found |
@@: |
inc eax |
cmp eax,[TASK_COUNT] ;exit loop if we look through all processes |
jle .loop |
;edx = number of threads |
;our process is zombi so it isn't counted |
cmp edx,1 |
jg .exit |
;if there isn't threads then clear memory. |
mov eax, [pg_dir] |
and eax, not 0xFFF |
stdcall map_page,[tmp_task_pdir],eax,dword PG_SW |
mov esi, [tmp_task_pdir] |
add esi, 0x600 |
mov eax, [esi] |
call free_page ;destroy master table |
add esi, 4 |
mov edi, 383 |
.destroy: |
mov eax, [esi] |
test eax, 1 |
jz .next |
and eax, not 0xFFF |
stdcall map_page,[tmp_task_ptab],eax,dword PG_SW |
stdcall destroy_page_table, [tmp_task_ptab] |
mov eax, [esi] |
call free_page |
.next: |
add esi, 4 |
dec edi |
jnz .destroy |
mov eax, [pg_dir] |
call free_page |
.exit: |
stdcall map_page,[tmp_task_ptab],dword 0,dword PG_UNMAP |
stdcall map_page,[tmp_task_pdir],dword 0,dword PG_UNMAP |
dec [pg_data.pg_mutex] |
ret |
endp |
align 4 |
proc fs_execute |
;fn_read:dword, file_size:dword, cluster:dword |
; ebx - cmdline |
; edx - flags |
; ebp - full filename |
; [esp+4] = procedure DoRead, [esp+8] = filesize & [esp+12]... - arguments for it |
locals |
cmdline dd ? |
flags dd ? |
filename dd ? |
retval dd ? |
endl |
pushad |
mov [cmdline], ebx |
mov [flags], edx |
mov eax, [ebp] |
mov [filename], eax |
stdcall wait_mutex, pg_data.tmp_task_mutex |
mov edi, [tmp_task_data] |
mov ecx, (2048+256)/4 |
xor eax, eax |
rep stosd |
mov esi, [filename] |
mov edi, [tmp_task_data] |
add edi, TMP_FILE_NAME |
mov ecx, 1024 |
rep movsb |
mov esi, [filename] |
mov edi, [tmp_task_data] |
add edi, TMP_ICON_OFFS |
mov ecx, 1024 |
rep movsb |
mov esi, [cmdline] |
test esi, esi |
jz @f |
mov edi, [tmp_task_data] |
add edi, TMP_CMD_LINE |
mov ecx, 256 |
rep movsb |
@@: |
mov eax, TMP_FILE_NAME |
add eax, [tmp_task_data] |
mov ebx, [tmp_task_data] ;cmd line |
add ebx, TMP_CMD_LINE |
stdcall fs_exec, eax, ebx, [flags], [ebp+8],\ |
[ebp+12], [ebp+16],[ebp+20] |
mov [retval], eax |
popad |
mov [pg_data.tmp_task_mutex], 0 |
mov eax, [retval] |
ret |
endp |
align 4 |
proc fs_exec stdcall file_name:dword, cmd_line:dword, flags:dword,\ |
fn_read:dword, file_size:dword,\ |
cluster:dword, some_data:dword |
locals |
slot dd ? |
app_path_size dd ? |
save_cr3 dd ? |
img_size dd ? |
endl |
; check filename length - with terminating NULL must be no more than 1024 symbols |
mov edi, [file_name] |
mov ecx, 1024 |
xor eax, eax |
repnz scasb |
jz @f |
mov eax, -ERROR_FILE_NOT_FOUND |
ret |
@@: |
sub edi, [file_name] |
mov [app_path_size], edi |
mov esi, new_process_loading |
call sys_msg_board_str ; write message to message board |
pushfd |
cli |
.wait_lock: |
cmp [application_table_status],0 |
je .get_lock |
call change_task |
jmp .wait_lock |
.get_lock: |
mov eax, 1 |
xchg eax, [application_table_status] |
cmp eax, 0 |
jne .wait_lock |
call set_application_table_status |
call get_new_process_place |
test eax, eax |
mov ecx, -0x20 ; too many processes |
jz .err |
mov [slot], eax |
mov edi,eax |
shl edi,8 |
add edi,PROC_BASE |
mov ecx,256/4 |
xor eax,eax |
cld |
rep stosd ;clean extended information about process |
; write application name |
mov edi, [file_name] |
mov ecx, [app_path_size] |
add edi, ecx |
dec edi |
std |
mov al, '/' |
repnz scasb |
cld |
jnz @f |
inc edi |
@@: |
inc edi |
; now edi points to name without path |
mov esi, edi |
mov ecx, 8 ; 8 chars for name |
mov edi, [slot] |
shl edi, cl |
add edi, PROC_BASE |
.copy_process_name_loop: |
lodsb |
cmp al, '.' |
jz .copy_process_name_done |
test al, al |
jz .copy_process_name_done |
stosb |
loop .copy_process_name_loop |
.copy_process_name_done: |
mov al, ' ' |
rep stosb |
pop eax |
mov cl, 3 ; 3 chars for extension |
dec esi |
@@: |
dec eax |
cmp eax, esi |
jbe .copy_process_ext_done |
cmp byte [eax], '.' |
jnz @b |
lea esi, [eax+1] |
.copy_process_ext_loop: |
lodsb |
test al, al |
jz .copy_process_ext_done |
stosb |
loop .copy_process_ext_loop |
.copy_process_ext_done: |
mov al, ' ' |
rep stosb |
; read header |
lea eax, [file_size] |
mov edi, TMP_BUFF |
call [fn_read] |
test eax, eax |
jnz .err |
; check menuet signature |
mov ecx, -0x1F |
;check MENUET signature |
cmp [TMP_BUFF],dword 'MENU' |
jnz .err |
cmp [TMP_BUFF+4],word 'ET' |
jnz .err |
stdcall test_app_header, TMP_BUFF |
test eax, eax |
jz .err |
mov eax, cr3 |
mov [save_cr3], eax |
stdcall create_app_space,[app_mem], [app_mem];[file_size] |
test eax, eax |
jz .failed |
mov ebx,[slot] |
shl ebx,8 |
mov [PROC_BASE+ebx+0xB8],eax |
mov esi, TMP_BUFF |
mov edi, new_app_base |
mov ecx, 512/4 |
cld |
rep movsd |
;read file |
@@: |
lea eax, [file_size] |
cmp dword [eax], 0 |
jz .done |
push edi |
call [fn_read] |
pop edi |
add edi, 512 |
test eax, eax |
jz @b |
cmp ebx, 6 |
jne .failed |
.done: |
stdcall add_app_parameters, [slot], new_app_base,\ |
[cmd_line],[file_name],[flags] |
mov eax, [save_cr3] |
call set_cr3 |
xor eax, eax |
mov [application_table_status],eax ;unlock application_table_status mutex |
popfd |
mov eax,[process_number] ;set result |
ret |
.failed: |
mov eax, [save_cr3] |
call set_cr3 |
.err: |
popfd |
xor eax, eax |
mov [application_table_status],eax |
ret |
endp |
align 4 |
proc add_app_parameters stdcall,slot:dword,img_base:dword,\ |
cmd_line:dword, app_path:dword, flags:dword |
mov eax,[slot] |
bt [cpu_caps], CAPS_SSE |
jnc .no_SSE |
shl eax, 8 |
mov ebx, eax |
add eax, eax |
add eax, [fpu_data] |
mov [ebx+PROC_BASE+APPDATA.fpu_state], eax |
mov [ebx+PROC_BASE+APPDATA.fpu_handler], 0 |
mov [ebx+PROC_BASE+APPDATA.sse_handler], 0 |
jmp .m1 |
.no_SSE: |
mov ecx, eax |
mov ebx, eax |
shl eax, 7 |
shl ebx, 4 |
sub eax, ebx ;eax*=112 |
add eax, [fpu_data] |
shl ecx, 8 |
mov [ecx+PROC_BASE+APPDATA.fpu_state], eax |
mov [ecx+PROC_BASE+APPDATA.fpu_handler], 0 |
mov [ecx+PROC_BASE+APPDATA.sse_handler], 0 |
.m1: |
mov ebx,[slot] |
cmp ebx,[TASK_COUNT] |
jle .noinc |
inc dword [TASK_COUNT] ;update number of processes |
.noinc: |
shl ebx,8 |
mov eax,[app_mem] |
mov [PROC_BASE+0x8c+ebx],eax |
shr ebx,3 |
mov eax, new_app_base |
mov dword [CURRENT_TASK+ebx+0x10],eax |
.add_command_line: |
mov edx,[app_i_param] |
test edx,edx |
jz .no_command_line ;application don't need parameters |
mov eax,[cmd_line] |
test eax,eax |
jz .no_command_line ;no parameters specified |
;calculate parameter length |
xor ecx,ecx |
.command_line_len: |
cmp byte [eax],0 |
jz .command_line_len_end |
inc eax |
inc ecx |
cmp ecx,255 |
jl .command_line_len |
.command_line_len_end: |
;ecx - parameter length |
;edx - address of parameters in new process address space |
inc ecx |
mov edi, [img_base] |
add edi, edx |
mov esi, [cmd_line] |
rep movsb |
.no_command_line: |
mov edx,[app_i_icon] |
test edx,edx |
jz .no_command_line_1 ;application don't need path of file |
mov esi,[app_path] |
test esi, esi |
jz .no_command_line_1 ;application don't need path of file |
mov ecx, 64 |
mov edi, [img_base] |
add edi, edx |
rep movsb |
.no_command_line_1: |
mov ebx,[slot] |
mov eax,ebx |
shl ebx,5 |
add ebx,CURRENT_TASK ;ebx - pointer to information about process |
mov [ebx+0xe],al ;set window number on screen = process slot |
mov [ebx],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 |
mov ecx,ebx |
add ecx,(draw_data-CURRENT_TASK) ;ecx - pointer to draw data |
;set draw data to full screen |
mov [ecx+0],dword 0 |
mov [ecx+4],dword 0 |
mov eax,[SCR_X_SIZE] |
mov [ecx+8],eax |
mov eax,[SCR_Y_SIZE] |
mov [ecx+12],eax |
;set window state to 'normal' (non-minimized/maximized/rolled-up) state |
mov [ecx+WDATA.fl_wstate],WSTATE_NORMAL |
;set cr3 register in TSS of application |
mov ecx,[slot] |
shl ecx,8 |
mov eax,[PROC_BASE+0xB8+ecx] |
;or eax, PG_NOCACHE |
mov [l.cr3],eax |
mov eax,[app_start] |
mov [l.eip],eax ;set eip in TSS |
mov eax,[app_esp] |
mov [l.esp],eax ;set stack in TSS |
;gdt |
mov ax,app_code ;ax - selector of code segment |
mov [l.cs],ax |
mov ax,app_data |
mov [l.ss],ax |
mov [l.ds],ax |
mov [l.es],ax |
mov [l.fs],ax |
mov ax,graph_data ;ax - selector of graphic segment |
mov [l.gs],ax |
mov [l.io],word 128 |
mov [l.eflags],dword 0x3202 |
mov [l.ss0],os_data |
mov ebx,[slot] |
shl ebx,12 |
add ebx,sysint_stack_data+4096 |
mov [l.esp0],ebx |
;copy tss to it place |
mov eax,tss_sceleton |
mov ebx,[slot] |
imul ebx,tss_step |
add ebx,tss_data ;ebx - address of application TSS |
mov ecx,120 |
call memmove |
;Add IO access table - bit array of permitted ports |
or eax,-1 |
mov edi,[slot] |
imul edi,tss_step |
add edi,tss_data+128 |
mov ecx,2048 |
cld |
rep stosd ;full access to 2048*8=16384 ports |
mov ecx,ebx ;ecx - address of application TSS |
mov edi,[slot] |
shl edi,3 |
;set TSS descriptor |
mov [edi+gdts+tss0+0],word tss_step ;limit (size) |
mov [edi+gdts+tss0+2],cx ;part of offset |
mov eax,ecx |
shr eax,16 |
mov [edi+gdts+tss0+4],al ;part of offset |
mov [edi+gdts+tss0+7],ah ;part of offset |
mov [edi+gdts+tss0+5],word 01010000b*256+11101001b ;system flags |
;flush keyboard and buttons queue |
mov [KEY_COUNT],byte 0 |
mov [BTN_COUNT],byte 0 |
mov edi,[slot] |
shl edi,5 |
add edi,window_data |
mov ebx,[slot] |
movzx esi,word [WIN_STACK+ebx*2] |
lea esi,[WIN_POS+esi*2] |
call windowactivate ;gui initialization |
mov ebx,[slot] |
shl ebx,5 |
mov [CURRENT_TASK+ebx+0xa],byte 0 ;set process state - running |
; set if debuggee |
mov eax, [flags] |
test byte [flags], 1 |
jz .no_debug |
mov [CURRENT_TASK+ebx+0xa],byte 1 ;set process state - suspended |
mov eax,[CURRENT_TASK] |
mov [PROC_BASE+ebx*8+0xac],eax ;set debugger PID - current |
.no_debug: |
mov esi,new_process_running |
call sys_msg_board_str ;output information about succefull startup |
ret |
endp |
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,5 |
mov ecx,2*32 |
.loop: |
;ecx=offset of current process info entry |
;ebx=maximum permitted offset |
cmp byte [CURRENT_TASK+ecx+0xa],9 |
jz .endloop ;skip empty slots |
cmp [CURRENT_TASK+ecx+0x4],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,5 |
mov eax,ecx ;convert offset to index of slot |
pop ecx |
pop ebx |
ret |
check_region: |
;input: |
; ebx - start of buffer |
; ecx - size of buffer |
;result: |
; eax = 1 region lays in app memory |
; eax = 0 region don't lays in app memory |
mov eax,[CURRENT_TASK] |
jmp check_process_region |
;----------------------------------------------------------------------------- |
check_process_region: |
;input: |
; eax - slot |
; ebx - start of buffer |
; ecx - size of buffer |
;result: |
; eax = 1 region lays in app memory |
; eax = 0 region don't lays in app memory |
test ecx,ecx |
jle .ok |
shl eax,5 |
cmp word [CURRENT_TASK+eax+0xa],0 |
jnz .failed |
shl eax,3 |
mov eax,[PROC_BASE+eax+0xb8] |
test eax,eax |
jz .failed |
mov eax,1 |
ret |
; call MEM_Get_Linear_Address |
; push ebx |
; push ecx |
; push edx |
; mov edx,ebx |
; and edx,not (4096-1) |
; sub ebx,edx |
; add ecx,ebx |
; mov ebx,edx |
; add ecx,(4096-1) |
; and ecx,not (4096-1) |
;.loop: |
;;eax - linear address of page directory |
;;ebx - current page |
;;ecx - current size |
; mov edx,ebx |
; shr edx,22 |
; mov edx,[eax+4*edx] |
; and edx,not (4096-1) |
; test edx,edx |
; jz .failed1 |
; push eax |
; mov eax,edx |
; call MEM_Get_Linear_Address |
; mov edx,ebx |
; shr edx,12 |
; and edx,(1024-1) |
; mov eax,[eax+4*edx] |
; and eax,not (4096-1) |
; test eax,eax |
; pop eax |
; jz .failed1 |
; add ebx,4096 |
; sub ecx,4096 |
; jg .loop |
; pop edx |
; pop ecx |
; pop ebx |
.ok: |
mov eax,1 |
ret |
; |
;.failed1: |
; pop edx |
; pop ecx |
; pop ebx |
.failed: |
xor eax,eax |
ret |
align 4 |
proc read_process_memory |
;Input: |
; eax - process slot |
; ebx - buffer address |
; ecx - buffer size |
; edx - 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], ebx |
mov [r_count], ecx |
mov [tmp_r_cnt], ecx |
mov [offset], edx |
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 eax, [slot] |
shl eax,8 |
mov ebx, [offset] |
add ebx, new_app_base |
push ecx |
stdcall map_memEx, [proc_mem_map],\ |
[PROC_BASE+eax+0xB8],\ |
ebx, ecx |
pop ecx |
mov esi, [offset] |
and esi, 0xfff |
add esi, [proc_mem_map] |
mov edi, [buff] |
mov edx, ecx |
rep movsb |
add [offset], edx |
sub [tmp_r_cnt], edx |
jnz .read_mem |
popad |
mov eax, [r_count] |
ret |
endp |
align 4 |
proc write_process_memory |
;Input: |
; eax - process slot |
; ebx - buffer address |
; ecx - buffer size |
; edx - 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], ebx |
mov [w_count], ecx |
mov [tmp_w_cnt], ecx |
mov [offset], edx |
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 eax, [slot] |
shl eax,8 |
mov ebx, [offset] |
add ebx, new_app_base |
push ecx |
stdcall map_memEx, [proc_mem_map],\ |
[PROC_BASE+eax+0xB8],\ |
ebx, ecx |
pop ecx |
mov edi, [offset] |
and edi, 0xfff |
add edi, [proc_mem_map] |
mov esi, [buff] |
mov edx, ecx |
rep movsb |
add [offset], edx |
sub [tmp_w_cnt], edx |
jnz .read_mem |
popad |
mov eax, [w_count] |
ret |
endp |
align 4 |
proc new_sys_threads |
locals |
thread_start dd ? |
thread_stack dd ? |
params dd ? |
slot dd ? |
endl |
mov [thread_start], ebx |
mov [thread_stack], ecx |
mov [params], 0 |
xor edx,edx ; flags=0 |
cmp eax,1 |
jnz .failed ;other subfunctions |
mov esi,new_process_loading |
call sys_msg_board_str |
.wait_lock: |
cmp [application_table_status],0 |
je .get_lock |
call change_task |
jmp .wait_lock |
.get_lock: |
mov eax, 1 |
xchg eax, [application_table_status] |
cmp eax, 0 |
jne .wait_lock |
call set_application_table_status |
call get_new_process_place |
test eax, eax |
jz .failed |
mov [slot], eax |
xor eax,eax |
mov [app_i_param],eax |
mov [app_i_icon],eax |
mov ebx, [thread_start] |
mov ecx, [thread_stack] |
mov [app_start],ebx |
mov [app_esp],ecx |
mov esi,[CURRENT_TASK] |
shl esi,8 |
add esi,PROC_BASE |
mov ebx,esi ;ebx=esi - pointer to extended information about current thread |
mov edi,[slot] |
shl edi,8 |
add edi,PROC_BASE |
mov edx,edi ;edx=edi - pointer to extended infomation about new thread |
mov ecx,256/4 |
rep stosd ;clean extended information about new thread |
mov edi,edx |
mov ecx,11 |
rep movsb ;copy process name |
mov eax,[ebx+0x8c] |
mov [app_mem],eax ;set memory size |
mov eax,[ebx+0xb8] |
mov [edx+0xb8],eax ;copy page directory |
stdcall add_app_parameters, [slot], new_app_base,\ |
[params], dword 0,dword 0 |
mov esi,new_process_running |
call sys_msg_board_str ;output information about succefull startup |
mov [application_table_status],0 ;unlock application_table_status mutex |
mov eax,[process_number] ;set result |
ret |
.failed: |
mov [application_table_status],0 |
mov eax,-1 |
ret |
endp |
align 4 |
proc wait_mutex stdcall, mutex:dword |
mov ebx, [mutex] |
.wait_lock: |
cmp dword [ebx],0 |
je .get_lock |
push ebx |
call change_task |
pop ebx |
jmp .wait_lock |
.get_lock: |
mov eax, 1 |
xchg eax, [ebx] |
test eax, eax |
jnz .wait_lock |
ret |
endp |
include "debug.inc" |
iglobal |
new_process_loading db 'K : New Process - loading',13,10,0 |
new_process_running db 'K : New Process - done',13,10,0 |
start_not_enough_memory db 'K : New Process - not enough memory',13,10,0 |
endg |