Перейти к содержимому
Аладдин Р.Д.
Библиотека

Немного о багах в BIOS/UEFI ноутбуков Lenovo/Fujitsu/Toshiba/HP/Dell

БиблиотекаБиблиотека

Июль, 2017

Описание багов BIOS/UEFI ноутбуков, с которыми приходилось работать при адаптации загрузчиков (баги не видны пользователю, но мешают работе загрузчика, даже если всё сделано правильно; выявлены как в интерфейсах сред исполнения, так и в коде режима SMM процессоров Intel). Контекст: существует продукт, шифрующий системный диск — на этапе запуска ПК разработанный загрузчик расшифровывает диск и после установки перехватчиков передаёт управление оригинальному загрузчику ОС. Баги — от простых к сложным.

Lenovo, UEFI: запуск загрузчика. UEFI игнорировал значение глобальной переменной BootOrder и всегда загружал Windows, если находил её запись (загрузчик записывался на системный раздел и ставился первым в очереди — без толку). Обход: подмена загрузчика самой Windows (добавляет работу — подменный файл надо защищать в ОС).

HP, UEFI: посылка USB-команд. Загрузчик не определял ни одного USB-устройства (CCID-ридеры), при этом ноутбук запускался с флэшки. При вызове UsbControlTransfer протокола EFI_USB_IO_PROTOCOL — таймаут. Ошибка: в реализации EfiUsbDataIn и EfiUsbDataOut перепутаны местами — вызов с EfiUsbDataOut в действительности читал с устройства, и наоборот. Некрасивое решение: при запуске проверять поле FirmwareRevision структуры EFI_SYSTEM_TABLE на “HPQ” + значение 0x10000001 и для таких прошивок намеренно менять EfiUsbDataIn/EfiUsbDataOut на противоположные.

Fujitsu LifeBook E743, UEFI: USB-ответы. Новые CCID-устройства не работали: UsbBulkTransfer всегда возвращал EFI_DEVICE_ERROR. Причина: USB допускает короткий пакет от устройства, и хост-контроллер возвращает статус “Short Packet”, но драйвер USB трактовал его как ошибку (стые CCID отвечали длинными пакетами, новые — короткими). Обход через анализ выходного буфера: в формате RDR_to_PC_DataBlock поле bMessageType всегда 0x80 — оно предварительно обнулялось, и если после “ошибки” поле оказывалось 0x80, ответ считался корректным, а размер вычислялся по dwLength.

Toshiba Satellite U200, BIOS: карта памяти. Загрузчик не находил участок памяти для размещения резидентного кода: при сканировании карты (сервис 0xe820 прерывания int 15h) часть диапазонов пропускалась. BIOS трактовал входной регистр ECX (размер буфера, у загрузчика — 64) как число записей, возвращаемых за один вызов, — считывалось по две записи, одна игнорировалась. Решение: передавать в ECX 24, отказавшись от прямой совместимости с будущими версиями BIOS.

HP, BIOS: остановка USB 3.0 и переинициализация PIC. После ввода ПИН смарт-карты ПК зависал намертво. Цепочка: загрузчик на базе RTOS в защищённом режиме перед возвратом в реальный режим возвращает PIC-контроллер в исходное состояние (PIC давно эмулируется через SMM); RTOS при остановке USB 3.0 хост-контроллера сбрасывала бит HC OS Owned Semaphore (24) регистра USBLEGSUP, возвращая управление BIOS, но не дожидалась установки бита HC BIOS Owned Semaphore (16) — и SMI-обработчик возвращал управление над хост-контроллером, породивший SMI PIC-контроллер не обрабатывался вовсе. Контроллер оставался частично непроинициализированным, доставка прерываний ломалась, процессор вставал на невалидный вектор. Обход: ожидание установки бита 16 перед возвратом PIC.

Dell Latitude E7240, BIOS: доставка прерываний от PIC. Зависание при перезагрузке (при включении — норма): page fault на странице перед страницей со стеками прерываний (у RTOS отдельные 256-байтные стеки на прерывание, смежно). Причина: эмулируемый PIC доставлял прерывание повторно до посылки EOI — переполнялся стек прерывания, портились соседние, доступ уходил на неотображённую страницу. Обход: запрет доставки прерывания на PIC до вызова зарегистрированных обработчиков и разрешение после.

Заключение. Список неполный; радикального решения проблемы стабильности нет — “тратить по три дня на анализ и устранение” каждой проблемы при десятке проблем выбивает из графика. Понимание реальности вынудило к реверс-инжинирингу загрузчика Windows — использовать только те механизмы, что использует он. После проблем с USB в UEFI в загрузчик помещены собственные драйверы хост-контроллеров (со “костылями” код станет тяжело развивать; свои драйверы также закрывают FastBoot, который не гарантирует загрузку USB-драйверов — камень в огород UEFI как стандарта). Складывается впечатление, что BIOS/UEFI разрабатываются в отрыве от понимания принципов работы или без должного тестирования: достаточно, чтобы запускался Windows и Linux — “всё остальное — издержки производства”. BIOS и UEFI — самые нестабильные среды исполнения; тяжелее всего работать с EFI MacBook, но это другая история.

Это краткая аннотация статьи, полную версию читайте в первоисточнике.


Читать полную версию

Первоисточник: Интернет-портал habrahabr.ru, июль, 2017

Эксперт: Блог Аладдин на Хабре