Недавно столкнулся с программой VmWare. И был очень удивлен теми
фокусами, которые она вытворяет. Я и не предполагал, что на одной
машине могут работать несколько виртуальных i386 машин. Разве
такое в принципе возможно? Ведь каждая из операционных систем
должна переодически переключаться в защищенный режим и исполнять
привелигированные инструкции, управлять памятью и т.д. И тем не
менее это работает.
Никто случайно не знает, как такое возможно ? Или есть какие идеи ?
Здравствуйте Debug, Вы писали:
D>Никто случайно не знает, как такое возможно ? Или есть какие идеи ?
Возможно из-за того что на процессорах Intel 80x86 существует исключение "привелигированная инструкция".
Оно возникае в том случае когда юзеровская программа пытается вызвать "опасную" команду типа IN, OUT и т.д.
VMWare включает в себя драйвер который работает в привилегированном режиме и перехватывает такие исключения,
делает то что попросили и возвращает управление юзеровской программе — вот вкратце и все .
____________________
God obviously didn't debug, hasn't done any maintenance, and no documentation can be found. Truly amateur work.
Здравствуйте Debug, Вы писали:
D>Недавно столкнулся с программой VmWare. И был очень удивлен теми D>фокусами, которые она вытворяет. Я и не предполагал, что на одной D>машине могут работать несколько виртуальных i386 машин. Разве D>такое в принципе возможно? Ведь каждая из операционных систем D>должна переодически переключаться в защищенный режим и исполнять D>привелигированные инструкции, управлять памятью и т.д. И тем не D>менее это работает.
Все оперционки там все время в защищенном режиме, если считать "виртуальный 86" режим разновидностью защищенного (для случая с DOS). Привелегированные команды отличаются от непривелегированных только тем, что при выполнении первых (при выполнении кой-каких условий) возникает GPF. Обработчик этого GPF может сделать все, что угодно — просто выполнить команду и передать управление обратно, как будто никакого GPF и в помине не было, "хитро" выполнить команду — сэмулировать ввод/вывод для устройства, которого нет или выполнить вызов драйвера host-операционки (в терминологии VmWare), или, наконец, просто прибить задачу, выполнившую привелегированную команду (чем так любит заниматься Windows). Так что фокус только в корректной эмуляции железа и написании драйверов для guest и host операционок.
Есть, правда, еще одна проблема. На "правильном" процессоре при работе в защищенном режиме для задачи не должно быть способа определить, на каком кольце защиты она выполняется (и вообще, в каком режиме работает процессор), кроме хронометража (по снижению производительности). К сожалению, для процессоров i386 это не так — вроде есть какой-то (не совсем очевидный) способ прочитать то ли весь регистр CR0, то ли его бит PE). Единственная операционка, AFAIK, которая использует этот хак — OS/2, и то только во время инсталляции. VmWare ее, кстати, не поддерживает :( .
D>Никто случайно не знает, как такое возможно ? Или есть какие идеи ?
Читай книгу Шульмана "Неофициальная Windows 95". Там это неплохо расписано. И (или) доки на процессор.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.
Re[2]: Чудеса VmWare
От:
Аноним
Дата:
27.06.02 10:32
Оценка:
Здравствуйте TepMuHyc, Вы писали:
TMH>Возможно из-за того что на процессорах Intel 80x86 существует исключение "привелигированная инструкция". TMH>Оно возникае в том случае когда юзеровская программа пытается вызвать "опасную" команду типа IN, OUT и т.д. TMH>VMWare включает в себя драйвер который работает в привилегированном режиме и перехватывает такие исключения, TMH>делает то что попросили и возвращает управление юзеровской программе — вот вкратце и все .
Если честно, не совсем понятно. Например. Есть хост-операционная система WinXP, под ней, как гостевая запущена Win2K.
В последней происходит какой-либо системный вызов (т.е. вызывается INT 2E). Необходимо обработать данное прерывание. Для этого должно произойти переключение процессора в защищенный режим, в котором он "рулит" машиной как хочет. В частности происходит управление физической памятью, устанавливаются типы подкачки страниц (регистр CR3) и т.д. Причем, машина получает доступ ковсем ресурсам. Кто и как должен управлять такими ситуациями ? Как хост-операционка передает (и передает ли) управление гостевым ОС, как забирает потом управление ? Как решаются проблемы с управлением памятью и обработкой прерываний ? Ведь гостевая ОС полностью функциональна, будто бы она запускалась сама по себе, и о хостовой ОС "не догадывается". Тем более, что гостевых ОС может быть несколько. Одним драйвером режима ядра тут не обойтись (на мой взгляд). Хотя может я и ошибаюсь.
Большое спасибо за ответ, но хотелось бы что-то поподробнее.
S>Все оперционки там все время в защищенном режиме, если считать "виртуальный 86" режим разновидностью защищенного (для случая с DOS). Привелегированные команды отличаются от непривелегированных только тем, что при выполнении первых (при выполнении кой-каких условий) возникает GPF. Обработчик этого GPF может сделать все, что угодно — просто выполнить команду и передать управление обратно, как будто никакого GPF и в помине не было,
что собственно и делается при запуске DOS сессии в Win9x
S>"хитро" выполнить команду — сэмулировать ввод/вывод для устройства, которого нет или выполнить вызов драйвера host-операционки (в терминологии VmWare),
интересно, VmWare "держит" и Linux и WinNT все версии и Win9x тоже все. Все их функции эмулировать — это наверное будет накладно (к тому же VmWare и "весит" не столько, чтобы вместить весь необходимый код). А как, например, эммулировать распределение виртуальной памяти, ведь каждая из ОС пытается сама управлять физической доступной памятью?
А обработчики прерываний? У процессора ведь только 1 ITDR (interrupt table descriptor register). А как понять в "виртуальном 86" гостевой операционки, что выполняется в данный момент: код пользователя или ядра (должна ведь обеспечиваться защита памяти) ?
S>или, наконец, просто прибить задачу, выполнившую привелегированную команду (чем так любит заниматься Windows).
ну это мало интересно
S> Так что фокус только в корректной эмуляции железа и написании драйверов для guest и host операционок.
насколько я видел, драйвера в хостовой ОС не заменяются VmWare, только добавляется пара новых
S>Есть, правда, еще одна проблема. На "правильном" процессоре при работе в защищенном режиме для задачи не должно быть способа определить, на каком кольце защиты она выполняется (и вообще, в каком режиме работает процессор), кроме хронометража (по снижению производительности). К сожалению, для процессоров i386 это не так — вроде есть какой-то (не совсем очевидный) способ прочитать то ли весь регистр CR0, то ли его бит PE). Единственная операционка, AFAIK, которая использует этот хак — OS/2, и то только во время инсталляции. VmWare ее, кстати, не поддерживает .
ксати, интересный момент
S>Читай книгу Шульмана "Неофициальная Windows 95". Там это неплохо расписано. И (или) доки на процессор.
Здравствуйте Debug, Вы писали:
S>>Все оперционки там все время в защищенном режиме, если считать "виртуальный 86" режим разновидностью защищенного (для случая с DOS). Привелегированные команды отличаются от непривелегированных только тем, что при выполнении первых (при выполнении кой-каких условий) возникает GPF. Обработчик этого GPF может сделать все, что угодно — просто выполнить команду и передать управление обратно, как будто никакого GPF и в помине не было,
D>что собственно и делается при запуске DOS сессии в Win9x
Не, даже там не для всего так. Доступ к портам иногда эмулируется, например, для принтера.
S>>"хитро" выполнить команду — сэмулировать ввод/вывод для устройства, которого нет или выполнить вызов драйвера host-операционки (в терминологии VmWare),
D>интересно, VmWare "держит" и Linux и WinNT все версии и Win9x тоже все. Все их функции эмулировать — это наверное будет накладно (к тому же VmWare и "весит" не столько, чтобы вместить весь необходимый код).
А зачем эмулировать все их функции? Достаточно эмулировать ввод/вывод и процессор (прерывания и управляющие регистры, работу с памятью). Насчет тормозов — они есть. Естественно, "обычный" код приложений, выполняющихся в guest-операционках, не тормозит. Но вызовы прерываний, ввод/вывод, обработка исключений — тормозит со страшной силой. Особенно ввод/вывод.
D> А как, например, эммулировать распределение виртуальной памяти, ведь каждая из ОС пытается сама управлять физической доступной памятью?
Про память не скажу, совсем не в курсе. Но думаю, примерно так же, как и все остальное.
D>А обработчики прерываний? У процессора ведь только 1 ITDR (interrupt table descriptor register). А как понять в "виртуальном 86" гостевой операционки, что выполняется в данный момент: код пользователя или ядра (должна ведь обеспечиваться защита памяти) ?
Регистр-то один, зато доступ к нему — привелегированный. Супервизор при попытках записи гостей в настоящий IDTR запоминает, что они туда суют, при попытках чтения — возвращает им запомненное значение. При возникновении прерывания host-обработчики разбираются, откуда оно пришло и при необходимости "вспоминают" IDTR гостя и передают управление в соответствующий обработчик гостя.
S>> Так что фокус только в корректной эмуляции железа и написании драйверов для guest и host операционок.
D>насколько я видел, драйвера в хостовой ОС не заменяются VmWare, только добавляется пара новых
Я не говорил, что какие-то дрова менять надо. Но, как минимум, таблицу дескрипторов прерываний подлатать придется.
Одним из 33 полных кавалеров ордена "За заслуги перед Отечеством" является Геннадий Хазанов.