Для начала стоит напомнить читателю о том, что BIOS, в оригинале, был неотъемлемой частью операционной системы фирмы Microsoft. Ну вот, например, рассмотрим работу с серийным портом в ОС MS DOS: нам не обязательно знать, какое именно оборудование установлено, так как мы оперируем вводом-выводом в некоторую зону памяти (I/O port) и отслеживаем некоторые прерывания. И то и другое нам предоставляет BIOS. Так же и с дисками: нет дискового контроллера, есть адреса в памяти и прерывания. То есть, фактически, BIOS предоставлял MS DOS услуги по инициализации устройств, предоставлял абстракцию для работы с ними, и, в последнюю очередь, передавал управление загрузчику ОС.

Тогда не было инструментов автоматической конфигурации устройств, и после установки каждого устройства на шину ISA, надо было взвести тумблеры на материнской плате в определённое положение, чтобы BIOS знал, какие регионы памяти и прерывания он должен зарезервировать, к каким портам шины он должен их привязать. Это архитектурная особенность шины, которая перекачивала и в современное её представление — шину LPC (таки да, почти во всех современных ПК на x86 есть сериализированный наследник шины ISA, на нём сидят SuperIO и ЕС подсистемы), которая требует описания подключенных к ней устройств для корректной работы. Хорошо хоть это делается один раз — при написании BIOS’а под конкретную материнскую плату.

А потом фирма IBM, пытаясь тем самым вернуть рынок «персоналок», решила выкатить новую системную шину, которая даровала смертным труЪ Ынтерпрайз, а именно 32х-битный Микроканал (MCA), умевший в поиск установленных устройств и их автоматическую настройку. Но задачу обеспечения совместимости с MS DOS никто не отменял, так что надо было как-то производить манипуляции с устройствами, выдав в конце заветный адрес и прерывание. А действий может быть много, и они зависят от того, какой именно функционал нужен от периферийного устройства пользователю. Короче, нужна целая программа, которая предоставляла бы пользователю интерфейс для настройки функционала, а потом инициализировала бы это устройство, создавая адреса в памяти и занимая прерывания. Исполнятся эта программа должна в контексте инициализации оборудования, размещаться должна на устройстве. Собственно в таком виде это до нас и дошло: устройства на шине PCI (PCIe) могут иметь свою микропрограмму инициализации (OPROM), которая должна быть найдена BIOS’ом и исполнена до передачи управления загрузчику ОС. Яркий пример — интерфейсы конфигурации дисковых контроллеров.

Ну а на современных материнских платах, где очень много оборудования интегрировано изначально, OPROM принято хранить прямо в образе BIOS’а. Но в формате отдельных участков. То есть взаимодействие с ними осуществляется так же, как с OPROM’ами на платах расширения, просто расположены они в той же микросхеме ПЗУ, что и BIOS.

А ещё, со временем, компьютеры перестали поставляться с операционной системой, прошитой в микросхему BIOS’а. ОС туда не помещались уже никак. Там осталась только часть, ответственная за первичную инициализацию, способная потом отдать управление в некий адрес, принадлежащий дисковому накопителю или чему ещё. Ну а сама ОС поставлялась и работала на дискете. Потом ОС увеличились в объёмах и стали поставляться на нескольких дискетах и подразумевалось, что их не плохо было бы установить на НЖМД. И грузить оттуда, без дискет. Но грузиться надо уметь и с того, и с другого. Ведь ОС надо сначала с чего-то на НЖМД установить, а потом ещё и переустанавливать надо, когда что-то не то удалишь или изменишь.

И вот тут началась веселуха: НЖМД стали большими, на них стали хранить много данных, в том числе весьма конфиденциальных. И даже если вход в ОС защищён некой аутентификацией, то никто тебе не мешает загрузится со съёмного носителя, скопировать или изменить данные, хранящиеся на НЖМД, не столкнувшись с необходимость аутентификации. Да, можно поставить пароль на вход в выбор загрузки BIOS’а, но это обходится снятием батарейки CMOS’а. Так что нужно было некоторое средство, которое бы мешало грузится с неизвестных носителей, контролировало бы целостность файлов ОС (чтобы пользователь случайно не загрузил скомпроментированную ОС), а заодно, не плохо бы, туда посадить датчики вскрытия корпуса рабочей станции. Ну и вообще стоит мешать загрузке, если пользователь не может аутентифицироваться. Ещё до начала загрузки ОС.

Это решили очень быстро: стали выпускаться различные программные (МДЗ/ПМДЗ) и программно-аппаратные (МДЗ/АПМДЗ) решения, которые перехватывали процесс загрузки сразу после инициализации оборудования BIOS’ом, и которые отдавали контроль загрузки BIOS’у только после успешного прохождения проверок аутентификационных данных пользователя и целостности файлов ОС. Выше я писал о том, как BIOS можно заставить исполнять некоторый код до передачи управления загрузчику ОС. Тут та же схема: после исполнения OPROM’ов устройств, в последнюю очередь, но до передачи управления загрузчику ОС, исполняется OPROM МДЗ. МДЗ программные, соответственно, целиком записываются в микросхему ПЗУ на мат. плате и исполняются как OPROM’ы встроенных устройств на ЦПУ самой машины, а АПМДЗ имеют свой собственный микроконтроллер, который сам исполняет свою миркопрограмму и взаимодействует с аппаратурой рабочей станции. Из-за этого, в теории, АПМДЗ имеют некоторое преимущество над МДЗ, так как на их работу не может повлиять ничто иное.

В наш век UEFI всё это является не более чем фикцией. Ибо описанные выше вещи осуществляются через прослойку эмуляции механизма BIOS’а. Выключил эмуляцию, и никакой АПМДЗ не поможет. Но UEFI подразумевает возможность написания модулей, которые могут быть интегрированы в механизм работы самого UEFI. И тут уже погоды не делает наличие аппаратной составляющей в МДЗ, так как весь код надо исполнять на ЦПУ машины, в среде UEFI. Так что АПМДЗ уверенно уходят в историю, уступая место программным реализациям МДЗ, способным интегрироваться в UEFI. Благо в UEFI для МДЗ есть специальные интерфейсы подключения, ибо UEFI спроектирован с оглядкой на Ынтерпрайз.

Беда вся в чём? После UEFI ОС не производит полную переинициализацию устройств. Это одна из «главных фишек» UEFI — уменьшение времени загрузки ОС за счёт отсутствия необходимости повторной инициализации устройств. После классического BIOS’а современные ОС осуществляли такой процесс, так как то, что отдавал им BIOS, пригодно было лишь для работы с простыми устройствами ввода-вывода. Ну и участки кода UEFI никто не вычищает из памяти, соответственно. Ну вы поняли, — там можно исполнять параллельно с ОС некоторый вредоносный код.

И даже если мы договоримся и купим исходные коды какого-либо UEFI-биоса, с целью проверки их на отсутствие «закладок» и интеграции в них нашего МДЗ, то откроется нам истина: UEFI не инициализирует процессор и память, для этого применяются напрочь закрытые компоненты от intel и amd (в зависимости от того, чья платформа используется). И на них нет ни исходников, ничего. Да, ныне ничто в Ring0 не исполняется. Нет, выход есть. Даже два:

  1. сказать, что закрытые компоненты исполняются, такие как Intel ME и AMD PSP, в Ring-1 (-2, -3, -(N+1)), то есть закрыть глаза: ведь Intel и AMD не могут хотеть нам зла, и не могут допускать ошибок в своих компонентах (хоть в том же ME уже была признана дыра Intel’ом, а обновления для микрокода CPU обе фирмы выпускают регулярно, ибо ошибки вылазят всё новые);
  2. начать создавать код инициализации аппаратного обеспечения с нуля, который позволил бы выкинуть подобные закрытые компоненты.

По второму пути пошла Google. Именно поэтому она использует проект coreboot для создания bios’ов своих chrome-устройств. Они достигли огромного прогресса в инициализации intel-платформ без использования ME, включая возможность удаления ME из прошивки. И их мотивация понятна: пока есть ME, которая имеет доступ к ЦПУ, памяти и устройствам, доступ с большим приоритетом чем ОС, при том, что это не заметно из ОС, — нам никакой МДЗ не поможет. Я уверен, что все ответсвенные данные сотрудники обрабатывают и хранят на устройствах с доверенным BIOS’ом, ибо тот код, который отдаёт Google в проект coreboot позволяет сделать вывод, что их наработки касаются далеко не только тех Chromebook’ов и Chromebox’ов, что идут в продажу.

Но по этому пути пойти не так просто, как может показаться. Ведь отказ от ME пораждает кучу проблем. Ну вот у меня, например, произошли проблемы с инициализации SuperIO, хотя на это ME, официально, никак не влияет. Я, конечно, всё героически превозмог и локализовал проблему, но, фактически, это странная ситуация и множественные подводные камни. А разработка BIOS’ов на потоке требует наличия коллектива увлечённых хакеров (в первоначальном смысле этого слова, где речь не о взломе, а о разборе по болтикам). То есть это не про такие приятные бизнесу понятия как «чёткий график разработки» и «определённые объёмы финансирования». Он про ненормированный рабочий график, когда удобно разработчику, про сроки, которые трудно предсказать, и про проблемы, которых никто не ожидал, но решать их надо.

Добавить комментарий

Ваш e-mail не будет опубликован. Обязательные поля помечены *

36 + = 45