我有一个小型引导程序,可以在屏幕上打印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;
}
你能告诉我我做错了吗?