Switch the implementation of the function around: make it look like this.
Up vote 4 down vote favorite 3 share g+ share fb share tw.
The code: /* ctsw. C : context switcher */ #include 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); } It's a context switcher for a small, cooperative, non-preemptive kernel.
Contextswitch() is called by dispatcher() with the stack pointer of the process to load. Once %esp and other general purpose registers have been loaded, iret is called and the user process starts running. I need to setup an interrupt to return to the point in contextswitch() after the iret so I can restore the kernel context and return the value of the syscall to dispatcher().
How can I access the memory address of _entry_point from outside the function? C assembly kernel link|improve this question edited Feb 7 '10 at 1:37 asked Feb 7 '10 at 1:15Mike Douglas1,979919 100% accept rate.
Switch the implementation of the function around: make it look like this: Context switch from user to kernel; Call into kernel routines; Context switch back from kernel to user. Then you can just set up the interrupt to run the function from the start. There will need to be a global pointer for "the current user process" - to switch between processes, the kernel code that's run by "Call into kernel routines" just changes that variable to point at a different process.
You will need one special case - for the initial switch from kernel to user mode, for the initial process that's running after boot. After that though, the above function should be able to handle it.
This is a good idea, and if I didn't already have the dispatcher and process control code already written assuming the other model, I might use it. – Mike Douglas Feb 7 '10 at 3:23.
After a little while playing around with GCC, I've got an answer. Dropping down to assembly silences GCC warnings about unused labels. So, _entry_point: is replaced with asm volatile("_entry_point:"); and void contextinit() { set_evec_(49, &&_entry_point); } is replaced with void contextinit() { long x; asm("movl $_entry_point, %%eax\n" "movl %%eax, %0": "=g" (x) : : "%eax"); set_evec(49, x); }.
Besides using inline assembly to access the _entry_point, you can also define it as a function, like: asm volatile("_entry_point:"); void contextinit() { extern void _entry_point(); set_evec(49, (long)&_entry_point); }.
I cant really gove you an answer,but what I can give you is a way to a solution, that is you have to find the anglde that you relate to or peaks your interest. A good paper is one that people get drawn into because it reaches them ln some way.As for me WW11 to me, I think of the holocaust and the effect it had on the survivors, their families and those who stood by and did nothing until it was too late.