Комментарии 25
Черный экран смерти - это, по сути, не экран смерти, а просто выход в дос.
Не знаю как сейчас, но раньше бсод обратно в реальный режим процессор не переводил. Это, вообще говоря, нетривиальная задача.
На данный момент х86 процессоры могут работать в четырёх режимах.
Real-Mode - реальный, системная поддержка в виде BIOS;
Protected-Mode - защищённый, поддержка Win и никсы;
Virtual-Mode - для эмуляции реального режима, из защищённого;
System-Management-Mode – реальный из защищённого, без эмуляции.
Не знаю как сейчас, но раньше перевести процессор из защищённого режима обратно в реальный была задача более чем тривиальная.
В общем случае это нетривиально. Предположим, вы можете выполнить произвольный код в 64-битном режиме в ринг-0. И вы ничего не знаете про ОС. Без знания мапинга линейных адресов на физические вернуться в реалмод не получится. А получить его без использования сервисов ОС мягко говоря проблематично.
Каждый раз завершая Doom (который выполнялся под экстендером DOS4GW Pro) вы выходили из Protected Mode в Real Mode (или в Virtual Mode если у вас в CONFIG.SYS грузился QEMM386). Значит и виндоуз бы справился.
Каждый раз завершая Doom (который выполнялся под экстендером DOS4GW Pro)
Всё верно, но сравнение имхо некорректное. Если проводить аналогии, надо было бы писáть «каждый раз когда крашится сам DOS4GW Pro, вы выходили в риал мод».
DOS4GW Pro в этом случае брал на себя функции ОС, а мы как раз рассматриваем случай, когда крякнула именно сама ОС, а не приложение, которое ей управляется.
Ну да, это не совсем тривиально, но вполне возможно. Конечно обычный "программист на C#", а тем более "программист 1C" или того хуже "программист на JavaScript" или "программист на Python" это не сделает, но тот кто хотя бы умеет писать драйвера [для Windows или модули для Linux] вполне это осилит. Это раз уж мы говорим про процессоры x86/x64 и про т.н. "IBM PC Compatible" компьютеры. OS тут вообще никаким боком. Находясь на кольце #0 можно без проблем прочитать все необходимые page registers, все GDT, IDT и прочую кухню. Исходя из этого определить маппинг линейных адресов на физические становится очень даже возможным. Далее запрещаем прерывания, перезагружаем GDT и IDT, перезагружаем всё что относится к табличной адресации, заодно выключая её нафиг, загружаем в сегментные регистры корректные дескрипторы для real mode, сбрасываем младший бит в регистре CR0 для выключение protected mode и включения real mode, делаем длинный jmp для сброса кеша инструкций, разрешаем прерывания и вуаля, мы в обычно реальном режиме как после сброса.
Во времена 286 сбрасывать бит PE было невозможно -- регистра CR0 не существовало, а через lmsw/smsw это бит можно было только взвести для перехода из реального в защищённый, но сбросить никак. Поэтому приходилось делать аппаратный сброс процессора записью 0xFE в порт 0x64, предварительно записав в BDA (BIOS Data Area) по адресу 0x40:0x67 адрес куда процессор должен перейти после сброса вместо обычного для него цикла POST. А начиная с 386 у CPU появился CR0 в котором запросто можно было сбросить бит PE.
Как тут уже заметили DOS4GW это делал. И Phar Lap DOS Extender это делал. Даже досовский драйвер HIMEM.SYS это прекрасно умел делать.
Я со всем этим столкнулся впервые ещё на 286 (real mode/protected mode) в конце 80-х прошлого века, после уже на 386 и 486 (real mode/protected mode/v86 mode). Вот начиная с пентиумов у меня появилась другая работа и другие интересы и необходимость в подобном отпала. Поэтому с режимом SMM не сталкивался и знаю про него только понаслышке.
В реальном режиме страничное преобразование отключено, следовательно перед возвратом в реальный режим надо настроить тождественное преобразование линейных адресов в физические. А это без помощи ОС (почти) невозможно. Мы не можем изменить существующие таблицы страниц, т.к. в CR3 физический адрес и неизвестно какие линейные адреса ему соответствуют (и есть ли такие вообще). Не можем узнать диапазоны адресов с тождественным преобразованием, т.к. не можем прочитать таблицы страниц. И мы не можем создать новые таблицы страниц ровно по той же причине - надо писать по физическим адресам, а мы можем только по линейным.
Да почему же не можем прочитать? Мы же на нулевом кольце, поэтому что хотим то и читаем. Это раз. А два это то, что мы ведь всё ещё говорим про BSOD, да? А это, сюрприз, дело рук не какой-нибудь малвари, которая "ничего не знает про OS", а дело рук самой OS. Так что этим переходом из защищённого режима в реальный будет заниматься не mycoolprog.exe от абстрактного хакера j0hN $MiTh, а абстрактная функция NtOsLeaveProtectedMode где-то в недрах ядра OS, которая по дизайну будет иметь доступ ко всем internal таблицам и функциям этой самой OS. И обладая всей этой информацией эта функция прекрасно воссоздаст все необходимые вещи, включая пресловутый маппинг линейных адресов на физические.
Другое дело что эта функция не написана разработчиками ядра (хотя и могла быть написана). А вот почему она не написана -- "Впрочем, это уже совсем другая история" (C) Каневский.
Да почему же не можем прочитать?
Пример. Мы хотим после переключения в реальный режим продолжить выполнение с адреса 0х10000. Ок, для простоты - mov ebx,10000h xor eax,eax mov cr0,eax jmp ebx (дескрипторы сегментов останутся старые, ну и ладно). Для этого нам надо по физическому адресу 0х10000 поместить какой-то свой код реального режима. Как это сделать в нулевом кольце в общем случае из защищенного режима при CR0.PG = 1? Никак. Для этого нужно знать линейный адрес, который отображается на физический 0х10000 (если такое отображение существует). Для этого надо прочитать таблицы страниц. Для этого надо узнать какой линейный адрес соответствует физическому адресу в CR3. Для этого надо прочитать таблицы страниц... Ну вы поняли. Без помощи ОС или хитрых трюков не обойтись.
Без помощи ОС или хитрых трюков не обойтись.
Помощь OS как раз в виде [несуществующей в реале, но вполне возможной] функции NtOsLeaveProtectedMode.
И хитрые трюки тоже вполне возможны. Другое дело что это никому не надо -- какой смысл выходить в том же Windows в реальный режим? В чём сермяжная правда от этого? В чём цимес? Лично я не могу придумать никакой реальной пользы от этого.
Один из известных трюков для работы с физической памятью, не используя сервисы ОС - отключить на время страничное преобразование (предположим, что мы в самом простом 32-битном режиме с 4-Кб страницами).
Для этого надо узнать физический адрес текущей страницы кода. Потом
mov ebx, <физический адрес нужной команды в текущей странице>
mov eax, cr0
and eax,07FFFFFFFh
mov cr0,eax
jmp ebx
(сама команда jmp ebx выбирается с еще включенным страничным преобразованием, хотя и после его отключения mov cr0,eax - это не баг, а фича).
А физический адрес можно узнать, меняя базовый адрес Local APIC с шагом 4 Кб, не путать с К&Б) и читая после модификации текущую страницу.
Как только какие-то известные значения в текущей странице перестают быть таковыми - значит мы записали в Local APIC физический адрес текущей страницы.
Правда, надо еще кэш отключать, т.к. выполнение кода из кэшируемой памяти, на которую отображен Local APIC может привести к #MC.
мы ведь всё ещё говорим про BSOD
поэтому что хотим то и читаем
Если page fault in non paged area произошёл на этапе «что хотим то и читаем», каковы дальнейшие действия ОС должна предпринять по-вашему? Вместо bsod что должно произойти?
Мне кажется, идеальным экраном смерти был именно тот самый от XP, информация выводимая им, действительно была полезна. С другой стороны, QR, ведущий на сайт с более подробной статьей о причинах ошибки был бы отличным дополнением. К сожалению, такой редакции так и не появилось...
В какой-то из старых версий Windows (в районе до 95-го включительно) на синем экране показывали имя библиотеки и имя процедуры, где возник BSOD, а потом это убрали, заставив пользователя самому как-то доставать эти дампы и скармливать их анализаторам.
Объясните мне, непродвинутому пользователю ПК, каким образом помогала информация на самом БСОДе, сколько себя помню, с нулевых, на ПК и тем более ноутах после отрисовки БСОДа комп уходил в ребут в течение 0,5 - 3-х секунд, за которые даже код ошибки невозможно было успеть прочитать, а тут пишут про "более информативный" экран у NT.
В русифицированной XP надписи по задумке должны были выводиться на русском. Но дальше видимо что-то пошло не так, русский шрифт не добавили и на синем экране выводились "кракозябры", где читаемым был только код ошибки. Для непосвященного это выглядело еще более устрашающе...
Странно именно начиная с ME я не видел синий экран, но до 2000 конечно было далеко с ее стабильность и позволяющей делать, что не позволяла ME. Рецепт без проблемной работы линейки 95-Me в правильной установке драйверов. Наподобие как строишь дом и тогда она работает годами без сбоев. Это первое, что меня удивило в 2000 - ставишь драйвера "неправильно" и все работает, правда падает производительность на уровне погрешности (измерял).
Странно, что не упоминается хотя бы Purple Screen of Death - с таким падает ESXi. А то "каких ещё цветов бывают экраны смерти", а этого-то как раз и нет в статье.
Информация
- Сайт
- www.ispsystem.ru
- Дата регистрации
- Дата основания
- Численность
- 101–200 человек
- Местоположение
- Россия
- Представитель
- ISPsystem
Цвет настроения синий — история BSOD и палитра экранов смерти