Page 1 of 1

Software Interrupts

Posted: Fri Jul 08, 2005 1:02 pm
by Goober
Is there more than one way of setting up software interrupts (eg int 0x18)? I know you can load the IDT with pointers to your ISRs, but I think I've seen it done differently before.

Thanks.

Re:Software Interrupts

Posted: Fri Jul 08, 2005 2:23 pm
by Tora OS
Off topic but related question: would you use the "reserved" ints for your kernel intrupts?

Re:Software Interrupts

Posted: Fri Jul 08, 2005 3:31 pm
by fraserjgordon
Tora:

Don't use the Intel reserved ints. Use the "User" interrupts which are 0x20 to 0xFF, IIRC.

Goober:

It is possible to use trap gates and task gates for interrupts as well. (interrupt gates are usually used). For more information on this, see the Intel System Programming Manual (Volume 3)

Re:Software Interrupts

Posted: Fri Jul 08, 2005 5:19 pm
by Goober
The Intel docs make my hair hurt.

Is there any resources on interrupt gates else where? I can't find them in the FAQ.

Re:Software Interrupts

Posted: Fri Jul 08, 2005 7:02 pm
by mystran
You could check BonaFide OSdev, or something...

But you should make yourself familiar with the intel manuals, since you are going to want to check (and recheck) tons of things from there.

Re:Software Interrupts

Posted: Fri Jul 08, 2005 9:17 pm
by AR
There are call gates that you can put in the GDT if that's what you mean?

Re:Software Interrupts

Posted: Fri Jul 08, 2005 9:20 pm
by Goober
You can put call gates in the GDT? Maybe I should read up on this...

Bonafide has no resources about this. Only the IDT and hardware interrupts.

Re:Software Interrupts

Posted: Fri Jul 08, 2005 10:24 pm
by AR
That's because Interrupts are easier to set up, I'm unfortunately not an expert on them, Brendan probably knows more than I do. Or you can look it up in the docs.

Here's a code excerpt for setting up a gate:

Code: Select all

struct GDTEntry
   {
      UINT16  SegmentLimitLow;
      UINT16  SegmentBaseLow;
      UINT8   SegmentBaseMid;
      UINT8   Flags1;
      UINT8   Flags2;
      UINT8   SegmentBaseHigh;
   } __attribute__((__packed__));

   pGDT[num].SegmentLimitLow = CodeSelector;
   pGDT[num].SegmentBaseLow = EntryPoint & 0xFFFF;
   pGDT[num].SegmentBaseMid = (EntryPoint & 0xFF0000) >> 16;
   pGDT[num].Flags1 = 0xC | GDT_RING3 | GDT_PRESENT; //Call gate can be used in Ring 3, 0xC declares it is a callgate
   pGDT[num].Flags2 = 0;
   pGDT[num].SegmentBaseHigh = (EntryPoint & 0xFF000000) >> 24;
(WARNING: The above code was taken out of its context in one of my code archives, I might have broken it slightly)

To use the callgate in user space you would use:

Code: Select all

lcall $DESCRIPTORNUMBER, $0

Re:Software Interrupts

Posted: Sat Jul 09, 2005 2:18 pm
by Goober
wow...maybe it is easier with the IDT. How do I set up my IDT to point to my ISR's?

Re:Software Interrupts

Posted: Sat Jul 09, 2005 3:06 pm
by AR

Code: Select all

struct IDTEntry
   {
      UINT16 loffset;
      UINT16 selector;
      UINT8 unused;
      UINT8 constant:5;   ///< 5 bits - Must be 01110
      UINT8 DPL:2;
      UINT8 Present:1;
      UINT16 hoffset;
   } __attribute__((__packed__));

   pIDT[num].loffset = Function & 0x0000FFFF;
   pIDT[num].hoffset = (Function & 0xFFFF0000) >> 16;
   pIDT[num].selector = CodeSelector;
   pIDT[num].unused = 0;
   pIDT[num].constant = 0xE;
   pIDT[num].DPL = IDT_RING3;
   pIDT[num].Present = 1;

Re:Software Interrupts

Posted: Sat Jul 09, 2005 6:18 pm
by mystran
I've posted this before, but here's my routine for building an interrupt gate.

Code: Select all

/*
 * Builds interrupt gate, at adds it to IDT.
 *
 * Access should be INTERRUPT_USER or INTERRUPT_SYSTEM.
 *
 */ 
void build_int_gate(unsigned char num,
        interrupt_handler handler, unsigned char access) {

    unsigned long hoffset;

    hoffset = (unsigned long) handler;

    idt[num] =
        /* handler offset */
        ((unsigned long long) (hoffset & 0xffff0000) << 32) +
        ((unsigned long long) (hoffset & /*****/ 0x0000ffff)) +
        /* attributes, 32 bit interrupt gate, kernel CS */
        0x00008e0000080000LL +
        /* priviledges */
        ((unsigned long long) (access & 0x03) << 45);

}
Btw, the forum doesn't handle whitespace inside code-blocks in a sane manner. It's kinda annoying actually...