IDT, выполненный в C, не работает

Я не могу заставить IDT работать, потому что мои процедуры прерывания не вызываются, особенно связанные с клавиатурой, когда я нажимаю клавишу на клавиатуре. Я передаю адрес специального 48-битного указателя таблицы 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

person manuhg    schedule 04.04.2012    source источник
comment
В случае проблем с прерываниями было бы полезно указать вашу платформу и, возможно, вашу операционную систему.   -  person Matthias    schedule 04.04.2012
comment
Моя собственная операционная система.   -  person manuhg    schedule 04.04.2012
comment
... и ваша платформа (т. е. какой процессор и, в случае прерываний, контроллер прерываний, если он есть)   -  person Matthias    schedule 04.04.2012
comment
Нам нужно больше информации. Покажите нам, как создается IDT, точный код loadidt и определение dt_ptr.   -  person Paweł Dziepak    schedule 04.04.2012


Ответы (1)


Вы устанавливаете смещение вектора IRQ на 0x20. Это означает, что IRQ0 отображается на прерывание 0x20, IRQ1 на прерывание 0x21 и т. д. Однако вы устанавливаете обработчики irq для выполнения при возникновении прерываний 0x00 и 0x01. Вот как вы должны установить IDR:

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

Дополнительную информацию о PIC можно найти здесь (раздел Инициализация точно объясняет, что вы делать в remap_irqs функции.

person Paweł Dziepak    schedule 07.04.2012
comment
благодарю вас. Что-то может быть не так с gdt. в целом никаких улучшений. - person manuhg; 08.04.2012