Context switching question - can it really be this simple??
Posted: Fri Nov 25, 2011 6:33 pm
First of all, thanks to everyone for reading and considering my question. I'm floored this actually compiled and executed the first time without any issues. Therefore, I have to have some something wrong!
I am building out the initialization of my kernel. GDT and IDT are initialized. I have created a heap and started paging (actually in reverse order with the heap created after paging is started). Then I create a null process which will end up being a kernel butler process to maintain some housekeeping (not sure what that will be yet, but it is ready just in case). I have then established the timer interrupt set to fire 50 times per second. All of this works great. Thanks to James Molloy's tutorial that has helped me to this point. http://www.jamesmolloy.co.uk/tutorial_html/
As a part of the timer interrupt handler, I have added a Reschedule procedure to perform a context switch. The interrupt handler saves all registers on the stack on the way in and pops them all back in place on the way back out. The interrupt handler does not use the kernel stack, but the process stack.
The issue I have is that it works. Well, it works with just a null process by itself anyway. What am I missing?
Again, thank you for your assistance!
I am building out the initialization of my kernel. GDT and IDT are initialized. I have created a heap and started paging (actually in reverse order with the heap created after paging is started). Then I create a null process which will end up being a kernel butler process to maintain some housekeeping (not sure what that will be yet, but it is ready just in case). I have then established the timer interrupt set to fire 50 times per second. All of this works great. Thanks to James Molloy's tutorial that has helped me to this point. http://www.jamesmolloy.co.uk/tutorial_html/
As a part of the timer interrupt handler, I have added a Reschedule procedure to perform a context switch. The interrupt handler saves all registers on the stack on the way in and pops them all back in place on the way back out. The interrupt handler does not use the kernel stack, but the process stack.
The issue I have is that it works. Well, it works with just a null process by itself anyway. What am I missing?
Code: Select all
#ifndef PROCESS_H
#define PROCESS_H
typedef enum {PRC_ERR = 0,
PRC_CURR = 1,
PRC_RDY = 2,
PRC_MSGW = 3,
PRC_SEMW = 4,
PRC_DLYW = 5,
PRC_SUSP = 6} ProcessState;
typedef struct ProcessEntry {
uint16 pid;
ProcessState state;
uint16 priority;
uint32 sem;
uint32 msg;
uint8 hasMsg;
uint32 esp;
uint16 ss;
struct ProcessEntry *next;
} ProcessEntry;
extern ProcessEntry *rdyHead;
extern ProcessEntry *rdyTail;
extern ProcessEntry *currProc;
extern ProcessEntry *NullProcess;
extern uint16 nextPID;
extern uint16 processCount;
void InitProcess(void);
void ReadyProcess(ProcessEntry *prc);
void Reschedule(void);
#endif
Code: Select all
#include "kernel.h"
ProcessEntry *currProc = 0;
void Reschedule(void)
{
// Put the current process on the ready queue; if
// ready queue is empty, this process will be back
// at the top of the queue.
ReadyProcess(currProc);
// Make sure the stack is static for the rest if
// this function until the return
// Save the current stack information into the
// process structure. All other registers are
// saved on the stack already.
asm volatile("mov %%ss,%0":"=r"(currProc->ss));
asm volatile("mov %%esp,%0":"=r"(currProc->esp));
// Get the new current process off the top of the
// ready queue. It is possible that it is the
// process that just gave up the CPU.
currProc = rdyHead;
rdyHead = rdyHead->next;
currProc->next = 0;
// From the process structure, restore the stack
// for the next process to get a slice of CPU.
asm volatile("mov %0,%%ss"::"r"(currProc->ss));
asm volatile("mov %0,%%esp"::"r"(currProc->esp));
// The return of this function will return to the
// new current process.
}