Page 1 of 1

enabling IF flag restarts

Posted: Mon Mar 31, 2003 12:00 am
by prasikumbhare
my bootloader enters into protected mode & jumps to image load address 0x600.
asm part calls _kmain. kmain() starts execution now.

(bootloader setups GDT with null ,linear code & data descriptors.
es=fs=gs=ds = ss = 0x10 i.e. linear data seg.desc. by bootloader.)
do i need to setup a TSS first? is it because of no TSS.
Please let me know what goes wrong.

here is the code ....

// kernel.c
#include "global.h"              // prototype declaration & data structure defn.

static INT_DESCRIPTOR  idt[0x31];
static IDT_REG         idtr;


kmain()
{
    setup_IDT();
    setup_PIC();
    enable_IRQ(1);        // enable keyboard interrupt.
    asm("sti"):           // restarts now.....

}
// if asm("hlt"); is placed between enable_IRQ(1); & asm("sti"), it hangs.

// I changed the sequence of sti & enable_IRQ. (no asm("hlt"); in between)
// now it restarts on enable_IRQ(1).  I tested this again by plasing "hlt "
//between them.

void serup_IDT()
{
  dword i;
  memset (&idt, 0, sizeof(idt));                  //... ok

// Int 0Dh - General Protection Fault Handler
   idt[0x0D].offs0_15 = ((dword)(&gpf_isr))&0xFFFF;
   idt[0x0D].offs16_31 = ((dword)(&gpf_isr)) >> 16;
   idt[0x0D].sel = 8;
   idt[0x0D].paramcnt = 0;
   idt[0x0D].attrs = ACS_INT_GATE;

// IRQ0...0Fh

  for (i=0;i<16;i++)
  {
    idt[0x20+i].sel = 8;
    idt[0x20+i].paramcnt = 0;
    idt[0x20+i].attrs = ACS_INT_GATE;
     idt[0x20+i].offs0_15  = ((dword)(&demo_isr))&0xFFFF;
     idt[0x20+i].offs16_31 = ((dword)(&demo_isr))>> 16;
  }

   idt[0x20].offs0_15  = ((dword)(&timer_isr))&0xFFFF;
   idt[0x20].offs16_31 = ((dword)(&timer_isr)) >> 16;
  idt[0x21].offs0_15  = ((dword)(&kb_isr))&0xFFFF;
  idt[0x21].offs16_31 = ((dword)(&kb_isr)) >> 16;

  idtr.base = (dword) &idt;
  idtr.limit = sizeof(idt)-1;
  LIDT (&idtr);                            // asm routine ,works correctly.
}

void setup_pic()
{
remap_pic(0x20,0x28);
set_IRQ_mask(0xff);
}


void remap_pic(byte master_vector, byte slave_vector)
{
  outportb (PORT_8259_M, 0x11);                 /* start 8259 initialization */
  outportb (PORT_8259_S, 0x11);
  outportb (PORT_8259_M+1, master_vector);      /* master base interrupt vector */
  outportb (PORT_8259_S+1, slave_vector);       /* slave base interrupt vector */
  outportb (PORT_8259_M+1, 1<<2);               /* bitmask for cascade on IRQ2 */
  outportb (PORT_8259_S+1, 2);                  /* cascade on IRQ2 */
  outportb (PORT_8259_M+1, 1);                  /* finish 8259 initialization */
  outportb (PORT_8259_S+1, 1);
}
void set_IRQ_mask (dword IRQ_mask)
{
  outportb (PORT_INT_MASK_M, IRQ_mask & 0xFF);
  outportb (PORT_INT_MASK_S, IRQ_mask >> 8);
}

// here is asm part :

GLOBAL _kb_isr,_demo_isr,_timer_isr
EXTERN _kb_handler,_demo_handler,_timer_handler

_kb_isr:

      pushad
      call _kb_handler
      popad
      iret

_demo_isr:
      pushad
      call _demo_handler
      popad
      iret

_timer_isr:
      pushad
      call _timer_handler
      popad
      iret


Thanks in advance.