外的代碼:訪問標籤的功能
/* ctsw.c : context switcher
*/
#include <kernel.h>
static void *kstack;
extern int set_evec(int, long);
/* contextswitch - saves kernel context, switches to proc */
enum proc_req contextswitch(struct proc_ctrl_blk *proc) {
enum proc_req call;
kprintf("switching to %d\n", getpid(proc));
asm volatile("pushf\n" // save kernel flags
"pusha\n" // save kernel regs
"movl %%esp, %0\n" // save kernel %esp
"movl %1, %%esp\n" // load proc %esp
"popa\n" // load proc regs (from proc stack)
"iret" // switch to proc
: "=g" (kstack)
: "g" (proc->esp)
);
_entry_point:
asm volatile("pusha\n" // save proc regs
"movl %%esp, %0\n" // save proc %esp
"movl %2, %%esp\n" // restore kernel %esp
"movl %%eax, %1\n" // grabs syscall from process
"popa\n" // restore kernel regs (from kstack)
"popf" // restore kernel flags
: "=g" (proc->esp), "=g" (call)
: "g" (kstack)
);
kprintf("back to the kernel!\n");
return call;
}
void contextinit() {
set_evec(49, (long)&&_entry_point);
}
這是一個小的,合作的,非搶佔內核上下文轉換器。 contextswitch()
由dispatcher()
調用,加載進程的堆棧指針。一旦%esp和其他通用寄存器被載入,調用iret
並且用戶進程開始運行。
我需要設置一箇中斷以返回contextswitch()
之後的iret
之後的位置,這樣我就可以恢復內核上下文並將系統調用的值返回到dispatcher()
。
如何從函數外部訪問內存地址_entry_point
?
這是一個好主意,如果我沒有已經已經寫假設調度和過程控制代碼另一種模式,我可能會使用它。 –