从零写OS(九):进程调度,CPU 的分时复用
到目前为止,内核一直是单线程跑到底——一件事没做完,别的什么都不能干。 这一章让内核同时跑多个进程。每隔一段时间,时钟中断打断当前进程,把 CPU 交给下一个,轮流执行。这就是多任务的核心机制。 上下文是什么 进程被打断之后,下次恢复时要从断点继续执行,不能出错。这意味着必须把 CPU 的状态完整保存下来——这份状态就叫上下文(Context)。 x86-64 ABI 规定了 callee-saved 寄存器(被调用者负责保存的寄存器,C 函数调用约定中,这些寄存器的值在函数调用前后必须保持不变):rbx、rbp、r12~r15。加上程序指针 rip 和栈指针 rsp,这些就是切换时需要保存和恢复的全部。 typedef struct { uint64_t r15, r14, r13, r12; uint64_t rbx, rbp; uint64_t rip; // 下次从哪里继续执行 uint64_t rsp; // 栈在哪里 } context_t; 每个进程一份 context,切换时:把当前进程的寄存器存入 ctx,再把下一个进程 ctx 里的值写回寄存器——CPU 就"变身"成另一个进程了。 进程结构 #define MAX_PROCS 8 #define STACK_SIZE 8192 // 每个进程 8KB 内核栈 typedef enum { PROC_UNUSED = 0, PROC_READY, PROC_RUNNING, } proc_state_t; typedef struct { context_t ctx; uint8_t *stack; proc_state_t state; uint32_t pid; } process_t; static process_t procs[MAX_PROCS]; static int current_proc = 0; 状态机很简单:UNUSED(槽位空闲)→ READY(等待调度)→ RUNNING(正在跑)→ 被打断后回到 READY。 ...