gpt4 book ai didi

c - 用 C 语言完成的 IDT 不起作用

转载 作者:行者123 更新时间:2023-11-30 15:58:07 32 4
gpt4 key购买 nike

我无法让 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是否正常工作?

提前致谢。

编辑:我正在为我自己的操作系统执行此操作。我怀疑我的汇编例程是否能够正确接收指针的地址。所以我也尝试使用内联汇编来做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

最佳答案

您将 IRQ vector 偏移设置为 0x20。这意味着 IRQ0 映射到中断 0x20IRQ1 映射到中断 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函数中所做的事情。

关于c - 用 C 语言完成的 IDT 不起作用,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/10013744/

32 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com