I have my partial OS up and running. It's an extension of the tutorials of MuOS by Gregor Brunmar at http://hem.passagen.se/gregge/index_hires.html
My OS is loaded with the assembly kernel at 0x7C00 loading and calling a C kernel at 0x7E00, with a stack set up at 0x90000.
The kernel runs in segmented protected mode (as per the tutorials), it scrolls the screen nicely, buffers scan-codes and ascii codes, handles a few commands, etc. No multi-tasking or anything, everything is linear and in one binary. I have an interrupt table which calls my kprintf equivalent for any exceptions then hangs the system.
My problem arose when I created a new command to buffer some data. My keyboard routine called my new procedure, the procedure kprintf'd a debug string, then I declared a variable for a buffer.
Code: Select all
unsigned char lBuffer[1500];
short lLength = 0;
This is where things started to go ... odd.
With the buffer defined as 1500 bytes, the machine (and Bochs) would triple-fault and reset as soon as I called the new procedure. It didn't even seem to call my interrupt routines, which should have hung the system. If I change the definition to 1000 bytes, the system seems ok, it's also fine with a buffer of 2000 bytes. With any length between 1000 and 1500, the system will become extremely unstable, sometimes triple-faulting, sometimes calling my exception handlers for exceptions 6 (Invalid OpCode), 8 (Double-fault) or 13 (GPF) sometimes after a long pause.
I concluded that this behaviour must be something to do with the stack overwriting something (or other corruption), then returning to some invalid address or just out "into the weeds", but the kernel is only about 25k. I can also tried moving the inital stack down to start at 0x7000 with the same result.
I've poked around with Bochs, and the triple-fault seems to occur toward the end of my buffer-defining procedure, possibly as it's returning and deallocating the local variables from the stack, but I am unsure how to proceed any further with debugging on either my test machine or Bochs.
I fear that it might be some mistake in my interrupt handler. I've taken a copy of the kernel and tried to reduce it to just the code that causes the problem, but it's still too big to post here, the compiled size is now 4k.
One bizarre (yes, I'd say bizarre) observation I made when reducing the code, I have a section of code similar to the following:
Code: Select all
unsigned char mShiftKeyDown = 0;
unsigned char mCapsLock = 0;
unsigned char mKeymapGB[128] = {
0, 0, '1', '2', '3', ...
};
void KeyboardCommandProcessing()
{
...
if (mShiftKeyDown ^ mCapsLock == 1)
{
}
else
{
lASCIICode = mKeymapGB[lScanCode];
}
...
}
I've been poking this for a few days now, and I have no idea how to proceed.
Any suggestions will be appreciated.
Thanks