From a3a226ad956494d849f0c29a50294b725b48d085 Mon Sep 17 00:00:00 2001 From: 0x35c <> Date: Fri, 7 Nov 2025 16:23:30 +0100 Subject: [PATCH] fix: thread switch gets back into the isr routine but iret does not return to the correct frame --- headers/thread.h | 4 ++-- src/kernel.c | 3 ++- src/multitasking/switch_to_thread.s | 18 +++++++----------- src/multitasking/thread.c | 15 +++++++-------- 4 files changed, 18 insertions(+), 22 deletions(-) diff --git a/headers/thread.h b/headers/thread.h index 7fbf4de..0db58aa 100644 --- a/headers/thread.h +++ b/headers/thread.h @@ -14,8 +14,8 @@ typedef enum { } state_t; struct tcb { - uint8_t *esp; - uint8_t *esp0; + uint32_t *esp; + uint32_t *esp0; uint16_t tid; state_t state; struct pcb *process; diff --git a/src/kernel.c b/src/kernel.c index 993db84..3bd9ea3 100644 --- a/src/kernel.c +++ b/src/kernel.c @@ -48,5 +48,6 @@ void kernel_main(multiboot_info_t *mbd, uint32_t magic) create_process(1); create_thread(current_pcb, shell_init); toris(); - while (true); + while (true) + ; } diff --git a/src/multitasking/switch_to_thread.s b/src/multitasking/switch_to_thread.s index 90a8d4a..9629db1 100644 --- a/src/multitasking/switch_to_thread.s +++ b/src/multitasking/switch_to_thread.s @@ -4,11 +4,9 @@ .global switch_thread switch_thread: - push ebx - push ebp - push edi - push esi - + mov edx, DWORD PTR [esp] + cmp DWORD PTR [current_tcb], 0 + je .LABEL1 mov eax, [current_tcb] // save the current stack pointer to the old stack @@ -16,6 +14,7 @@ switch_thread: // stack pointer + the 4 regs pushed // and + 1 to get the argument (next thread) +.LABEL1: mov esi, [esp+(4+1)*4] mov [current_tcb], esi @@ -23,9 +22,6 @@ switch_thread: mov esp, [eax+0] // get esp - pop esi - pop edi - pop ebp - pop ebx - - iret + push edx + + ret diff --git a/src/multitasking/thread.c b/src/multitasking/thread.c index 717a50a..25419b4 100644 --- a/src/multitasking/thread.c +++ b/src/multitasking/thread.c @@ -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 // of the thread 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->next = NULL; new_tcb->state = NEW; - struct tcb *it = process->thread_list; - if (it) { - while (it) - it = it->next; - it = new_tcb; - } - else { + if (process->thread_list == NULL) { 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;