#include "thread.h" #include "../lib/string.h" #include "../kernel/memory.h" #define PG_SIZE 4096 // 由 kernel_thread 去执行 function(func_arg) static void kernel_thread(thread_func *function, void *func_arg) { function(func_arg); } // 初始化线程栈 thread_stack void thread_create(struct task_struct *pthread, thread_func function, void *func_arg) { // 先预留中断栈空间 pthread->self_kstack -= sizeof(struct intr_stack); // 再预留线程栈空间,线程栈位于中断栈顶 pthread->self_kstack -= sizeof(struct thread_stack); struct thread_stack *kthread_stack = (struct thread_stack *)pthread->self_kstack; kthread_stack->eip = kernel_thread; kthread_stack->function = function; kthread_stack->func_arg = func_arg; kthread_stack->ebp = kthread_stack->ebx = kthread_stack->edi = kthread_stack->esi = 0; } // 初始化线程基本信息 void init_thread(struct task_struct *pthread, char *name, int prio) { _memset(pthread, 0, sizeof(*pthread)); _strcpy(pthread->name, name); pthread->status = TASK_RUNNING; pthread->priority = prio; // self_kstack是线程自己在内核态下使用的栈顶地址 pthread->self_kstack = (uint32_t *)((uintptr_t)pthread + PG_SIZE); pthread->stack_magic = 0x19940625; // 自定义的魔数 } // 创建优先级为 prio 的线程, 线程名为 name, 线程所执行的函数是 function(func_arg) struct task_struct *thread_start(char *name, int prio, thread_func function, void *func_arg) { // pcb 线程控制块 struct task_struct *thread = get_kernel_pages(1); // 申请一页内存(内核空间)做为PCB init_thread(thread, name, prio); // 初始化线程基本信息 thread_create(thread, function, func_arg); // 初始化线程栈 thread_stack // ret 指令的作用是弹出栈顶的数据到 eip 寄存器,然后跳转到 eip 寄存器的地址执行 // 此时栈顶数据是kthread_stack->eip 的值 kernel_thread。 // 因此,在执行 ret 后,会跳转到 kernel_thread 函数执行。 asm volatile("movl %0, %%esp; pop %%ebp; pop %%ebx; pop %%edi; pop %%esi; ret" : : "g"(thread->self_kstack) : "memory"); return thread; }