인터럽트 루틴이 호출되지 않아서 IDT가 작동하지 못합니다. 특히 키보드의 키를 누를 때 키보드 관련 문제가 발생합니다. IDT 테이블의 특수 48 비트 포인터의 주소를 전달합니다. 나는 또한 적어도 GDT가 작동 여부 모르는IDT가 C에서 작동하지 않습니다.
dt_ptr idt_ptr; // defining the pointer
loadidt(dt_ptr *a); // how i am passing the pointer's address to assembly routine
처럼 그 일을하고있다.
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
설명하여 플랫폼 및 어쩌면 운영 체제 – Matthias
내 운영 체제 – geek1000
... 및 플랫폼 (즉, 어떤 프로세서 및 인터럽트 고려 사항이있는 경우 컨트롤러가 인터럽트) – Matthias