Как обрабатывать 15-ю запись в таблице дескрипторов прерываний

РЕДАКТИРОВАТЬ: исходный код можно найти в моем репо на Github: https://github.com/tuhdo/os-study.

Я сопоставил IRQ 2 PIC (x86) с 32-й записью и далее в IDT. Чтобы проверить прерывания PIC, я назначил первую 31 подпрограмму той же функции. Проблема в том, что я не могу заставить работать 15-ю запись прерывания, поскольку она зарезервирована в соответствии с таблицей векторов прерываний. То есть всякий раз, когда я попадаю в защищенный режим, после включения режима в cr0 и перехода к первой инструкции в пространстве ядра (последняя строка в stage2.asm, то есть jmp 08h:0xFF0) происходит сбой (в Bochs он переходит на адрес f000:fff0, который происходит, когда что-то идет не так). Без добавления 15-й записи я могу выполнить весь код и правильно завершить работу с помощью инструкции hlt.

Поскольку запись зарезервирована, что мне делать, чтобы пропустить запись за 15 часов? В настоящее время моя общая запись IDT выглядит так:

;; IRQ0
  dw   0
  dw   0x30        ; gdt selector 0x30
  db   0
  db   011001110b  ; interrupt gate callable from userspace
  dw   0

Соответствующий код находится в gdt.inc и idt.inc. Моя ОС имеет несколько основных функций:

  • Загрузчик
  • 32-битный защищенный режим.
  • Системные вызовы (из пользовательского пространства в ядро ​​и обратно)
  • Поддержка начального прерывания: пока что я могу обрабатывать деление на 0 или явный вызов прерывания (т.е. int 1). Я уже активировал PIC (pic.inc) и хотел чтобы попробовать, так как я сопоставил прерывания PIC в 0x32. Однако после добавления 15-й записи IDT я получил тройную ошибку, в то время как 14-я и ниже у меня такой проблемы не было.

person Tu Do    schedule 09.10.2015    source источник
comment
Вы должны предоставить больше кода (желательно полностью работоспособного). Вам не нужно пропускать зарезервированные записи в IDT.   -  person Jester    schedule 09.10.2015
comment
То есть вы переключаетесь из реального в защищенный режим, а потом вылетаете? Что заставляет вас думать, что это связано с таблицей дескрипторов прерываний и конкретной записью в ней?   -  person Daniel Jour    schedule 10.10.2015
comment
@DanielJour Хотя трудно сказать, является ли конкретная запись причиной проблемы, я думаю, что IDT - это разумная вещь, на которую стоит обратить внимание, тем более, что процессор, похоже, имеет тройной сбой (что может быть объяснением того, что Bochs перескочил на f000: fff0)   -  person Michael Petch    schedule 11.10.2015
comment
@MichaelPetch Действительно, IDT - это разумная вещь, на которую стоит взглянуть, но также и GDT (если он недействителен, или размер в GDTR неправильный, или ...) и многие другие вещи, которые могли пойти не так. Без дополнительной информации это будет не более чем смутное предположение.   -  person Daniel Jour    schedule 11.10.2015
comment
@DanielJour Нет, где я сказал, что вы не должны смотреть на GDT (или что-то еще). Но я упомянул IDT, потому что это была часть вашего обсуждения (и OP). Кажется, я пока единственный человек, который проголосовал за закрытие этого вопроса, потому что информации недостаточно.   -  person Michael Petch    schedule 11.10.2015
comment
@MichaelPetch Ой, пожалуйста, извините меня, я неправильно понял ваш первый комментарий :) Я все еще надеялся, что OP добавит соответствующие детали, но похоже, что этого не произойдет, поэтому я тоже голосую за то, чтобы закрыть это.   -  person Daniel Jour    schedule 11.10.2015
comment
Если происходит сбой сразу после установки CR0 и входа в защищенный режим, то проблема не в IDT содержимого. IDT читается только по мере необходимости, и на этом этапе нет необходимости читать IDT. У вас должны быть отключены прерывания (CLI), и не должно быть причин для возникновения ошибки или исключения. В частности, поскольку вы переназначили прерывания PIC, единственное, что может заставить ЦП прочитать 15-ю запись IDT, - это явная инструкция INT 0x0f.   -  person Ross Ridge    schedule 12.10.2015
comment
@RossRidge ОС может перейти в защищенный режим и выполнить код пользовательского пространства в user_space.asm   -  person Tu Do    schedule 12.10.2015
comment
Это противоречит тому, что вы написали в своем вопросе. В любом случае остается, что нет причин, по которым содержимое 15-й записи IDT могло вызвать сбой.   -  person Ross Ridge    schedule 12.10.2015
comment
@RossRidge На самом деле, без добавления 15-й записи, я могу выполнить код в user_space.asm, но после добавления 15-й записи в idt.inc и при попытке перейти к первой инструкции ядра (расположенной в 0x10ff0, вы можете увидеть код ядра в kernel.asm) в защищенном режим, он разбился. Я не уверен, произошло ли в это время какое-то прерывание, требующее 15-й записи.   -  person Tu Do    schedule 12.10.2015


Ответы (1)


Я знаю, что было не так. Причина в том, что я выделил только один сектор для stage2.asm, но добавление дополнительных записей увеличивает загрузчик этапа 2 за пределы 512 байт. По этой причине IDT деформировалась при загрузке и произошла ошибка.

Я изменил эту строку в Makefile, которая выделяет только 1 сектор:

dd if=$(BUILD_DIR)/stage2.bin of=disk.dsk bs=512 count=1 seek=1

выделить 3 сектора:

dd if=$(BUILD_DIR)/stage2.bin of=disk.dsk bs=512 count=3 seek=1

Я знаю, что мне следует начать писать файловую систему, но я займусь этим позже, поскольку ядро ​​для меня имеет более высокий приоритет.

person Tu Do    schedule 12.10.2015