PIT IRQ causing General Protection Fault

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
0xC
Posts: 6
Joined: Fri Feb 25, 2011 4:39 am
Location: Durham, United Kingdom

PIT IRQ causing General Protection Fault

Post by 0xC »

I have been following and 'extending' the "Bran's kernel development tutorial" as a starting block (not just blindly copying code, actually finding out what is happening and why), anyway everything was going fine until I got to IRQs. I have created functions which remap the IRQ to 32-47, stub functions to intercept every IRQ and a handler which distributes the interrupt to a specific handler. The first handler I set up was to handle the PIT, on IRQ0, but I get one tick, and then I get a general protection fault. This led me to believe that it could be that the remap is wrong, but I've checked it against then one in bran's code and his works (in the same emulator (qemu, if it matters)).

The IRQ0 handling function is as follows:

Code: Select all

void Tick(struct Registers *R)
{
	Video_PrintString("Recieved a tick!\n");
}
The function to remap the IRQ follows:

Code: Select all

void IRQ_Remap()
{
    outportb(0x20, 0x11);
    outportb(0xA0, 0x11);
    outportb(0x21, 0x20);
    outportb(0xA1, 0x28);
    outportb(0x21, 0x04);
    outportb(0xA1, 0x02);
    outportb(0x21, 0x01);
    outportb(0xA1, 0x01);
    outportb(0x21, 0x0);
    outportb(0xA1, 0x0);
}


I'm unsure of what the problem is, but I'm hoping somebody else will have an answer.

Also I did search the forums before posting, but the only thing I could find was this: http://forum.osdev.org/viewtopic.php?f= ... lt#p183021, and that didn't help (I have enabled interrupts).

If any other code is required just ask :)

Thank you
-0xC
User avatar
Chandra
Member
Member
Posts: 487
Joined: Sat Jul 17, 2010 12:45 am

Re: PIT IRQ causing General Protection Fault

Post by Chandra »

I dont think 'IRQ Remapping' is causing the 'General Protection Fault'.In fact, I believe there's some problem with the 'GDT' setup. Can we have the portion of your code that sets up the GDT?
Programming is not about using a language to solve a problem, it's about using logic to find a solution !
0xC
Posts: 6
Joined: Fri Feb 25, 2011 4:39 am
Location: Durham, United Kingdom

Re: PIT IRQ causing General Protection Fault

Post by 0xC »

I've read somewhere that unless you remap the IRQ, a general protection fault will occur whenever an IRQ is fired. I'm unsure of the validity of this, but I will try to re-find the resource.

Also this is the GDT code, I'm aware it's extremely simplistic at the moment, but it will improve (eventually :p)

Code: Select all

void GDT_SetGate(int N, unsigned long Base, unsigned long Limit, unsigned char Access, unsigned char Granularity)
{
    /* Setup the descriptor base address */
    GDT[N].BaseLow = (Base & 0xFFFF);
    GDT[N].BaseMiddle = (Base >> 16) & 0xFF;
    GDT[N].BaseHigh = (Base >> 24) & 0xFF;

    /* Setup the descriptor limits */
    GDT[N].LimitLow = (Limit & 0xFFFF);
    GDT[N].Granularity = ((Limit >> 16) & 0x0F);

    /* Finally, set up the granularity and access flags */
    GDT[N].Granularity |= (Granularity & 0xF0);
    GDT[N].Access = Access;
}

void GDT_Install()
{
    /* Setup the GDT pointer and limit */
    GP.Limit = (sizeof(struct GDT_Entry) * 3) - 1;
    GP.Base = (unsigned int)&GDT;

    /* A NULL descriptor */
    /* This is needed as a protection feature by the processor. If
    	this is not here, then there will be a general protection 
    	fault
    */
    GDT_SetGate(0, 0, 0, 0, 0);

    /* The second entry is our Code Segment. The base address
      is 0, the limit is 4GBytes, it uses 4KByte granularity,
      uses 32-bit opcodes, and is a Code Segment descriptor.
	*/
	GDT_SetGate(1, 0, 0xFFFFFFFF, 0x9A, 0xCF);

	/* The third entry says that the data degment, is exactly
	   the same, but with the data flag set
	*/
    GDT_SetGate(2, 0, 0xFFFFFFFF, 0x92, 0xCF);

	/* Install the changes */
    GDT_Flush();
}
EDIT:
Found that resource:

Code: Select all

/* Normally, IRQs 0 to 7 are mapped to entries 8 to 15. This
*  is a problem in protected mode, because IDT entry 8 is a
*  Double Fault! Without remapping, every time IRQ0 fires,
*  you get a Double Fault Exception, which is NOT actually
*  what's happening. We send commands to the Programmable
*  Interrupt Controller (PICs - also called the 8259's) in
*  order to make IRQ0 to 15 be remapped to IDT entries 32 to
*  47 */
User avatar
Brendan
Member
Member
Posts: 8561
Joined: Sat Jan 15, 2005 12:00 am
Location: At his keyboard!
Contact:

Re: PIT IRQ causing General Protection Fault

Post by Brendan »

Hi,
0xC wrote:Also this is the GDT code, I'm aware it's extremely simplistic at the moment, but it will improve (eventually :p)
That code is buggy due to the way it handles the limit (it doesn't take into account the effect the granularity flag has). For example, if the granularity flag is set then you should do "limit = limit >> 12". Another alternative would be something like "if( limit > 0x000FFFFF ) { *set_granularity_flag*; limit >>= 12; }" so you don't need the "unsigned char Granularity" parameter at all (and could replace it with a 16-bit/32-bit flag maybe). For example, because of this bug if the caller asks for a limit of 0x12345678 then they'd get a limit of 0x45678FFF and not a limit of 0x12345FFF.

Unfortunately, because the limit is 0xFFFFFFFF (in all cases that matter) you'd end up with correct GDT entries anyway, so this isn't the problem you were looking for.

The problem you're looking for could be anything, including your IRQ handling code, the way you've defined the GDT entry structure, memory management problems (e.g. stack overwriting your code or something), or almost anything else. The best way to get more of an idea is to figure out where the code crashes (e.g. get the value of EIP for the instruction that caused the triple fault, from Bochs log or wherever, and use that to figure out which instruction in which piece of code is causing the problem/symptoms).
0xC wrote:EDIT:
Found that resource:

Code: Select all

/* Normally, IRQs 0 to 7 are mapped to entries 8 to 15. This
*  is a problem in protected mode, because IDT entry 8 is a
*  Double Fault! Without remapping, every time IRQ0 fires,
*  you get a Double Fault Exception, which is NOT actually
*  what's happening. We send commands to the Programmable
*  Interrupt Controller (PICs - also called the 8259's) in
*  order to make IRQ0 to 15 be remapped to IDT entries 32 to
*  47 */
The wording used is misleading. A double fault causes an "interrupt 8", and if the PIC is not remapped then the IRQ0 also causes an "interrupt 8", and you can't (easily) tell the difference. However, a double fault is never an IRQ, and an IRQ is never an exception.


Cheers,

Brendan
For all things; perfection is, and will always remain, impossible to achieve in practice. However; by striving for perfection we create things that are as perfect as practically possible. Let the pursuit of perfection be our guide.
User avatar
Chandra
Member
Member
Posts: 487
Joined: Sat Jul 17, 2010 12:45 am

Re: PIT IRQ causing General Protection Fault

Post by Chandra »

0xC wrote:I've read somewhere that unless you remap the IRQ, a General Protection Fault will occur whenever an IRQ is fired.
Not always 'General Protection Fault' but different 'Exceptions' depending upon the IRQ fired.Your case is "General Protection Fault whenever PIT IRQ fires" and that happens in the following cases:
1.You've mapped IRQs 0 to 7 through IDT ENTRIES 13 TO 20.
2. You have not setup the proper limit(amongst others) in the GDT for your kernel code and data selectors.
3. Your Interrupt handler code is buggy and overwrites the stack or some such.
Programming is not about using a language to solve a problem, it's about using logic to find a solution !
User avatar
Chandra
Member
Member
Posts: 487
Joined: Sat Jul 17, 2010 12:45 am

Re: PIT IRQ causing General Protection Fault

Post by Chandra »

And I doubt if you have properly adapted the code from 'Bran's Tutorials' because those codes are almost sure to work at the minimum. Check again if you've actually missed something.
Programming is not about using a language to solve a problem, it's about using logic to find a solution !
0xC
Posts: 6
Joined: Fri Feb 25, 2011 4:39 am
Location: Durham, United Kingdom

Re: PIT IRQ causing General Protection Fault

Post by 0xC »

Thanks for your help with everything guys, I'll revise my code and try to fix what is going wrong.

Thanks
-0xC
Post Reply