Software Interrupts

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
Goober

Software Interrupts

Post 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.
Tora OS

Re:Software Interrupts

Post by Tora OS »

Off topic but related question: would you use the "reserved" ints for your kernel intrupts?
fraserjgordon

Re:Software Interrupts

Post 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)
Goober

Re:Software Interrupts

Post 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.
mystran

Re:Software Interrupts

Post 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.
AR

Re:Software Interrupts

Post by AR »

There are call gates that you can put in the GDT if that's what you mean?
Goober

Re:Software Interrupts

Post 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.
AR

Re:Software Interrupts

Post 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
Goober

Re:Software Interrupts

Post by Goober »

wow...maybe it is easier with the IDT. How do I set up my IDT to point to my ISR's?
AR

Re:Software Interrupts

Post 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;
mystran

Re:Software Interrupts

Post 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...
Post Reply