· Начало · Отвђтить · Статистика · Поиск · FAQ · Правила · Установки · Язык · Выход · WASM.RU · Noir.Ru ·

 WASM Phorum —› WASM.ASSEMBLER —› ядро оси

Посл.отвђт Сообщенiе


Дата: Мар 25, 2004 16:35:43

ядро начинается с 0хffff8000, по адресу 0xffffa000 APIC
по адресу 0xffffc000 таблица индексов процесса
по адресу 0xffffe000 битве маски lockов, разрешений посылки сигнала и ожидания сигнала
0xfffff000 зарезервировано пока
собсна что хоцца может кто баги найдет или заинересуется осью
.text
//0xffff8000
.align 4096
idt__:
//IDT
.irpc num0,89abcdef
.irpc num1,0123456789abcdef
.irpc num2,08
.long 0x00108\num0\num1\num2
.long 0xffff8e00
.endr
.endr
.endr
//IDT dispatcher
.irp num,0,1,2,3,4,5,6,7
.align 8
pushl %eax
.byte 0x6a,\num
jmp ih0
.endr
.align 8,0x90
.byte 0x6a,0x8
jmp ih0
.align 8,0x90
pushl %eax
.byte 0x6a,0x9
jmp ih0
.irp num,10,11,12,13,14
.align 8,0x90
.byte 0x6a,\num
jmp ih0
.endr
.align 8,0x90
pushl %eax
.byte 0x6a,0xf
jmp ih0
.align 8,0x90
pushl %eax
.byte 0x6a,0x10
jmp ih0
.align 8,0x90
.byte 0x6a,0x11
jmp ih0
.irp num,18,19,20,21,22,23,24,25,26,27,28,29,30,31
.align 8,0x90
pushl %eax
.byte 0x6a,\num
jmp ih0
.endr
.irpc num0,23456789abcdef
.irpc num1,0123456789abcdef
pushl %eax
.byte 0x6a, 0x\num0\num1
jmp ih0
.endr
.endr
.align 4096
ih0:
//save general purpose registers
pushal
push %ds
push %es
push %fs
push %gs
//set default kernel-mode data segment
push %ss
pop %ds
movl 48(%esp),%ecx
andl $0xff,%ecx
movl %ecx,48(%esp)
//save page fault address if needed
movl %cr2,%eax
pushl %eax

xorl %edx,%edx
bt %ecx,0xffffa100
setcb %dl
#ifdef WITH_APIC
jnc no_eoi_needed
movl $0,0xffffa0b0
no_eoi_needed:
//read apic id
movl 0xffffa020,%eax
shrl $24,%eax
andl $0xf,%eax
#else
xorl %eax,%eax
#endif
pushl %edx
pushl %eax

movl 44(%esp),%eax
movb 0xffffb000(,%eax,8),%dl
decb %dl
js exec_laddr
jz switch_process
subb $2,%dl
js switch_process_ex
jz send_signal
jmp syscall
.align 8
send_signal:
movl 0xffffb004(,%eax,8),%esi

lock
incl (%esi)
jng raise_thread2
lock
incl 0xffffc004

addl $16,%esi
jmp wait
.align 8
raise_thread2:
movl 8(%esi),%edx
//edx=first waiting
movl 8(%edx),%ebx
//edx first->next
movl 12(%edx),%ecx
//ecx=first->prev

movl %ecx,12(%edx )
//next->prev=next
movl %edx,8(%ecx)
//prev->next=prev

movl %ebx,8(%esi)
//first=next

//activate thread
movl $0x1,(%esi)

addl $16,%esi
jmp wait
.align 8
complete:
addl $8,%esp
pop %gs
pop %fs
pop %es
pop %ds
popal
addl $8,%esp
iret
.align 8
exec_laddr:
//get user stack address
movl 68(%esp),%esi
movl 64(%esp),%edi
movw %di,%gs
subl $8,%edi
//save caller cs:eip
movl 52(%esp),%ebx
.byte 0x65
movl %ebx,(%edi)
movl 56(%esp),%ebx
.byte 0x65
movl %ebx,4(%edi)
//load new cs:eip
movzwl 0xffffb002(,%eax,8),%edx
movl 0xffffb004(,%eax,8),%eax
movl %edx,52(%esp)
movl %eax,56(%esp)
jmp complete
.align 64
switch_process_ex:
movl 40(%esp),%edx
jmp do_switch
.align 8
switch_process:
movl 0xffffb004(,%eax,8),%edx
.align 8
do_switch:
movl %esp,%ebx
andl $0xfffffc00,%ebx
#ifdef WITH_SSE
fxsave (%ebx)
#else
fsave (%ebx)
#endif
//get current thread index and minimal thread index
movl 512(%ebx),%eax
movl %esp,512(%ebx)
//mark thread as idle
movl 0xffffc000(,%eax,4),%edi
andl $0xcfffffff,(%esi)
//switch process to %edx
movl %edx,%cr3
xorl %eax,%eax
jmp do_scan
.align 64
switch_thread:
//assumed that at least one is ready to run
movl %esp,%ebx
andl $0xfffffc00,%ebx
#ifdef WITH_SSE
fxsave (%ebx)
#else
fsave (%ebx)
#endif
//get current thread index and minimal thread index
movl 512(%ebx),%eax
movl %esp,512(%ebx)
//mark thread as idle
movl 0xffffc000(,%eax,4),%edi
andl $0xcfffffff,(%esi)

jmp do_scan
rep_scan:
btc %eax,0xffffe000
//scan for new thread r2r
do_scan:

//but before scanning check if there are threads to run
lock
decl 0xffffc004
jns no_deac
//there is at least one thread and we will find it
//no threads are available to run
int $0xff
jmp complete
no_deac:
decl %eax
testl %eax,%eax
jne no_adj
movl $2047,%eax
no_adj:
//lock pointer to avoid deletion while it is in use
lock
bts %eax,0xffffe000
jc no_adj
//check if object was deleted
movl 0xffffc000(,%eax,4),%esi
testl %esi,%esi
jz rep_scan
//check if thread is waiting for event and cannot run
//event counter will be 0 if thread was ready
//check if thread is already running or is marked as stopped
cmp $0x0, (%esi)
je rep_scan
//mark it as running
lock
orl $0x40000000,(%esi)
//read new stack pointer
movl 4(%esi),%ebx
movl 512(%ebx),%esp
#ifdef WITH_SSE
fxrstor (%ebx)
#else
frstor (%ebx)
#endif
//save current thread index
movl %eax,512(%ebx)
jmp complete

.align 8
syscall:
movl 40(%esp),%edx
cmpl $4,%edx
je switch_thread
//read ecx
movl 36(%esp),%eax
cmpl $1023,%eax
ja __error
cmpl $2,%eax
jb __error
//lock pointer to avoid deletion while it is in use
lock0:
lock
bts %eax,0xffffe000
jc lock0
//check if object not exist
movl 0xffffc000(,%eax,4),%esi
testl %esi,%esi
jz __error_with_unlock
//check whnat should we do?
decl %edx
js __wait
jz __send
// get wait number
__query:
movl (%edi),%ebx
movl %ebx,40(%esp)
btc %eax,0xffffe000
jmp complete
//__send
.align 8
__send:
bt %eax,0xffffe100
jnc __error1
cmpl $0x7fffffff,(%esi)
je __error2
lock
incl (%esi)
jng raise_thread
lock
incl 0xffffc004
btc %eax,0xffffe000
jmp complete
.align 8
raise_thread:
movl 8(%esi),%edx
//edx=first waiting
movl 8(%edx),%ebx
//edx first->next
movl 12(%edx),%ecx
//ecx=first->prev

movl %ecx,12(%edx )
//next->prev=next
movl %edx,8(%ecx)
//prev->next=prev

movl %ebx,8(%esi)
//first=next

//activate thread
movl $0x1,(%esi)

btc %eax,0xffffe000
jmp complete
//__wait
.align 8
__wait:
//check if we should wait
bt %eax,0xffffe200
jnc __error1
lock
decl (%edi)
jns no_wait
jz simple_insert
//get thread object offset
movl %esp,%ebx
andl $0xfffffc00,%ebx
movl 512(%ebx),%edi
movl 0xffffc000(,%edi,4),%edi
//insert to wait queue
movl 8(%esi),%edx
movl %edx,8(%edi)
//next=queue

movl 12(%edx),%ebx
//tmp=queue->prev
movl %edi,12(%edx)
//queue->prev=this
movl %ebx,12(%edi)
//prev=tmp
movl %edi,8(%ebx)
//prer->next=this

movl $0x0,(%edi)

lock
decl 0xffffc004
//unlock object
btc %eax,0xffffe000
jmp switch_thread
no_wait:
btc %eax,0xffffe000
jmp complete
simple_insert:
//get thread object offset
movl %esp,%ebx
andl $0xfffffc00,%ebx
movl 512(%ebx),%edi
movl 0xffffc000(,%edi,4),%edi
movl %edi,8(%edi)
movl %edi,12(%edi)
movl %edi,8(%esi)
movl $0x0,(%edi)
//unlock object
lock
decl 0xffffc004

btc %eax,0xffffe000

jmp switch_thread
__error_with_unlock:
btc %eax,0xffffe000
__error:
movl $-1,40(%esp)
jmp complete
__error2:
movl $-2,40(%esp)
jmp complete


Дата: Мар 25, 2004 16:49:13

а вот и первые баги - при подсчете смещений с стеке забыл про
push ds
push es
push fs
push gs
и везде ошибка на 16 байт
.text
//0xffff8000
.align 4096
idt__:
//IDT
.irpc num0,89abcdef
.irpc num1,0123456789abcdef
.irpc num2,08
.long 0x00108\num0\num1\num2
.long 0xffff8e00
.endr
.endr
.endr
//IDT dispatcher
.irp num,0,1,2,3,4,5,6,7
.align 8
pushl %eax
.byte 0x6a,\num
jmp ih0
.endr
.align 8,0x90
.byte 0x6a,0x8
jmp ih0
.align 8,0x90
pushl %eax
.byte 0x6a,0x9
jmp ih0
.irp num,10,11,12,13,14
.align 8,0x90
.byte 0x6a,\num
jmp ih0
.endr
.align 8,0x90
pushl %eax
.byte 0x6a,0xf
jmp ih0
.align 8,0x90
pushl %eax
.byte 0x6a,0x10
jmp ih0
.align 8,0x90
.byte 0x6a,0x11
jmp ih0
.irp num,18,19,20,21,22,23,24,25,26,27,28,29,30,31
.align 8,0x90
pushl %eax
.byte 0x6a,\num
jmp ih0
.endr
.irpc num0,23456789abcdef
.irpc num1,0123456789abcdef
pushl %eax
.byte 0x6a, 0x\num0\num1
jmp ih0
.endr
.endr
.align 4096
ih0:
//save general purpose registers
pushal
push %ds
push %es
push %fs
push %gs
//set default kernel-mode data segment
push %ss
pop %ds
movl 60(%esp),%ecx
andl $0xff,%ecx
movl %ecx,60(%esp)
//save page fault address if needed
movl %cr2,%eax
pushl %eax

xorl %edx,%edx
bt %ecx,0xffffa100
setcb %dl
#ifdef WITH_APIC
jnc no_eoi_needed
movl $0,0xffffa0b0
no_eoi_needed:
//read apic id
movl 0xffffa020,%eax
shrl $24,%eax
andl $0xf,%eax
#else
xorl %eax,%eax
#endif
pushl %edx
pushl %eax

movl 60(%esp),%eax
movb 0xffffb000(,%eax,8),%dl
decb %dl
js exec_laddr
jz switch_process
subb $2,%dl
js switch_process_ex
jz send_signal
jmp syscall
.align 8
send_signal:
movl 0xffffb004(,%eax,8),%esi

lock
incl (%esi)
jng raise_thread2
lock
incl 0xffffc004

addl $16,%esi
jmp wait
.align 8
raise_thread2:
movl 8(%esi),%edx
//edx=first waiting
movl 8(%edx),%ebx
//edx first->next
movl 12(%edx),%ecx
//ecx=first->prev

movl %ecx,12(%edx )
//next->prev=next
movl %edx,8(%ecx)
//prev->next=prev

movl %ebx,8(%esi)
//first=next

//activate thread
movl $0x1,(%esi)

addl $16,%esi
jmp wait
.align 8
complete:
addl $8,%esp
pop %gs
pop %fs
pop %es
pop %ds
popal
addl $8,%esp
iret
.align 8
exec_laddr:
//get user stack address
movl 84(%esp),%esi
movl 80(%esp),%edi
movw %di,%gs
subl $8,%edi
//save caller cs:eip
movl 68(%esp),%ebx
.byte 0x65
movl %ebx,(%edi)
movl 72(%esp),%ebx
.byte 0x65
movl %ebx,4(%edi)
//load new cs:eip
movzwl 0xffffb002(,%eax,8),%edx
movl 0xffffb004(,%eax,8),%eax
movl %edx,68(%esp)
movl %eax,72(%esp)
jmp complete
.align 64
switch_process_ex:
movl 56(%esp),%edx
jmp do_switch
.align 8
switch_process:
movl 0xffffb004(,%eax,8),%edx
.align 8
do_switch:
movl %esp,%ebx
andl $0xfffffc00,%ebx
#ifdef WITH_SSE
fxsave (%ebx)
#else
fsave (%ebx)
#endif
//get current thread index and minimal thread index
movl 512(%ebx),%eax
movl %esp,512(%ebx)
//mark thread as idle
movl 0xffffc000(,%eax,4),%edi
andl $0xcfffffff,(%esi)
//switch process to %edx
movl %edx,%cr3
xorl %eax,%eax
jmp do_scan
.align 64
switch_thread:
//assumed that at least one is ready to run
movl %esp,%ebx
andl $0xfffffc00,%ebx
#ifdef WITH_SSE
fxsave (%ebx)
#else
fsave (%ebx)
#endif
//get current thread index and minimal thread index
movl 512(%ebx),%eax
movl %esp,512(%ebx)
//mark thread as idle
movl 0xffffc000(,%eax,4),%edi
andl $0xcfffffff,(%esi)

jmp do_scan
rep_scan:
btc %eax,0xffffe000
//scan for new thread r2r
do_scan:

//but before scanning check if there are threads to run
lock
decl 0xffffc004
jns no_deac
//there is at least one thread and we will find it
//no threads are available to run
int $0xff
jmp complete
no_deac:
decl %eax
testl %eax,%eax
jne no_adj
movl $2047,%eax
no_adj:
//lock pointer to avoid deletion while it is in use
lock
bts %eax,0xffffe000
jc no_adj
//check if object was deleted
movl 0xffffc000(,%eax,4),%esi
testl %esi,%esi
jz rep_scan
//check if thread is waiting for event and cannot run
//event counter will be 0 if thread was ready
//check if thread is already running or is marked as stopped
cmp $0x0, (%esi)
je rep_scan
//mark it as running
lock
orl $0x40000000,(%esi)
//read new stack pointer
movl 4(%esi),%ebx
movl 512(%ebx),%esp
#ifdef WITH_SSE
fxrstor (%ebx)
#else
frstor (%ebx)
#endif
//save current thread index
movl %eax,512(%ebx)
jmp complete

.align 8
syscall:
movl 56(%esp),%edx
cmpl $4,%edx
je switch_thread
//read ecx
movl 52(%esp),%eax
cmpl $1023,%eax
ja __error
cmpl $2,%eax
jb __error
//lock pointer to avoid deletion while it is in use
lock0:
lock
bts %eax,0xffffe000
jc lock0
//check if object not exist
movl 0xffffc000(,%eax,4),%esi
testl %esi,%esi
jz __error_with_unlock
//check whnat should we do?
decl %edx
js __wait
jz __send
// get wait number
__query:
movl (%edi),%ebx
movl %ebx,56(%esp)
btc %eax,0xffffe000
jmp complete
//__send
.align 8
__send:
bt %eax,0xffffe100
jnc __error1
cmpl $0x7fffffff,(%esi)
je __error2
lock
incl (%esi)
jng raise_thread
lock
incl 0xffffc004
btc %eax,0xffffe000
jmp complete
.align 8
raise_thread:
movl 8(%esi),%edx
//edx=first waiting
movl 8(%edx),%ebx
//edx first->next
movl 12(%edx),%ecx
//ecx=first->prev

movl %ecx,12(%edx )
//next->prev=next
movl %edx,8(%ecx)
//prev->next=prev

movl %ebx,8(%esi)
//first=next

//activate thread
movl $0x1,(%esi)

btc %eax,0xffffe000
jmp complete
//__wait
.align 8
__wait:
//check if we should wait
bt %eax,0xffffe200
jnc __error1
lock
decl (%edi)
jns no_wait
jz simple_insert
//get thread object offset
movl %esp,%ebx
andl $0xfffffc00,%ebx
movl 512(%ebx),%edi
movl 0xffffc000(,%edi,4),%edi
//insert to wait queue
movl 8(%esi),%edx
movl %edx,8(%edi)
//next=queue

movl 12(%edx),%ebx
//tmp=queue->prev
movl %edi,12(%edx)
//queue->prev=this
movl %ebx,12(%edi)
//prev=tmp
movl %edi,8(%ebx)
//prer->next=this

movl $0x0,(%edi)

lock
decl 0xffffc004
//unlock object
btc %eax,0xffffe000
jmp switch_thread
no_wait:
btc %eax,0xffffe000
jmp complete
simple_insert:
//get thread object offset
movl %esp,%ebx
andl $0xfffffc00,%ebx
movl 512(%ebx),%edi
movl 0xffffc000(,%edi,4),%edi
movl %edi,8(%edi)
movl %edi,12(%edi)
movl %edi,8(%esi)
movl $0x0,(%edi)
//unlock object
lock
decl 0xffffc004

btc %eax,0xffffe000

jmp switch_thread
__error_with_unlock:
btc %eax,0xffffe000
__error:
movl $-1,40(%esp)
jmp complete
__error2:
movl $-2,40(%esp)
jmp complete


Powered by miniBB 1.6 © 2001-2002
Время загрузки страницы (сек.): 0.083