0

特にキーボードのキーを押したときにキーボード関連の割り込みルーチンが呼び出されないため、IDT を機能させることができません。IDT テーブルの特別な 48 ビット ポインターのアドレスを渡しています。みたいにやってます

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 が正しく動作しているかどうかを確認するにはどうすればよいですか?

前もって感謝します。

編集:私は自分のOSのためにこれをやっています。アセンブリ ルーチンがポインタのアドレスを正しく受け取ることができるかどうか疑問です。そのため、インラインアセンブリを使用して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
4

1 に答える 1

1

IRQ ベクトル オフセットを に設定し0x20ます。つまり、 interrupt 、interrupt などにIRQ0マップされます。ただし、割り込みが発生したときに irq ハンドラーが実行されるように設定します。それがIDRを設定する方法です:0x20IRQ10x210x000x01

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

ここでPIC に関する詳細情報を見つけることができます(セクション初期化では、関数で何をしているのかを正確に説明していremap_irqsます。

于 2012-04-07T18:54:06.803 に答える