forked from KolibriOS/kolibrios
92f657f440
git-svn-id: svn://kolibrios.org@593 a494cfbc-eb01-0410-851d-a64ba20cac60
1140 lines
24 KiB
PHP
1140 lines
24 KiB
PHP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
;; ;;
|
|
;; Copyright (C) KolibriOS team 2004-2007. All rights reserved. ;;
|
|
;; Distributed under terms of the GNU General Public License ;;
|
|
;; ;;
|
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
|
|
|
$Revision$
|
|
|
|
|
|
DRV_COMPAT equ 5 ;minimal required drivers version
|
|
DRV_CURRENT equ 5 ;current drivers model version
|
|
|
|
DRV_VERSION equ (DRV_COMPAT shl 16) or DRV_CURRENT
|
|
|
|
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, app_data ;os_data
|
|
mov ds, bx
|
|
mov es, bx
|
|
|
|
mov ebx, [irq_tab+eax*4]
|
|
test ebx, ebx
|
|
jz .exit
|
|
|
|
call ebx
|
|
mov [check_idle_semaphore],5
|
|
|
|
.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_slot]
|
|
test dword [ebx+APPDATA.event_mask],EVENT_NOTIFY
|
|
jz @f
|
|
and dword [ebx+APPDATA.event_mask], not EVENT_NOTIFY
|
|
mov edi, [p_ev]
|
|
mov dword [edi], EV_INTR
|
|
mov eax, [ebx+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_read16 stdcall, bus:dword, devfn:dword, reg:dword
|
|
xor eax, eax
|
|
xor ebx, ebx
|
|
mov ah, byte [bus]
|
|
mov al, 5
|
|
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
|
|
|
|
align 4
|
|
proc pci_write16 stdcall, bus:dword, devfn:dword, reg:dword, val:dword
|
|
xor eax, eax
|
|
xor ebx, ebx
|
|
mov ah, byte [bus]
|
|
mov al, 9
|
|
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
|
|
|
|
; param
|
|
; ebx= io_control
|
|
;
|
|
; retval
|
|
; eax= error code
|
|
|
|
align 4
|
|
srv_handlerEx:
|
|
cmp ebx, OS_BASE
|
|
jae .fail
|
|
|
|
mov eax, [ebx+handle]
|
|
cmp [eax+SRV.magic], ' SRV'
|
|
jne .fail
|
|
|
|
cmp [eax+SRV.size], SRV_SIZE
|
|
jne .fail
|
|
|
|
stdcall [eax+SRV.srv_proc], ebx
|
|
ret
|
|
.fail:
|
|
or eax, -1
|
|
ret
|
|
|
|
restore handle
|
|
restore io_code
|
|
restore input
|
|
restore inp_size
|
|
restore output
|
|
restore out_size
|
|
|
|
align 4
|
|
proc get_service stdcall, sz_name:dword
|
|
mov eax, [sz_name]
|
|
test eax, eax
|
|
jnz @F
|
|
ret
|
|
@@:
|
|
mov edx, [srv.fd]
|
|
@@:
|
|
cmp edx, srv.fd-SRV_FD_OFFSET
|
|
je .not_load
|
|
|
|
stdcall strncmp, edx, [sz_name], 16
|
|
test eax, eax
|
|
je .ok
|
|
|
|
mov edx, [edx+SRV.fd]
|
|
jmp @B
|
|
.not_load:
|
|
pop ebp
|
|
jmp load_driver
|
|
.ok:
|
|
mov eax, edx
|
|
ret
|
|
endp
|
|
|
|
align 4
|
|
reg_service:
|
|
.sz_name equ esp+4
|
|
.handler equ esp+8
|
|
mov eax, [.sz_name]
|
|
test eax, eax
|
|
jz .fail
|
|
|
|
mov ebx, [.handler]
|
|
test ebx, ebx
|
|
jz .fail
|
|
|
|
mov eax, SRV_SIZE
|
|
call malloc ;call alloc_service
|
|
test eax, eax
|
|
jz .fail
|
|
|
|
mov edi, eax
|
|
mov esi, [.sz_name]
|
|
mov ecx, 16/4
|
|
rep movsd
|
|
|
|
mov [eax+SRV.magic], ' SRV'
|
|
mov [eax+SRV.size], SRV_SIZE
|
|
|
|
mov ebx, srv.fd-SRV_FD_OFFSET
|
|
mov edx, [ebx+SRV.fd]
|
|
mov [eax+SRV.fd], edx
|
|
mov [eax+SRV.bk], ebx
|
|
mov [ebx+SRV.fd], eax
|
|
mov [edx+SRV.bk], eax
|
|
|
|
mov ecx, [.handler]
|
|
mov [eax+SRV.srv_proc], ecx
|
|
ret 8
|
|
.fail:
|
|
xor eax, eax
|
|
ret 8
|
|
|
|
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 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 get_curr_task
|
|
mov eax,[CURRENT_TASK]
|
|
shl eax, 8
|
|
ret
|
|
endp
|
|
|
|
align 4
|
|
proc get_fileinfo stdcall, file_name:dword, info:dword
|
|
locals
|
|
cmd dd ?
|
|
offset dd ?
|
|
dd ?
|
|
count dd ?
|
|
buff dd ?
|
|
db ?
|
|
name dd ?
|
|
endl
|
|
|
|
xor eax, eax
|
|
mov ebx, [file_name]
|
|
; sub ebx, new_app_base
|
|
mov ecx, [info]
|
|
; sub ecx, new_app_base
|
|
|
|
mov [cmd], 5
|
|
mov [offset], eax
|
|
mov [offset+4], eax
|
|
mov [count], eax
|
|
mov [buff], ecx
|
|
mov byte [buff+4], al
|
|
mov [name], ebx
|
|
|
|
mov eax, 70
|
|
lea ebx, [cmd]
|
|
; sub ebx, new_app_base
|
|
int 0x40
|
|
ret
|
|
endp
|
|
|
|
align 4
|
|
proc read_file stdcall,file_name:dword, buffer:dword, off:dword,\
|
|
bytes:dword
|
|
locals
|
|
cmd dd ?
|
|
offset dd ?
|
|
dd ?
|
|
count dd ?
|
|
buff dd ?
|
|
db ?
|
|
name dd ?
|
|
endl
|
|
|
|
xor eax, eax
|
|
mov ebx, [file_name]
|
|
mov ecx, [off]
|
|
mov edx, [bytes]
|
|
mov esi, [buffer]
|
|
|
|
mov [cmd], eax
|
|
mov [offset], ecx
|
|
mov [offset+4], eax
|
|
mov [count], edx
|
|
mov [buff], esi
|
|
mov byte [buff+4], al
|
|
mov [name], ebx
|
|
|
|
pushad
|
|
push eax
|
|
lea eax, [cmd]
|
|
call file_system_lfn
|
|
pop eax
|
|
popad
|
|
ret
|
|
endp
|
|
|
|
; description
|
|
; allocate kernel memory and loads the specified file
|
|
;
|
|
; param
|
|
; file_name= full path to file
|
|
;
|
|
; retval
|
|
; eax= file image in kernel memory
|
|
; ebx= size of file
|
|
;
|
|
; warging
|
|
; You mast call kernel_free() to delete each file
|
|
; loaded by the load_file() function
|
|
|
|
align 4
|
|
proc load_file stdcall, file_name:dword
|
|
locals
|
|
attr dd ?
|
|
flags dd ?
|
|
cr_time dd ?
|
|
cr_date dd ?
|
|
acc_time dd ?
|
|
acc_date dd ?
|
|
mod_time dd ?
|
|
mod_date dd ?
|
|
file_size dd ?
|
|
|
|
file dd ?
|
|
file2 dd ?
|
|
endl
|
|
|
|
lea eax, [attr]
|
|
stdcall get_fileinfo, [file_name], eax
|
|
test eax, eax
|
|
jnz .fail
|
|
|
|
mov eax, [file_size]
|
|
cmp eax, 1024*1024*16
|
|
ja .fail
|
|
|
|
stdcall kernel_alloc, [file_size]
|
|
mov [file], eax
|
|
|
|
stdcall read_file, [file_name], eax, dword 0, [file_size]
|
|
cmp ebx, [file_size]
|
|
jne .cleanup
|
|
|
|
mov eax, [file]
|
|
cmp dword [eax], 0x4B43504B
|
|
jne .exit
|
|
mov ebx, [eax+4]
|
|
mov [file_size], ebx
|
|
stdcall kernel_alloc, ebx
|
|
|
|
test eax, eax
|
|
jz .cleanup
|
|
|
|
mov [file2], eax
|
|
stdcall unpack, [file], eax
|
|
stdcall kernel_free, [file]
|
|
mov eax, [file2]
|
|
mov ebx, [file_size]
|
|
.exit:
|
|
push eax
|
|
lea edi, [eax+ebx] ;cleanup remain space
|
|
mov ecx, 4096 ;from file end
|
|
and ebx, 4095
|
|
jz @f
|
|
sub ecx, ebx
|
|
xor eax, eax
|
|
cld
|
|
rep stosb
|
|
@@:
|
|
mov ebx, [file_size]
|
|
pop eax
|
|
ret
|
|
.cleanup:
|
|
stdcall kernel_free, [file]
|
|
.fail:
|
|
xor eax, eax
|
|
xor ebx, ebx
|
|
ret
|
|
endp
|
|
|
|
align 4
|
|
proc get_proc_ex stdcall, proc_name:dword, imports:dword
|
|
|
|
.look_up:
|
|
mov edx, [imports]
|
|
test edx, edx
|
|
jz .end
|
|
mov edx, [edx]
|
|
test edx, edx
|
|
jz .end
|
|
.next:
|
|
mov eax, [edx]
|
|
test eax, eax
|
|
jz .next_table
|
|
|
|
push edx
|
|
stdcall strncmp, eax, [proc_name], 16
|
|
pop edx
|
|
test eax, eax
|
|
jz .ok
|
|
|
|
add edx,8
|
|
jmp .next
|
|
.next_table:
|
|
add [imports], 4
|
|
jmp .look_up
|
|
.ok:
|
|
mov eax, [edx+4]
|
|
ret
|
|
.end:
|
|
xor eax, eax
|
|
ret
|
|
endp
|
|
|
|
align 4
|
|
proc fix_coff_symbols stdcall, sec:dword, symbols:dword,\
|
|
sym_count:dword, strings:dword, imports:dword
|
|
locals
|
|
retval dd ?
|
|
endl
|
|
|
|
mov edi, [symbols]
|
|
mov [retval], 1
|
|
.fix:
|
|
movzx ebx, [edi+CSYM.SectionNumber]
|
|
test ebx, ebx
|
|
jnz .internal
|
|
mov eax, dword [edi+CSYM.Name]
|
|
test eax, eax
|
|
jnz @F
|
|
|
|
mov edi, [edi+4]
|
|
add edi, [strings]
|
|
@@:
|
|
push edi
|
|
stdcall get_proc_ex, edi,[imports]
|
|
pop edi
|
|
|
|
xor ebx, ebx
|
|
test eax, eax
|
|
jnz @F
|
|
|
|
mov esi, msg_unresolved
|
|
call sys_msg_board_str
|
|
mov esi, edi
|
|
call sys_msg_board_str
|
|
mov esi, msg_CR
|
|
call sys_msg_board_str
|
|
|
|
mov [retval],0
|
|
@@:
|
|
mov edi, [symbols]
|
|
mov [edi+CSYM.Value], eax
|
|
jmp .next
|
|
.internal:
|
|
cmp bx, -1
|
|
je .next
|
|
cmp bx, -2
|
|
je .next
|
|
|
|
dec ebx
|
|
shl ebx, 3
|
|
lea ebx, [ebx+ebx*4]
|
|
add ebx, [sec]
|
|
|
|
mov eax, [ebx+CFS.VirtualAddress]
|
|
add [edi+CSYM.Value], eax
|
|
.next:
|
|
add edi, CSYM_SIZE
|
|
mov [symbols], edi
|
|
dec [sym_count]
|
|
jnz .fix
|
|
mov eax, [retval]
|
|
ret
|
|
endp
|
|
|
|
align 4
|
|
proc fix_coff_relocs stdcall, coff:dword, sec:dword, sym:dword
|
|
locals
|
|
n_sec dd ?
|
|
endl
|
|
|
|
mov eax, [coff]
|
|
movzx ebx, [eax+CFH.nSections]
|
|
mov [n_sec], ebx
|
|
.fix_sec:
|
|
mov esi, [sec]
|
|
mov edi, [esi+CFS.PtrReloc]
|
|
add edi, [coff]
|
|
|
|
movzx ecx, [esi+CFS.NumReloc]
|
|
test ecx, ecx
|
|
jz .next
|
|
.next_reloc:
|
|
mov ebx, [edi+CRELOC.SymIndex]
|
|
add ebx,ebx
|
|
lea ebx,[ebx+ebx*8]
|
|
add ebx, [sym]
|
|
|
|
mov edx, [ebx+CSYM.Value]
|
|
|
|
cmp [edi+CRELOC.Type], 6
|
|
je .dir_32
|
|
|
|
cmp [edi+CRELOC.Type], 20
|
|
jne .next_reloc
|
|
.rel_32:
|
|
mov eax, [edi+CRELOC.VirtualAddress]
|
|
add eax, [esi+CFS.VirtualAddress]
|
|
sub edx, eax
|
|
sub edx, 4
|
|
jmp .fix
|
|
.dir_32:
|
|
mov eax, [edi+CRELOC.VirtualAddress]
|
|
add eax, [esi+CFS.VirtualAddress]
|
|
.fix:
|
|
add [eax], edx
|
|
add edi, 10
|
|
dec ecx
|
|
jnz .next_reloc
|
|
.next:
|
|
add [sec], COFF_SECTION_SIZE
|
|
dec [n_sec]
|
|
jnz .fix_sec
|
|
.exit:
|
|
ret
|
|
endp
|
|
|
|
align 4
|
|
proc load_driver stdcall, driver_name:dword
|
|
locals
|
|
coff dd ?
|
|
sym dd ?
|
|
strings dd ?
|
|
img_size dd ?
|
|
img_base dd ?
|
|
start dd ?
|
|
|
|
exports dd ? ;fake exports table
|
|
dd ?
|
|
file_name rb 13+16+4+1 ; '/sys/drivers/<up-to-16-chars>.obj'
|
|
endl
|
|
|
|
lea edx, [file_name]
|
|
mov dword [edx], '/sys'
|
|
mov dword [edx+4], '/dri'
|
|
mov dword [edx+8], 'vers'
|
|
mov byte [edx+12], '/'
|
|
mov esi, [driver_name]
|
|
lea edi, [edx+13]
|
|
mov ecx, 16
|
|
@@:
|
|
lodsb
|
|
test al, al
|
|
jz @f
|
|
stosb
|
|
loop @b
|
|
@@:
|
|
mov dword [edi], '.obj'
|
|
mov byte [edi+4], 0
|
|
stdcall load_file, edx
|
|
|
|
test eax, eax
|
|
jz .exit
|
|
|
|
mov [coff], eax
|
|
|
|
movzx ecx, [eax+CFH.nSections]
|
|
xor ebx, ebx
|
|
|
|
lea edx, [eax+20]
|
|
@@:
|
|
add ebx, [edx+CFS.SizeOfRawData]
|
|
add ebx, 15
|
|
and ebx, not 15
|
|
add edx, COFF_SECTION_SIZE
|
|
dec ecx
|
|
jnz @B
|
|
mov [img_size], ebx
|
|
|
|
stdcall kernel_alloc, ebx
|
|
test eax, eax
|
|
jz .fail
|
|
mov [img_base], eax
|
|
|
|
mov edi, eax
|
|
xor eax, eax
|
|
mov ecx, [img_size]
|
|
add ecx, 4095
|
|
and ecx, not 4095
|
|
shr ecx, 2
|
|
cld
|
|
rep stosd
|
|
|
|
mov edx, [coff]
|
|
movzx ebx, [edx+CFH.nSections]
|
|
mov edi, [img_base]
|
|
lea eax, [edx+20]
|
|
@@:
|
|
mov [eax+CFS.VirtualAddress], edi
|
|
mov esi, [eax+CFS.PtrRawData]
|
|
test esi, esi
|
|
jnz .copy
|
|
add edi, [eax+CFS.SizeOfRawData]
|
|
jmp .next
|
|
.copy:
|
|
add esi, edx
|
|
mov ecx, [eax+CFS.SizeOfRawData]
|
|
cld
|
|
rep movsb
|
|
.next:
|
|
add edi, 15
|
|
and edi, not 15
|
|
add eax, COFF_SECTION_SIZE
|
|
dec ebx
|
|
jnz @B
|
|
|
|
mov ebx, [edx+CFH.pSymTable]
|
|
add ebx, edx
|
|
mov [sym], ebx
|
|
mov ecx, [edx+CFH.nSymbols]
|
|
add ecx,ecx
|
|
lea ecx,[ecx+ecx*8] ;ecx*=18 = nSymbols*CSYM_SIZE
|
|
add ecx, [sym]
|
|
mov [strings], ecx
|
|
|
|
lea ebx, [exports]
|
|
mov dword [ebx], kernel_export
|
|
mov dword [ebx+4], 0
|
|
lea eax, [edx+20]
|
|
|
|
stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols],\
|
|
[strings], ebx
|
|
test eax, eax
|
|
jz .link_fail
|
|
|
|
mov ebx, [coff]
|
|
add ebx, 20
|
|
stdcall fix_coff_relocs, [coff], ebx, [sym]
|
|
|
|
mov ebx, [coff]
|
|
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szVersion
|
|
test eax, eax
|
|
jz .link_fail
|
|
|
|
mov eax, [eax]
|
|
shr eax, 16
|
|
cmp eax, DRV_COMPAT
|
|
jb .ver_fail
|
|
|
|
cmp eax, DRV_CURRENT
|
|
ja .ver_fail
|
|
|
|
mov ebx, [coff]
|
|
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szSTART
|
|
mov [start], eax
|
|
|
|
stdcall kernel_free, [coff]
|
|
|
|
mov ebx, [start]
|
|
stdcall ebx, DRV_ENTRY
|
|
test eax, eax
|
|
jnz .ok
|
|
|
|
stdcall kernel_free, [img_base]
|
|
xor eax, eax
|
|
ret
|
|
.ok:
|
|
mov ebx, [img_base]
|
|
mov [eax+SRV.base], ebx
|
|
mov ecx, [start]
|
|
mov [eax+SRV.entry], ecx
|
|
ret
|
|
|
|
.ver_fail:
|
|
mov esi, msg_CR
|
|
call sys_msg_board_str
|
|
mov esi, [driver_name]
|
|
call sys_msg_board_str
|
|
mov esi, msg_CR
|
|
call sys_msg_board_str
|
|
mov esi, msg_version
|
|
call sys_msg_board_str
|
|
mov esi, msg_www
|
|
call sys_msg_board_str
|
|
jmp .cleanup
|
|
|
|
.link_fail:
|
|
mov esi, msg_module
|
|
call sys_msg_board_str
|
|
mov esi, [driver_name]
|
|
call sys_msg_board_str
|
|
mov esi, msg_CR
|
|
call sys_msg_board_str
|
|
.cleanup:
|
|
stdcall kernel_free,[img_base]
|
|
.fail:
|
|
stdcall kernel_free, [coff]
|
|
.exit:
|
|
xor eax, eax
|
|
ret
|
|
endp
|
|
|
|
align 4
|
|
proc load_library stdcall, file_name:dword
|
|
locals
|
|
coff dd ?
|
|
sym dd ?
|
|
strings dd ?
|
|
img_size dd ?
|
|
img_base dd ?
|
|
exports dd ?
|
|
endl
|
|
|
|
cli
|
|
|
|
stdcall load_file, [file_name]
|
|
test eax, eax
|
|
jz .fail
|
|
|
|
mov [coff], eax
|
|
movzx ecx, [eax+CFH.nSections]
|
|
xor ebx, ebx
|
|
|
|
lea edx, [eax+20]
|
|
@@:
|
|
add ebx, [edx+CFS.SizeOfRawData]
|
|
add ebx, 15
|
|
and ebx, not 15
|
|
add edx, COFF_SECTION_SIZE
|
|
dec ecx
|
|
jnz @B
|
|
mov [img_size], ebx
|
|
|
|
call init_heap
|
|
stdcall user_alloc, [img_size]
|
|
|
|
test eax, eax
|
|
jz .fail
|
|
mov [img_base], eax
|
|
|
|
mov edx, [coff]
|
|
movzx ebx, [edx+CFH.nSections]
|
|
mov edi, [img_base]
|
|
lea eax, [edx+20]
|
|
@@:
|
|
mov [eax+CFS.VirtualAddress], edi
|
|
mov esi, [eax+CFS.PtrRawData]
|
|
test esi, esi
|
|
jnz .copy
|
|
add edi, [eax+CFS.SizeOfRawData]
|
|
jmp .next
|
|
.copy:
|
|
add esi, edx
|
|
; add edi, new_app_base
|
|
mov ecx, [eax+CFS.SizeOfRawData]
|
|
cld
|
|
rep movsb
|
|
.next:
|
|
add edi, 15 ;-new_app_base
|
|
and edi, -16
|
|
add eax, COFF_SECTION_SIZE
|
|
dec ebx
|
|
jnz @B
|
|
|
|
mov ebx, [edx+CFH.pSymTable]
|
|
add ebx, edx
|
|
mov [sym], ebx
|
|
mov ecx, [edx+CFH.nSymbols]
|
|
add ecx,ecx
|
|
lea ecx,[ecx+ecx*8] ;ecx*=18 = nSymbols*CSYM_SIZE
|
|
add ecx, [sym]
|
|
mov [strings], ecx
|
|
|
|
lea eax, [edx+20]
|
|
|
|
stdcall fix_coff_symbols, eax, [sym], [edx+CFH.nSymbols],\
|
|
[strings], dword 0
|
|
test eax, eax
|
|
jnz @F
|
|
|
|
@@:
|
|
mov edx, [coff]
|
|
movzx ebx, [edx+CFH.nSections]
|
|
mov edi, new_app_base
|
|
lea eax, [edx+20]
|
|
@@:
|
|
add [eax+CFS.VirtualAddress], edi ;patch user space offset
|
|
add eax, COFF_SECTION_SIZE
|
|
dec ebx
|
|
jnz @B
|
|
|
|
add edx, 20
|
|
stdcall fix_coff_relocs, [coff], edx, [sym]
|
|
|
|
mov ebx, [coff]
|
|
stdcall get_coff_sym,[sym],[ebx+CFH.nSymbols],szEXPORTS
|
|
mov [exports], eax
|
|
|
|
stdcall kernel_free, [coff]
|
|
mov eax, [exports]
|
|
ret
|
|
.fail:
|
|
xor eax, eax
|
|
ret
|
|
endp
|
|
|
|
align 4
|
|
proc stop_all_services
|
|
|
|
mov edx, [srv.fd]
|
|
.next:
|
|
cmp edx, srv.fd-SRV_FD_OFFSET
|
|
je .done
|
|
cmp [edx+SRV.magic], ' SRV'
|
|
jne .next
|
|
cmp [edx+SRV.size], SRV_SIZE
|
|
jne .next
|
|
mov ebx, [edx+SRV.entry]
|
|
mov edx, [edx+SRV.fd]
|
|
push edx
|
|
stdcall ebx, dword -1
|
|
pop edx
|
|
jmp .next
|
|
.done:
|
|
ret
|
|
endp
|
|
|
|
; param
|
|
; eax= size
|
|
; ebx= pid
|
|
|
|
align 4
|
|
create_kernel_object:
|
|
|
|
push ebx
|
|
call malloc
|
|
pop ebx
|
|
test eax, eax
|
|
jz .fail
|
|
|
|
mov ecx,[current_slot]
|
|
add ecx, APP_OBJ_OFFSET
|
|
|
|
pushfd
|
|
cli
|
|
mov edx, [ecx+APPOBJ.fd]
|
|
mov [eax+APPOBJ.fd], edx
|
|
mov [eax+APPOBJ.bk], ecx
|
|
mov [eax+APPOBJ.pid], ebx
|
|
|
|
mov [ecx+APPOBJ.fd], eax
|
|
mov [edx+APPOBJ.bk], eax
|
|
popfd
|
|
.fail:
|
|
ret
|
|
|
|
; param
|
|
; eax= object
|
|
|
|
align 4
|
|
destroy_kernel_object:
|
|
|
|
pushfd
|
|
cli
|
|
mov ebx, [eax+APPOBJ.fd]
|
|
mov ecx, [eax+APPOBJ.bk]
|
|
mov [ebx+APPOBJ.bk], ecx
|
|
mov [ecx+APPOBJ.fd], ebx
|
|
popfd
|
|
|
|
xor edx, edx ;clear common header
|
|
mov [eax], edx
|
|
mov [eax+4], edx
|
|
mov [eax+8], edx
|
|
mov [eax+12], edx
|
|
mov [eax+16], edx
|
|
|
|
call free ;release object memory
|
|
ret
|
|
|
|
|
|
|
|
if 0
|
|
|
|
irq:
|
|
|
|
.irq0:
|
|
pusfd
|
|
pushad
|
|
push IRQ_0
|
|
jmp .master
|
|
.irq_1:
|
|
pusfd
|
|
pushad
|
|
push IRQ_1
|
|
jmp .master
|
|
|
|
.master:
|
|
mov ax, app_data
|
|
mov ds, eax
|
|
mov es, eax
|
|
mov ebx, [esp+4] ;IRQ_xx
|
|
mov eax, [irq_handlers+ebx+4]
|
|
call intr_handler
|
|
mov ecx, [esp+4]
|
|
cmp [irq_actids+ecx*4], 0
|
|
je @F
|
|
in al, 0x21
|
|
bts eax, ecx
|
|
out 0x21, al
|
|
mov al, 0x20
|
|
out 0x20, al
|
|
jmp .restart
|
|
|
|
.slave:
|
|
mov ax, app_data
|
|
mov ds, eax
|
|
mov es, eax
|
|
mov ebx, [esp+4] ;IRQ_xx
|
|
mov eax, [irq_handlers+ebx+4]
|
|
call intr_handler
|
|
mov ecx, [esp+4]
|
|
sub ecx, 8
|
|
cmp [irq_actids+ecx*4], 0
|
|
je @F
|
|
in al, 0xA1
|
|
bts eax, ecx
|
|
out 0xA1, al
|
|
mov al, 0x20
|
|
out 0xA0, al
|
|
out 0x20, al
|
|
.restart:
|
|
mov ebx, [next_slot]
|
|
test ebx, ebx
|
|
jz @F
|
|
mov [next_task],0
|
|
mov esi, [prev_slot]
|
|
call do_change_task
|
|
add esp, 4
|
|
iretd
|
|
|
|
end if
|
|
|
|
|
|
|
|
|