fix: thread switch gets back into the isr routine but iret does not return to the correct frame

This commit is contained in:
0x35c
2025-11-07 16:23:30 +01:00
parent d1364f5c1f
commit a3a226ad95
4 changed files with 18 additions and 22 deletions

View File

@ -14,8 +14,8 @@ typedef enum {
} state_t; } state_t;
struct tcb { struct tcb {
uint8_t *esp; uint32_t *esp;
uint8_t *esp0; uint32_t *esp0;
uint16_t tid; uint16_t tid;
state_t state; state_t state;
struct pcb *process; struct pcb *process;

View File

@ -48,5 +48,6 @@ void kernel_main(multiboot_info_t *mbd, uint32_t magic)
create_process(1); create_process(1);
create_thread(current_pcb, shell_init); create_thread(current_pcb, shell_init);
toris(); toris();
while (true); while (true)
;
} }

View File

@ -4,11 +4,9 @@
.global switch_thread .global switch_thread
switch_thread: switch_thread:
push ebx mov edx, DWORD PTR [esp]
push ebp cmp DWORD PTR [current_tcb], 0
push edi je .LABEL1
push esi
mov eax, [current_tcb] mov eax, [current_tcb]
// save the current stack pointer to the old stack // save the current stack pointer to the old stack
@ -16,6 +14,7 @@ switch_thread:
// stack pointer + the 4 regs pushed // stack pointer + the 4 regs pushed
// and + 1 to get the argument (next thread) // and + 1 to get the argument (next thread)
.LABEL1:
mov esi, [esp+(4+1)*4] mov esi, [esp+(4+1)*4]
mov [current_tcb], esi mov [current_tcb], esi
@ -23,9 +22,6 @@ switch_thread:
mov esp, [eax+0] // get esp mov esp, [eax+0] // get esp
pop esi push edx
pop edi
pop ebp ret
pop ebx
iret

View File

@ -22,19 +22,18 @@ struct tcb *create_thread(struct pcb *process, void (*routine)(void))
// set esp to "skip" the 4 GPRs and eip later to be used as the context // set esp to "skip" the 4 GPRs and eip later to be used as the context
// of the thread // of the thread
new_tcb->esp = new_tcb->esp0 + STACK_SIZE - 5 * 4; new_tcb->esp = new_tcb->esp0 + STACK_SIZE - 5 * 4;
memcpy(new_tcb->esp + 4, routine, 4); new_tcb->esp[4] = (uint32_t)routine;
new_tcb->process = process; new_tcb->process = process;
new_tcb->next = NULL; new_tcb->next = NULL;
new_tcb->state = NEW; new_tcb->state = NEW;
struct tcb *it = process->thread_list; if (process->thread_list == NULL) {
if (it) {
while (it)
it = it->next;
it = new_tcb;
}
else {
process->thread_list = new_tcb; process->thread_list = new_tcb;
} else {
struct tcb *it = process->thread_list;
while (it->next)
it = it->next;
it->next = new_tcb;
} }
return new_tcb; return new_tcb;