title: x86 Interrupt handler not reacting
body: <p>I have a small bootloader that prints Hello World on the screen. I want to modify it so that it changes the written message when a key is pressed. I set up an IDT with one entry (the second one) that should call my handler. However I get no response. </p>
  
  <p>I got the values for selector and type_attr of the entry from some website, I am still not entirely sure if they are correct and how they work.</p>
  
  <p>This is the relevant code:</p>
  
  <pre><code>typedef unsigned int   uint32_t;
  typedef unsigned short uint16_t;
  typedef unsigned char  uint8_t;
  
  #define VID_PTR 0xb8000
  #define ROWS 25
  #define COLS 80
  #define IDT_SIZE 256
  
  struct IDTDescr {
      uint16_t offset_lower;
      uint16_t selector;
      uint8_t zero;
      uint8_t type_attr;
      uint16_t offset_upper;
  };
  
  struct IDTDescr IDT[IDT_SIZE];
  
  void write_string(const char *string) {
      char *vid_ptr = (char *) 0xb8000;
      int i;
      i = 0;
      while (i &lt; ROWS * COLS * 2) {
          vid_ptr[i] = ' ';
          vid_ptr[i+1] = 0x07;
          i += 2;
      }
      i = 0;
      while (string[i] != '\0' &amp;&amp; i &lt; ROWS * COLS) {
          vid_ptr[2*i] = string[i];
          i += 1;
      }
  }
  
  void callback() {
      write_string ("Hello Keyboard!");
      __asm__ ("iret");
  };
  
  void setup_interrupt() {
      /* Write IDT */
      uint32_t callback_address = (uint32_t) &amp;callback;
      IDT[0x1].offset_lower = callback_address &amp; 0xffff;
      IDT[0x1].selector = 0x08;
      IDT[0x1].zero = 0;
      IDT[0x1].type_attr = 0x8e;
      IDT[0x1].offset_upper = (callback_address &amp; 0xffff0000) &gt;&gt; 16;
  
      write_string((char *) 0x100000);
  
      /* Load IDTR */
      struct __attribute__((packed)) {
          uint16_t length;
          uint32_t base;
      } IDTR;
  
      IDTR.length = IDT_SIZE * sizeof(struct IDTDescr) - 1;
      IDTR.base = (uint32_t) &amp;IDT;
      __asm__ ( "lidt (%0)" : : "p"(&amp;IDTR) );
  }
  
  int kmain(void __attribute__((__unused__)) *foo, uint32_t __attribute__((__unused__)) bar) {
      write_string ("Hello World!");
      setup_interrupt ();
  
      while(1);
  
      return 0;
  }
  </code></pre>
  
  <p>Can you tell me what I did wrong?</p>