Доброго дня всем. Выкопал я в сети сборник статей "Разработка операционных систем". Решил поглядеть, работает ли. Дошел до обработки прерываний. Скомпилировал - не работает. В bochs ошибка : IOAPCI: Write to unsupported address. Ошибка именно в этой строке: #define IDT_TABLE 0x100000 #define IDT_REG 0x100800 #define SYS_CODE_SELECTOR 8 asm("lidt 0(,%0,)"::"a"(IDT_REG)); Вопрос: в чем проблемa?
Этих сборников. Поодной строчки судить трудно. Прерывания запрещены? Синтаксис чето не пойму ты что загружаешь регистр с адресса IDT_REG ? А регистр чего содержит.
ща весь код постану instlib.c : функции установки прерываний Code (Text): #define IDT_TABLE 0x100000 #define IDT_REG 0x100800 #define SYS_CODE_SELECTOR 8 void i_install(unsigned char vector, void (*func)(), unsigned char type) { char * idt_table=IDT_TABLE; unsigned char i; unsigned char b[8]; b[0]= (unsigned int)func & 0x000000FF; b[1]=( (unsigned int)func & 0x0000FF00) >> 8; b[2]=SYS_CODE_SELECTOR; b[3]=0; b[4]=0; b[5]=type; b[6]=( (unsigned int)func & 0x00FF0000) >> 16; b[7]=( (unsigned int)func & 0xFF000000) >> 24; for(i=0;i<8;i++){ *(idt_table+vector*8+i)=b[i]; } } //Включение обработки прерываний void i_setup() { unsigned short *table_limit = IDT_REG; unsigned int *table_address = IDT_REG+2; *table_limit = 256*8 - 1; *table_address = IDT_TABLE; asm("lidt 0(,%0,)"::"a"(IDT_REG)); } void i_enable() { asm("sti"); } void i_disable() { asm("cli"); } Code (Text): void init_interrupts() { i_install(0x20, &irq_timer, 0x8e); i_install(0x21, &irq_keyboard, 0x8e); i_setup(); i_enable(); }
Перед загрузкой IDT нужно замаскировать прерывания, а после размаскировать. NMI тоже надо маскировать перед установкой Порт 70h Бит 7 если 1 то NMI – разрешены иначе если 0 то NMI-запрещены NMI – Не маскируемые прерывания. PS. А использовать Intel'овский синтекс религия не позволяет?
собственно по тому учебнику тоже делаю, и когда реализовал что бы можно было писать загружается ядро и сразу вмварка уходит в даун после нажатия любого символа... Wedge если дошел дальше 11 урока, покажи свой kernel.c
ExMike Я в свое время видил много примеров. И статей по разработке. Вот с них и начинал. Но всеравно читал документацию. Если уходит в даун по нажатию то неверно обрабатываешь прерывания. Скорее всего размаскированны прерывания, а ошибка в таблице прерываний или обработчике прерываний. Еще могут быть ошибки со стеком и сегментыми регистрами. Обработчики исключений и ловушек нужно добавить тогда перезагружаться не будет, а будет в них попадать.
Wedge Столько багов. Вот еще один нашел. cli маскирует прерывания sti де маскирует прерывания. Лучши демаскировать только для которых есть обработчики, а это делается через програмирование контроллера. А теперь собственно бага перепрограмирован только ведущий контроллер прерываний, а надо и ведомый тоже. Или замаскировать его.
Wedge Дай лучши образ я посмотрю что нетак IOAPIC. От жары мозги уже плавяться. У второго вектор и так выши. Чето сразу не подумал. Можно нетрогать. А вот прерывания я бы не стал все размаскировать. Для этого их надо замаскировать на саомм контроллере. При помощи OCW1 MOV AL, 0FCh // Таймер, клава размаскированы OUT 21h, AL Ведомы замасирован так как он подключен по второй линии к первому.
Пофиксил свою траблу сенк 2Pavia вместо в ставки асма в си, переписали просто на асм и всё чудом запахало)