0

我无法获得IDT的工作,因为我的中断例程没有被调用,特别是当我按下键盘上的某个键时与键盘有关。我传递IDT表的特殊48位指针地址。我这样做在C中完成的IDT无法正常工作

dt_ptr idt_ptr; // defining the pointer 
loadidt(dt_ptr *a); // how i am passing the pointer's address to assembly routine 

我也不知道至少GDT是否工作或没有。

1)我该怎么做才能让我的IDT工作。我也看到了一些教程,但没有帮助 2)我如何验证GDT是否正常工作?

在此先感谢。

编辑:我这样做是为了我自己的操作系统。我怀疑我的汇编程序是否能够正确接收指针的地址。所以我也尝试使用内联汇编来做lidt,但没有帮助。我不知道什么是错的。任何线索,想法?

void remap_irqs(void) 
{ 
outb(0x20, 0x11); 
outb(0xA0, 0x11); 
outb(0x21, 0x20); 
outb(0xA1, 0x28); 
outb(0x21, 0x04); 
outb(0xA1, 0x02); 
outb(0x21, 0x01); 
outb(0xA1, 0x01); 
outb(0x21, 0x0); 
outb(0xA1, 0x0); 
outbyte('a'); 

}

void set_idt_gate(uint8 num, unsigned long base, word sel, uint8 flags) 
{ 
IDT[num].offset_low = (base & 0xFFFF); 
IDT[num].offset_high = (base >> 16) & 0xFFFF;  
IDT[num].selector = sel;  
IDT[num].zero = 0; 
IDT[num].type_attrs = flags; 
} 




void init_idt() 
{ 
outbyte('M'); 
idt_ptr.limit = (sizeof (idt_entry) * 256) - 1; 
idt_ptr.base =(uint32) &IDT; 

memset((uint8 *)&IDT, 0, sizeof(idt_entry) * 256); 
remap_irqs(); 
set_idt_gate(0, (unsigned) irq_0, 0x08, 0x8E); 
set_idt_gate(1, (unsigned) irq_1, 0x08, 0x8E); 
//install_isrs(); 
//install_irqs(); 
//idt_load(); 
//print_message(); 
lidt(&IDT,idt_ptr.limit); 
_LIDT(&idt_ptr); 
loadidt(&idt_ptr); 
} 



void lidt(void * base, unsigned short size) 
{ 
struct 
{ 
    unsigned short length; 
    unsigned long base; 
} __attribute__((__packed__)) IDTR; 

IDTR.length = size; 
IDTR.base = (unsigned long)base; 
asm("lidt (%0)" 
    : : "p"(&IDTR)); 

}

void _LIDT(dt_ptr *ptr) 
{ 
asm("lidt (%0)" : :"p"(ptr)); 
outbyte('n'); 
} 





void irq_0() 
{ 
//before_interrupt(); 
ticks+=1; 
if(ticks%18==0) 
{ 
    outbyte('+'); 
    outbyte('1'); 
} 
//after_interrupt(); 
} 

void irq_1() 
{ 
outbyte('a'); 
//before_interrupt(); 
irq1_keyb(); 
//after_interrupt(); 
} 

typedef struct { 
uint16 offset_low; // The lower 16 bits of the address to jump to when this 
interrupt occures:// offset 0-15 
uint16 selector;  // Kernel segment selector in IDT 
uint8 zero;   // This must always be zero. 
uint8 type_attrs; //gate types, atttribute types etc. 
uint16 offset_high; // The upper 16 bits of the address to jump to. offset 16-31 
} __attribute__((__packed__)) idt_entry; 


typedef struct { 
uint16 limit; 
uint32 base;  // The address of the first element in IDT array. 
} __attribute__((__packed__)) dt_ptr; 


global loadidt 
loadidt: 
push ebp 
mov ebp,esp  
mov eax,[ebp+8]  
lidt [eax]  
pop ebp  
ret 
+3

对于中断问题,这将有助于告诉你平台,也许你的操作系统 – Matthias 2012-04-04 15:03:47

+0

我自己的操作系统 – geek1000 2012-04-04 15:08:08

+0

...和你的平台(即,哪个处理器,以及在中断考虑的情况下,中断控制器,如果有的话) – Matthias 2012-04-04 15:10:02

回答

1

您设置的IRQ向量偏移到0x20。这意味着IRQ0映射到中断0x20,IRQ1以中断0x21等。但是,您设置您的irq处理程序在中断0x000x01发生时执行。这就是你应该如何设置IDR:

set_idt_gate(0x20, (unsigned) irq_0, 0x08, 0x8E); 
set_idt_gate(0x21, (unsigned) irq_1, 0x08, 0x8E); 

你可以找到关于PIC here更多的信息(部分初始化确切解释你在做什么在remap_irqs功能

+0

谢谢。 gdt可能有问题。整体没有改善。 – geek1000 2012-04-08 17:31:33