x86中断处理程序没有反应

时间:2015-01-09 19:25:22

标签: assembly x86 interrupt-handling

我有一个小型引导程序,可以在屏幕上打印Hello World。我想修改它,以便在按下某个键时更改写入的消息。我设置了一个IDT,其中包含一个应该调用我的处理程序的条目(第二个)。但我没有回应。

我从某个网站获得了条目的selector和type_attr的值,我仍然不完全确定它们是否正确以及它们是如何工作的。

这是相关代码:

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 < ROWS * COLS * 2) {
        vid_ptr[i] = ' ';
        vid_ptr[i+1] = 0x07;
        i += 2;
    }
    i = 0;
    while (string[i] != '\0' && i < 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) &callback;
    IDT[0x1].offset_lower = callback_address & 0xffff;
    IDT[0x1].selector = 0x08;
    IDT[0x1].zero = 0;
    IDT[0x1].type_attr = 0x8e;
    IDT[0x1].offset_upper = (callback_address & 0xffff0000) >> 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) &IDT;
    __asm__ ( "lidt (%0)" : : "p"(&IDTR) );
}

int kmain(void __attribute__((__unused__)) *foo, uint32_t __attribute__((__unused__)) bar) {
    write_string ("Hello World!");
    setup_interrupt ();

    while(1);

    return 0;
}

你能告诉我我做错了吗?

0 个答案:

没有答案