When a process is in execution, the contents of the PCB (which is in kernel memory space?) are loaded onto the CPU registers, and status registers, kernel stack pointers, user stack pointers, etc.
When there is a context switch to another process, the current "context" is stored back in the PCB and a switch is made to the new PCB.
Now when the kernel wants to bring back this PCB back into "context", how does it find this PCB, which is in the memory now? What information helps the kernel in finding the PCB which is in memory?
It's the job of schedular to look for the processor availability, then only context switch happens. As soon as core is available the Program Counter Value of stored PCBs in kernal is taken and given to CPU registers. I would like to tell the PCBs are stored in stack fashion by the kernal.
- PCB : it is a Data structure which could be a part of OS or User. But as it's sensitive data structure almost everywhere PCB is a part of kernel data structure
- PCB is mostly stored as per-process kernel stack which is in the kernel space and kernel has access to this which is kept protected from any users.
- Process switching is a function of scheduler and it is kernel module. There are many scheduling algorithms to define the process switching (Long / short / medium term etc.)
- Now the scheduler defines which process will run next and not kernel. The function of kernel is just to provide service when invoked(system calls/interrupts/traps).
- As a kernel module "
scheduler
" has access to all kernel data structures, so it defines the sequence of process (it can be preemptive or co-operative scheduler).
- Every process has its PCB, so active/running process gets its PCB loaded in to CPU registers and other required sections using it's previously stored PCB (mostly) before kernel stack.
Always keep in mind : Kernel is just like a waiter serving what is asked for, who does not know anything, doing everything like donkey work (though most important) as per told.
I would like to provide bit detail information (& to make it easy to understand, consider there is ONE kernel thread per process).
Now there is thread context (eip, ebp, esp, pagedir, kstack, kstacksize) with the every kernel thread (kthread). So, as we all know the thread/process life cycle, it passes through the states like - "Running, Runnable, wait, exit". When the thread is in the running state, its context is in the kernel data structure "context_t" stored somewhere in the kernel address space. and the kernel stack contains the pointer to that data structure
When the thread switch (in more technical words we should say context_switch) happens (reason may be - scheduler cpu time out, I/O operation completion etc.) the thread is enqueued into the runnable queue kernel data structure (waiting for its chance to get CPU).
When states become 'Running', context switch happens again and now the context_t gets loaded. which has all the necessary pointers to access the previously stored data members which will be used now to continue form the previously halted state.
All kernel data structures are stored in the kernel address space (> 0xc0000000) and thread has pointers to these block of context. (as threads gets switched, the new thread points to its context - again context switch, next thread points to its own data structure.