i have two fuction switch_contexts_asm and switch_contexts_with_iret_asm that do the context switching. The switch_contexts_with_iret_asm is the function that is used to switch to a newly created thread and switch_contexts is what is normally used. Each function takes two arguments. %eax is a pointer to the thread structure and %ebx is a pointer to the pointer of the current thread for the current processor(i don't have smp but i took this step to get ready for it)..
Oh yeah, BTW, i know that it works to switch from userspace to kernel threads because if i override my scheduler to switch into my idle process(part of the kernel) before the next thread, it works perfectly.
i have included them in this post:
Code: Select all
.global switch_contexts_asm
.global switch_contexts_with_iret_asm
switch_contexts_asm:
# we first need to pop cs and ip off the stack in order to be able to take the thread into eax
# 4 + esp = cur
cld
pusha
push %es
push %ds
push %fs
push %gs
# get current thread
cmp $0x0, (%ebx)
jnz if_curr_neq
jmp else_curr_neq
if_curr_neq:
mov (%ebx), %edx # move cur's value into ebx
mov %esp, (%edx) #copy new stack to current thread
else_curr_neq:
mov %eax, (%ebx) # now thread is the current one
mov 12(%eax),%ebx
mov %ebx, %cr3 #paging
mov (%eax),%esp # set our stack
mov $kernel_tss,%edx
mov %esp,4(%edx) #update current tss
pop %gs
pop %fs
pop %ds
pop %es
popa
sti
ret
switch_contexts_with_iret_asm:
# we first need to pop cs and ip off the stack in order to be able to take the thread into eax
# 4 + esp = cur
cld
pusha
push %es
push %ds
push %fs
push %gs
# get current thread
cmp $0x0, (%ebx)
jnz if_curr_neq_1
jmp else_curr_neq_1
if_curr_neq_1:
mov (%ebx), %edx # move cur's value into ebx
mov %esp, (%edx) #copy new stack to current thread
else_curr_neq_1:
mov %eax, (%ebx) # now thread is the current one
mov 12(%eax),%ebx
lock
mov %ebx, %cr3 #paging
lock
mov (%eax),%esp # set our stack
lock
mov $kernel_tss,%edx
lock
mov %esp,4(%edx) #update current tss
pop %gs
pop %fs
pop %ds
pop %es
popa
sti
iret