Kod:Dostęp etykietę z poza funkcją
/* 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);
}
Jest to przełącznik kontekst dla małej, spółdzielni, jądra zakaz poboru. contextswitch()
jest wywoływane przez dispatcher()
ze wskaźnikiem stosu procesu do załadowania. Po załadowaniu% esp i innych rejestrów ogólnego przeznaczenia, wywoływana jest nazwa iret
i rozpoczyna się proces użytkownika.
muszę skonfigurować przerwanie, aby powrócić do punktu, w contextswitch()
po iret
więc mogę przywrócić kontekst jądra i zwracają wartość syscall do dispatcher()
.
Jak uzyskać dostęp do adresu pamięci _entry_point
spoza funkcji?
Jest to dobry pomysł, a jeśli nie mają już kod dyspozytor i kontrola procesu już napisane przy założeniu, drugi model, mógłbym go użyć. –