Page 1 of 1

TSS Errors in Bochs

Posted: Fri Sep 12, 2003 7:18 pm
by stonedzealot
I'm not writing a multitasking OS yet. I want to get every basic concept down pat before I get into more advanced things (like schedulers and etc.). So this is a practice OS. Anyway, I just wanted to say that I want nothing to do with TSS.

I just completed writing my interrupt structure, just the IDT/IDTR and 256 ISRs that saves all of the data/extra (ds,es,fs,gs) segments, pushes the interrupt number and calls a c master function then pops everything off before the iret. Basic stuff.

Now comes the weird part. After I program the PIC and re enable interrupts (for the first time since we switched to pmode) it goes through the interrupt (the c function fires and successfully returns) but then Bochs complains about TSS problems:

get_SS_ESP_from_TSS: TR.cache invalid
get_SS_ESP_from_TSS: TR is of bogus type (0)
get_SS_ESP_from_TSS: TR.cache invalid
get_SS_ESP_from_TSS: TR is of bogus type (0)

and then Bochs dies because it's three exception 10s in a row that
are unresolved...

Where in the world is this coming from? I suppose I could initialize a TSS, but why would this be necessary if I'm no multitaksing (even though it's a 32 bit OS)?

Re:TSS Errors in Bochs

Posted: Fri Sep 12, 2003 9:20 pm
by stonedzealot
on a related note (I think). If the stack has 1 2 3 on it at the beginning of an ISR (before anything is called or executed) shouldn't it have 1 2 3 on the stack right before iret is called?

Re:TSS Errors in Bochs

Posted: Fri Sep 12, 2003 10:45 pm
by stonedzealot
My suspicions were proved correct, the stack is the problem. But oddly enough, it's not my fault (yet). Using Boch's print-stack debug function I found that the stack, after the interrupt was called, before anything was done in the ISR, looked like this:

Code: Select all

2890|___________EIP = 01002890
0010|

0008|___________CS = 00000008
0000|

With another 4 bytes as flags, but that doesn't factor into my observations.
Now, I knew that EIP was right, because I disassembled my kernel and found that the next instruction was at 2890 (EIP=001002890 because I loaded my kernel to 0x001000000. So that checked out. CS, however was pushed as 8...this should be 0x10 (16). I don't know how it got pushed that way, CS's selector was 0x10 when I dumped the CPU core, it was 0x10 every other time I dumped it... Huh. That's quite odd.

So I added the line mov, "[esp + 4], word 0x10" to the ISR, checked it once and made sure that the stack was:

Code: Select all

2890 -------------OR equivalent (added a line, got higher)
0010
0010 --------------CS selector = 0x10 now
0000
Ran the code and it worked just fine.

I've identified the problem, and have a solution, but it's a solution I shouldn't have to implement. Basically because I don't see this line of code in anyone elses ISR. So now my question is, why is the CPU pushing 0x8 instead of 0x10 to the stack?

Re:TSS Errors in Bochs

Posted: Sat Sep 13, 2003 3:17 am
by Pype.Clicker
First thing, as soon as you have several DPLs involved, you *must* have at least one TSS. The cpu will reload SS and ESP on interrupt with SS0 and ESP0 values from the TSS if the interrupt appears at DPL1,2 or 3.

For the CS thing, i'm unsure, but maybe you missed a "jump 0x10:..." in your last GDT reprogramming and are still working with an old selector (for instance the one from the bootloader ?)

Re:TSS Errors in Bochs

Posted: Sat Sep 13, 2003 6:42 pm
by stonedzealot
Figh. Figh. Figh. Figh. I thought that after you loaded in the GDT value of CODESEL into CS by jumping, you wouldn't need to jump again (if the selectors were identical). I am a foolish, foolish young man. As for having to set up a TSS eventually, yes, but since I wasn't switching DPL levels at the time, I figured it had to have something to do with multitasking.

Anyway. Thanks alot, Pype. You're invaluable. I know you've answered a lot of my stupid questions. =)

Re:TSS Errors in Bochs

Posted: Mon Sep 15, 2003 12:58 am
by Pype.Clicker
wangpeng wrote: I know you've answered a lot of my stupid questions. =)
Btw, there are no stupid questions: just stupid answers and questions that need to be re-stated ;)

actually, the "shadow/ghost-registers" that the CPU uses for limit checking and address translations are *registers*, so they're unaware of whatever occurs to memory and are only reloaded when you reload the selector (regardless of the old value of the selector). This means you need a "mov ds, ax" thing for data selectors and a jmp for CS.