0

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

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でこれをやっています。私のアセンブリルーチンがポインタのアドレスを正しく受け取ることができるかどうかは疑問です。だから私もインラインアセンブリを使用してふたをしようとしたが、助けていない。私は何が間違っているのか分からない。任意の手がかり、アイデア?

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

+0

私自身のオペレーティングシステム – geek1000

+0

...そしてあなたのプラットフォーム(どのプロセッサ、割り込みの場合は割り込みコントローラ、もしあれば割り込みコントローラ) – Matthias

答えて

1

あなたは0x20にオフセットのIRQベクタを設定します。つまり、IRQ0は割り込み0x20に割り当てられ、IRQ1は割り込み0x21などに割り当てられます。ただし、割り込み0x000x01が発生したときに実行するirqハンドラを設定します。それはあなたが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

関連する問題