बाहर से एक लेबल तक पहुँचना कोड:एक समारोह
/* 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
कहा जाता है और उपयोगकर्ता प्रक्रिया चलना शुरू हो जाती है।
मैं सेटअप करने के लिए एक अवरोध की जरूरत iret
के बाद contextswitch()
में बात करने के लिए वापस जाने के लिए तो मैं गिरी संदर्भ बहाल करने और dispatcher()
को syscall का मूल्य लौट सकते हैं।
मैं फ़ंक्शन के बाहर से _entry_point
के मेमोरी पते का उपयोग कैसे कर सकता हूं?
यह एक अच्छा विचार है, और अगर मैं पहले से ही नहीं था डिस्पैचर और प्रक्रिया नियंत्रण कोड पहले से ही यह मानते हुए लिखा दूसरा मॉडल, मैं इसका इस्तेमाल कर सकता हूं। –