software task switch, mainly for Viktor.
Posted: Mon Nov 18, 2002 3:23 pm
hello!
i was browsing alt.os.development to get that final knowledge :->> which will make me able to write software task switch and found this nice piece of code by Viktor, so thats why my questions are addressed to him, but i believe that the other guys can help me too.
consider this code :
;example switcher:
entry_XXX:
push IRQ_NUMBER_XXX ; interrupt gate number
jmp kernel_entry
kernel_entry:
push ;regs
mov eax, esp
mov esp, KERNEL_STACK
push eax
call kernel_code_in_c ; DWORD kernel(DWORD* regs);
cmp eax, 0
jz skip_switch
;switch here
mov eax, new_cr3
mov cr3, eax
;the tss is patched by the kernel (A)
;the new esp0 is set regs=new_thread->kernel_stack_ptr;(B)
skip_switch:
pop eax
mov esp, eax
pop ;regs
iret
nice, huh? i have a couple questions :
i believe that after pushing regs and saving/loading stack pointer there could be a code to set data segment regs with kernel data selector.
1.) i would like to know in which case man can skip this step, like Viktor did.
2.) my kernel is mapped to start at 3 gig (0xC0000000) loaded at 1 meg. what happened when i want to use a c function like kernel_code_in_c(), when i have mapped kernel code not in 1:1 ratio. it looks like that to have
access to my kernel data variables i have to reload cr3 with my kernel page dir. thats not very wise, it costs a lot of time. does it mean that to skip reloading cr3 with kernel page dir i cannot have kernel mapped like i have now?
3.) if the kernel is not mapped 1:1 is there any way how to skip reloading cr3 with kernel page dir if i want to work with kernel data, accessing vector of tasks and such stuff?
4.) you (Viktor) are using just one KERNEL_STACK for all threads. does it mean that to have just one kernel stack you need probably have this stack mapped in all user address spaces to point the same physical memory (i think one page is enough for the switcher), because an access to that stack is made through user page dir which is actually loaded?
5.) at line marked with (A) Viktor wrote : tss is patched by the kernel. what does it mean? esp0 in tss (that only one tss we have) set with new_thread->kernel_stack_ptr on line (B)? if so, why to do setting esp with KERNEL_STACK? when cpu detects the ring3 to ring0 transition, the stack pointer is got from tss, or not?
maybe all this questions are wrong.
i am just confused with accessing kernel data in timer_irq when cr3 has user task page dir. maybe accessing through kernel descriptors which's base starts at 3 gig? probably no, address translation will still go through user pdbr.
thanks a lot to everybody which will make this software task switch clear for me.
skoco
i was browsing alt.os.development to get that final knowledge :->> which will make me able to write software task switch and found this nice piece of code by Viktor, so thats why my questions are addressed to him, but i believe that the other guys can help me too.
consider this code :
;example switcher:
entry_XXX:
push IRQ_NUMBER_XXX ; interrupt gate number
jmp kernel_entry
kernel_entry:
push ;regs
mov eax, esp
mov esp, KERNEL_STACK
push eax
call kernel_code_in_c ; DWORD kernel(DWORD* regs);
cmp eax, 0
jz skip_switch
;switch here
mov eax, new_cr3
mov cr3, eax
;the tss is patched by the kernel (A)
;the new esp0 is set regs=new_thread->kernel_stack_ptr;(B)
skip_switch:
pop eax
mov esp, eax
pop ;regs
iret
nice, huh? i have a couple questions :
i believe that after pushing regs and saving/loading stack pointer there could be a code to set data segment regs with kernel data selector.
1.) i would like to know in which case man can skip this step, like Viktor did.
2.) my kernel is mapped to start at 3 gig (0xC0000000) loaded at 1 meg. what happened when i want to use a c function like kernel_code_in_c(), when i have mapped kernel code not in 1:1 ratio. it looks like that to have
access to my kernel data variables i have to reload cr3 with my kernel page dir. thats not very wise, it costs a lot of time. does it mean that to skip reloading cr3 with kernel page dir i cannot have kernel mapped like i have now?
3.) if the kernel is not mapped 1:1 is there any way how to skip reloading cr3 with kernel page dir if i want to work with kernel data, accessing vector of tasks and such stuff?
4.) you (Viktor) are using just one KERNEL_STACK for all threads. does it mean that to have just one kernel stack you need probably have this stack mapped in all user address spaces to point the same physical memory (i think one page is enough for the switcher), because an access to that stack is made through user page dir which is actually loaded?
5.) at line marked with (A) Viktor wrote : tss is patched by the kernel. what does it mean? esp0 in tss (that only one tss we have) set with new_thread->kernel_stack_ptr on line (B)? if so, why to do setting esp with KERNEL_STACK? when cpu detects the ring3 to ring0 transition, the stack pointer is got from tss, or not?
maybe all this questions are wrong.
i am just confused with accessing kernel data in timer_irq when cr3 has user task page dir. maybe accessing through kernel descriptors which's base starts at 3 gig? probably no, address translation will still go through user pdbr.
thanks a lot to everybody which will make this software task switch clear for me.
skoco