El código:Acceso a una etiqueta desde fuera de una función
/* 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);
}
Es un selector de contexto para un pequeño núcleo, cooperativo, no preferente. contextswitch()
se llama por dispatcher()
con el puntero de pila del proceso para cargar. Una vez que se han cargado% esp y otros registros de propósito general, se llama al iret
y el proceso de usuario comienza a ejecutarse.
Necesito fijar una interrupción para volver al punto en contextswitch()
después de la iret
para que pueda restaurar el contexto del núcleo y devolver el valor de la llamada al sistema de dispatcher()
.
¿Cómo puedo acceder a la dirección de memoria _entry_point
desde fuera de la función?
Esta es una buena idea, y si no tuviera ya el código despachador y control de procesos ya escrito asumiendo el otro modelo, podría usarlo. –