Triple-faults on startup [SOLVED]

Question about which tools to use, bugs, the best way to implement a function, etc should go here. Don't forget to see if your question is answered in the wiki first! When in doubt post here.
Post Reply
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Triple-faults on startup [SOLVED]

Post by pcmattman »

I keep getting triple faults on startup of my OS, and often it takes several restarts before the OS actually successfully boots.

Part of the Bochs log is below:

Code: Select all

00241772720e[CPU0 ] interrupt(): gate descriptor is not valid sys seg
00241772720e[CPU0 ] interrupt(): gate descriptor is not valid sys seg
00241772720e[CPU0 ] interrupt(): gate descriptor is not valid sys seg
00241772720i[CPU0 ] protected mode
00241772720i[CPU0 ] CS.d_b = 32 bit
00241772720i[CPU0 ] SS.d_b = 32 bit
00241772720i[CPU0 ] | EAX=0010c8a0  EBX=00108000  ECX=0019ae0f  EDX=00000000
00241772720i[CPU0 ] | ESP=0019ae08  EBP=0019ae18  ESI=0002be83  EDI=0002be88
00241772720i[CPU0 ] | IOPL=0 id vip vif ac vm RF nt of df IF tf sf ZF af PF cf
00241772720i[CPU0 ] | SEG selector     base    limit G D
00241772720i[CPU0 ] | SEG sltr(index|ti|rpl)     base    limit G D
00241772720i[CPU0 ] |  CS:0008( 0001| 0|  0) 00000000 000fffff 1 1
00241772720i[CPU0 ] |  DS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00241772720i[CPU0 ] |  SS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00241772720i[CPU0 ] |  ES:0010( 0002| 0|  0) 00000000 000fffff 1 1
00241772720i[CPU0 ] |  FS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00241772720i[CPU0 ] |  GS:0010( 0002| 0|  0) 00000000 000fffff 1 1
00241772720i[CPU0 ] | EIP=00104d9a (00104d9a)
00241772720i[CPU0 ] | CR0=0x00000011 CR1=0 CR2=0x00000000
00241772720i[CPU0 ] | CR3=0x00000000 CR4=0x00000000
00241772720i[CPU0 ] >> leave  : C9
00241772720e[CPU0 ] exception(): 3rd (13) exception with no resolution, shutdown status is 00h, resetting
I think it may be a problem in my GDT, but I haven't had any trouble up until now. The only reason I can think of that would have caused this is a recent modification to my multitasker, which I took out after this started appearing.
Last edited by pcmattman on Tue Mar 13, 2007 3:55 pm, edited 1 time in total.
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

Have you considered disabling interrupts when you don't have a functional IDT? :shock:
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

Interrupts are disabled at startup, then my kernel enables them after it finishes booting. I doubt that's the problem.
pjt
Posts: 6
Joined: Thu Nov 23, 2006 10:46 am

Re: Triple-faults on startup

Post by pjt »

pcmattman wrote:I think it may be a problem in my GDT, but I haven't had any trouble up until now. The only reason I can think of that would have caused this is a recent modification to my multitasker, which I took out after this started appearing.
This happened to me, when I added the system call interrupt, but the GDT wasn't big enough. :)
User avatar
Combuster
Member
Member
Posts: 9301
Joined: Wed Oct 18, 2006 3:45 am
Libera.chat IRC: [com]buster
Location: On the balcony, where I can actually keep 1½m distance
Contact:

Post by Combuster »

The problem is that your IDT is bogus:
00241772720e[CPU0 ] interrupt(): gate descriptor is not valid sys seg
In itself this is not a problem. Enabling interrupts is on itself not a problem.
However, this combination of circumstances forces the processors to use a broken IDT which will obviously not work.
"Certainly avoid yourself. He is a newbie and might not realize it. You'll hate his code deeply a few years down the road." - Sortie
[ My OS ] [ VDisk/SFS ]
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

The GDT is definitely big enough, I've removed the code that first caused this from the multitasker (and rebuilt the library).

It really started when I attempted to change the RTC clock speed using code like this:

Code: Select all

void SetClockRate( int hz )
{
	int divisor = 1193180 / hz;       /* Calculate our divisor */
	outportb(0x43, 0x36);             /* Set our command byte 0x36 */
	outportb(0x40, divisor & 0xFF);   /* Set low byte of divisor */
	outportb(0x40, divisor >> 8);     /* Set high byte of divisor */
}
I have no idea what went wrong there :(. Either way, I'm still really confused as to why this is happening. There's got to be a way of fixing this... and to think I was so close to beta testing :(.
User avatar
~
Member
Member
Posts: 1228
Joined: Tue Mar 06, 2007 11:17 am
Libera.chat IRC: ArcheFire

Post by ~ »

At what rate is your RTC? I remember having a problem like that when I tried to get nanoseconds with the RTC and ended up with miliseconds, and I don't remember if the PC locked or it restarted, but it was giving problems, maybe was more than the RTC could handle.

Try commenting out that routine call or use a lower rate; if that doesn't work it should be some change you don't remember having done that you did to test code and was forgotten and now is giving problems.
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

I commented out changing the clock rate, and I've checked over all of the code of my OS (that's not an easy task, either). All of the test code has been removed.

Hang on a second, I just figured it out! My memset, memcpy etc... functions disable interrupts before they start. Afterwards, they enable them again! I think I did this because my GUI was halting during mem* function calls, which may instead be a problem with the multitasker and not the calls.

Edit: fixed the problem, took out the interrupt stuff in mem* functions and replaced it with disabling and enabling multitasking. Everything works properly now...
pcmattman
Member
Member
Posts: 2566
Joined: Sun Jan 14, 2007 9:15 pm
Libera.chat IRC: miselin
Location: Sydney, Australia (I come from a land down under!)
Contact:

Post by pcmattman »

I just found a good use for this: whenever I need to restart the computer, I just enable interrupts (just in case they weren't already) and then do this:

Code: Select all

while( true )
    idt_install();
// never get here
Because interrupts are enabled, it trashes the IDT and triple faults the CPU. I think it's pretty nifty :D.
User avatar
mystran
Member
Member
Posts: 670
Joined: Thu Mar 08, 2007 11:08 am

Post by mystran »

Suggestion for temporarily disabling interrupts:

Write a pair of functions, one of which disables interrupts, and returns 1 if interrupts where enabled, 0 if not. The other takes one arguments, and enables interrupts if the argument is true.

Basicly:

Code: Select all


int disable_interrupts() {
   int val = true_if_interrupts_enabled();
   if(val) disable_interrupts_real();
   return val;
}

void restore_interrupts(int state) {
  if(val) enable_interrupts();
}
You can then do stuff like:

Code: Select all

void non_reentrant_function() {

   int istate = disable_interrupts();

   /* do whatever needs interrupts disabled */

   restore_interrupts(istate);
}
Now you'll never accidentally enable interrupts unless you actually disabled them. :)
The real problem with goto is not with the control transfer, but with environments. Properly tail-recursive closures get both right.
ehird
Member
Member
Posts: 214
Joined: Thu Mar 15, 2007 8:48 am

Post by ehird »

pcmattman wrote: Because interrupts are enabled, it trashes the IDT and triple faults the CPU. I think it's pretty nifty :D.
Linux does that as a last resort. Presumably for a reason ;)
Post Reply