Реймонд описал забавную историю о том, как Windows делала системные вызовы на процессорах 386.
Но он выкинул 286-часть этой истории. У Microsoft и Intel была похожая на ту, что описывает Реймонд с 386, встреча, но в тот раз Microsoft попросила переключатель из защищённого режима (protected mode) обратно в реальный (real mode).
Видите ли, процессор 286 мог переключаться из реального режима (никакой виртуальной памяти) в защищённый режим (виртуальная память), но не обратно. Теория звучала так: вы никогда не захотите возвращаться обратно, потому что это было бы "глупо".
Но, конечно же, это не учитывает соображения обратной совместимости. OS/2 поддерживала только одно приложение реального режима, запущенное в системе, в "DOS Box". DOS box была просто ещё одной задачей (task), она получала свои куски процессорного времени как и другие задачи (ok, вообще-то нет, но концептуально это выглядело так), так что система делала МНОГО переключений между реальным и защищённым режимом процессора.
Было критично, что мы могли бы переключаться из защищённого режима обратно в реальный (когда переключаемся на DOS box). Проблема в том, что единственным документированным способом сделать это - была запись в устройство контроля клавиатуры (keyboard controller device) (которое, на самом деле, на PC управляло НАМНОГО большим, чем просто клавиатура). К несчастью, клавиатурный контроллер был ОЧЕНЬ медленным, так что этот механизм переключения работал за миллисекунды.
Поэтому Microsoft начала сумасшедший поиск быстрого способа переключения в реальный режим.
И потом они нашли его.
Их решение:
LIDT -1 INT 1Как это работает? Ну, LIDT -1 устанавливает описатель таблицы дескрипторов на недопустимый физический адрес. Система пытается выполнить команду INT 1, которая приводит к загрузке IDT в память (fault). Ну, IDT не может быть найдена, так что возбуждается ошибка типа not present (double fault). Эта ошибка (not present) пытается возбудиться в обработчике ошибки not present, что приводит к очередной ошибке (triple fault).
Процессор 286 не мог обрабатывать fault-ы вложенностью более трёх, так что он офигевал и перезагружал себя. Что приводило к выполнению системного ROM, и мы просто устанавливали стартовый адрес для реального режима (который хранился в памяти реального режима) и... пуф! Мы перепрыгнули из защищённого режима в реальный за микросекунды (а не миллисекунды).
Вообще-то я нашёл описание этой техники в web тут (прим.пер.: ссылка мертва, вот архив, но сейчас это описание есть много где - например, тут. А описание triple fault есть и в вики). Интересно, что статья в web говорит, что эта техника пришла от Intel - ну, они могут быть правы. Я помню, что она разрабатывалась исключительно внутри Microsoft, но я могу ошибаться. Когда я распакую вещи после переезда в новый офис, я проверю свой мануал по 286.
Много позже: я только что пролистал свой 286 reference manual (достаточно хорошо выдержанное первое издание), и я обнаружил ссылку, которая обсуждалась в статье. Комментарий выглядит так: "установите нулевую IDT для насильного выключения по любой ошибке защищённого режима или прерыванию". Вот и всё, это единственная подсказка от Intel, касающаяся техники triple fault для перезагрузки в реальном режиме. Лично я не удивлён, что инженеры IBM не разобрались в этом.
http://idioms.thefreedictionary.com/pick+up+on
ОтветитьУдалитьто есть инженеры ibm так и не разобрались в этом
Спасибо! Исправил.
ОтветитьУдалить