Ассемблер + C или я не могу заставить работать прерывания
Помогите, я запускаю ОС, и она вылетает! ИДТ Лоадет нормально. Что я сделал не так? Это действительно сложно! Мне нужно написать ОС в защищенном режиме!
#define IT 0x000000
#define IR 0x000800
#define SCS 0x8
#define IRQ_HANDLER(func) void func (void)\
{asm(#func ": pusha \n call _" #func " \n movb $0x20, %al \n outb %al, $0x20 \n popa \n iret \n");}\
void _ ## func(void)
void init_interrupts() {
int i=0;
unsigned short *ir=IR;
for(i=0;i<256*8;i++){
*(ir+i)=0;
}
*(ir)=256*8-1;
*(ir+2)=(IT &0xFFFF0000)>>16;
*(ir+4)=(IT&0x0000FFFF);
set_int_handler(0x20, timer_int_handler, 0x8E);
//set_int_handler(0x21, print_c, 0x8E);
asm("lidt 0(,%0,)"::"a"(IR));
opb(0x21,0xfd);
opb(0xa1,0xff);
opb(0x20,0x20); opb(0xa0,0x20);
asm("sti");
}
void set_int_handler(char index, void *handler, char type) {
asm("pushf \n cli");
char *ad=IT;
*(ad+index*8)=(char)(handler)&0x000000FF;
*(ad+index*8+1)=((char)(handler)&0x0000FF00)>>8;
*(ad+index*8+2)=0x8;
*(ad+index*8+3)=0;
*(ad+index*8+4)=0;
*(ad+index*8+5)=type;
*(ad+index*8+6)=((char)(handler)&0x00FF0000)>>16;
*(ad+index*8+7)=((char)(handler)&0xFF000000)>>24;
asm("popf");
}
...
Я не знаю что делать!
1 ответ
Во-первых, так или иначе, большинство компиляторов позволяют вам создавать ISR напрямую.
Во-вторых, вы должны отлавливать все с самого начала, если только вы не хотите, чтобы система зависала при первом необработанном или ложном прерывании (что на первый взгляд кажется тем, что происходит).
Надлежащая подсистема обработки прерываний сделает код намного более чистым и переносимым, что позволит вам проверять IRQ на наличие неработающих шин (например, ISA) и правильно маршрутизировать общие IRQ.
Большинство эмуляторов поддерживают протокол GDB и позволяют легко устранять неисправности такого рода. Например, вы можете запустить QEMU с -d int
а также -no-reboot
для устранения проблем такого рода, когда происходит сбой, вы можете проверить его в отладчике. Вы можете найти некоторые инструкции для начала работы в QEMU Wikibook. Вы также можете попробовать BOCHS, он поставляется с внутренним отладчиком, который лучше работает на низком уровне, а эмуляция иногда более точна.