Содержание статьи
Микросхемы SPI Flash ROM, в частности микросхема SST 25VF080B, используемая в
рассматриваемой платформе поддерживают сигнал защиты записи WP# (Write Protect).
В отличие от одноименного сигнала микросхем LPC Flash, для SPI Flash этот сигнал
не управляет непосредственно разрешением записи информации, а действует в
сочетании с битами BP0-BP3 (Block Protect) и BPL (Block Protect Lock) регистра
статуса. Четыре бита в регистре статуса BP0-BP3 выбирают один из 16 вариантов
защиты микросхемы BIOS, среди этих вариантов – полный запрет записи по всем
адресам, разрешение записи по всем адресам, а также варианты, обеспечивающие
избирательную защиту блоков. Разумеется, сама по себе такая защита не
эффективна, поскольку программа может изменить содержимое битов BP0-BP3 и
разрешить запись. Чтобы этого не произошло, используется бит BPL и внешний
сигнал защиты записи WP#. Установка бита BPL=1 делает биты BPL и BP0-BP3
недоступными для перезаписи. Данная защита действует только при наличии сигнала
логического "0" на вход WP#, а при наличии логической "1" на входе WP#, биты BPL
и BP0-BP3 доступны для перезаписи независимо от состояния бита BPL.
Таким образом, защитой содержимого микросхемы BIOS можно программно управлять
посредством регистра статуса, а объектом аппаратной защиты, реализуемой сигналом
WP#, является содержимое регистра статуса, а не записанная информация.
Подробности в [5].
Для активации данного механизма защиты, BIOS при старте платформы должен
записать значение битов BP0-BP3 в соответствии с требуемым режимом защиты, а
также установить бит BPL=1 для предотвращения последующей модификации битов
BP0-BP3 и BPL. Затем требуется обеспечить подачу логического "0" на вход WP#.
Желательно, чтобы метод программного управления сигналом WP# был уникален для
каждой модели материнской платы, это осложнит работу "вирусописателей".
К сожалению, и этот механизм защиты, поддерживаемый микросхемами SPI Flash,
реально не используется разработчиками BIOS и материнских плат. Во всех
платформах, исследованных автором, в регистре статуса Flash, бит BPL=0, то есть
защита не используется и статусный регистр доступен для перезаписи.
Примечание
Символ "#" после названия сигнала означает, что активным уровнем является
низкий. Например, рассматриваемый сигнал защиты записи WP# (Write Protect),
интерпретируется следующим образом: Логический "0" означает наличие защиты
записи, логическая "1" – отсутствие защиты. В цифровой схемотехнике такие
сигналы называют инверсными.
Запуск операций стирания и записи содержимого микросхемы SPI Flash
выполняется в два этапа. Сначала передается команда Write Enable, затем команда,
непосредственно запускающая стирание или запись. Если заданная
последовательность операций не соблюдена, содержимое микросхемы не изменяется.
Такой механизм эффективно защищает BIOS от случайного искажения в результате
программного сбоя, однако препятствием для "вирусописателей" он не является, так
как требуемая последовательность операций описана в открытой документации на
микросхемы SPI Flash, например [4-7].
Меры предосторожности
При отладке предлагаемых процедур, выполняющих стирание и перезапись
содержимого микросхемы Flash ROM, неизбежно существует риск искажения BIOS с
последующим отсутствием старта материнской платы. Примеры, содержащиеся в
прилагаемом каталоге WORK, рассчитаны на специалистов, имеющих квалификацию и
оборудование для восстановления BIOS, если это потребуется. Идеальное рабочее
место для отладки предлагаемых программ – это материнская плата, в которой
микросхема BIOS установлена в "панельку", допускающую извлечение микросхемы без
использования пайки, в сочетании с программатором. Исходное содержимое
микросхемы желательно сохранить в виде двоичного файла. Заметим, что если будет
искажен BIOS Boot Block, процедуры самовосстановления, рекламируемые
производителями материнских плат, окажутся неработоспособными. Напомним, что во
время рабочего сеанса используется копия BIOS в Shadow RAM, поэтому если
содержимое микросхемы BIOS будет искажено, это проявится только при очередной
перезагрузке. Таким образом, чтобы избежать необходимости аварийного
восстановления BIOS, перед сбросом или выключением питания следует восстановить
исходное содержимое Flash ROM.
Категорически не рекомендуется проводить эксперименты на основном рабочем
компьютере, лучше собрать стенд, используя, например, старую плату, оставшуюся
после апгрейда.
Замечания по совместимости
Операции, рассматриваемые в примерах 1-3, требуют программирования
конфигурационных регистров и ресурсов платформы, реализация которых различается
в разных чипсетах. Разумеется, рассмотреть все наборы системной логики в рамках
одной статьи невозможно, поэтому автор остановился на конкретном примере:
материнская плата Gigabyte GA-965P-S3 (чипсет Intel 965, микросхема BIOS SST
25VF080B). Примеры 1-3 предназначены только для плат с указанной элементной
базой. Используя предлагаемый материал, заинтересованный читатель может
реализовать библиотеку процедур для поддержки более широкой номенклатуры
платформ.
Пример 1. Процедура чтения идентификатора и регистра статуса Flash ROM.
Как и в ранее опубликованных статьях данного цикла, в целях монопольного и
беспрепятственного взаимодействия программы с оборудованием при работе с
предлагаемым примером, автор применил "древнюю" технологию отладки под DOS.
Аргументация такого шага и рекомендации по организации рабочего места приведены
в ранее опубликованной статье "64-битный
режим под DOS: исследовательская работа № 1". Прежде чем рассматривать
процедуры стирания и записи содержимого микросхемы BIOS, рассмотрим более
простой пример – чтение идентификатора и статуса этой микросхемы.
Каталог WORK\ID_FLASH содержит следующие файлы:
ASM_TD.BAT – обеспечивает ассемблирование, линковку и запуск программы
под отладчиком. При запуске TASM и TLINK используются опции, обеспечивающие
добавление отладочной информации в EXE файл.
ASM_EXE.BAT – обеспечивает ассемблирование и линковку. Генерируется
EXE файл.
FLASH_ID.ASM – основной модуль программы.
A20.INC – Библиотека для управления и контроля состояния адресной
линии A20 с использованием выходного порта контроллера клавиатуры.
BIGREAL.INC – Библиотека поддержки режима Big Real Mode, для
использования 32-битных адресов в диапазоне 0-4 Гб. Этот режим, как и управление
адресной линией A20, необходимы для работы данной программы, так как в
рассматриваемой платформе, регистры контроллера SPI используют технологию
Memory-mapped I/O, то есть адресуются в пространстве памяти.
SPIFLASH.INC – Библиотека процедур для взаимодействия с микросхемой
BIOS, подключенной к интерфейсу SPI. Реализация контроллера SPI в различных
чипсетах отличается, данная библиотека предназначена для поддержки микросхемы
Intel ICH8, то есть "южного моста" чипсета Intel 965. Для полного понимания
работы процедур данной библиотеки, следует обратиться к документу [3].
OUTPUT.INC – Библиотека процедур для вывода текстовых сообщений с
использованием функций DOS и перевода шестнадцатеричных чисел в текстовое
представление.
DATASEGS.INC – Сегменты данных. Содержит сегмент переменных, сегмент
текстовых строк и сегмент стека.
Рассмотрим выполнение программы чтения идентификатора и статуса микросхемы
BIOS. Нумерация пунктов приведенного ниже алгоритма соответствует нумерации
пунктов в комментариях к исходному тексту программы. См. файл
WORK\ID_FLASH\flash_id.asm.
1) Установка адреса стека, загрузка регистров SS и SP.
2) Выдача сообщения о начале выполнения программы.
3) Проверка режима работы процессора (Real или Protected). Так как данная
программа использует непосредственное взаимодействие с регистрами чипсета и
другими системными ресурсами, процессор должен быть в режиме Real Mode. Если
процессор в режиме Protected Mode, переходим к пункту 15 (завершение с ошибкой).
4) Подготовка к адресации памяти выше 1 MB. Для этого разрешаем адресную
линию A20 и включаем режим Big Real Mode, обеспечивающий использование 32-битной
адресации в реальном режиме. Это необходимо для доступа к регистрам диапазона
SPIBAR. Подробности в [3]. Если при управлении адресной линией A20 возникли
ошибки, переходим к пункту 15 (завершение с ошибкой).
5) Детектирование чипсета материнской платы, получение адреса диапазона RCBA
(Root Complex Base Address). Вначале проверяем наличие поддержки функций
PCIBIOS, затем, используя PCIBIOS, проверяем наличие "южного моста" Intel ICH8
по кодам PCI Vendor ID, PCI Device ID. Если чипсет не распознан, переходим к
пункту 14 (завершение с ошибкой). Напомним, что текущая версия программы
поддерживает платформы только с данным типом "южного моста". Считываем базовый
адрес диапазона RCBA.
6) Установка разрешения циклов записи для интерфейса SPI. Устанавливаем бит 0
в регистре BIOS_CNTL. Подробности в [3].
7) Установка указателей и сегментных регистров. DS:EBX далее будет
использоваться как базовый адрес блока регистров контроллера SPI (SPIBAR). Этот
указатель является входным параметром для подпрограмм SPI_Read и
Scan_Opcode_Menu. По правилам Big Real Mode, DS=0, а EBX содержит 32-битный
физический адрес. Базовый адрес блока регистров управления контроллера SPI равен
RCBA+3020h. Сегмент ES будет использоваться для генерации строк текстовых
сообщений.
8) Считываем и визуализируем идентификатор микросхемы Flash ROM.
Идентификатор содержит два байта. Первый байт – Vendor ID (синоним Manufacturer
ID) идентифицирует производителя микросхемы, в нашем примере он равен BFh, этот
код присвоен фирме SST. Второй байт – тип микросхемы, для 25VF080B он равен 8Eh.
Процедура чтения идентификатора состоит из передачи микросхеме кода команды (90h
для команды Read ID) и считывания двух байт идентификатора.
Напомним, что контроллер SPI не позволяет непосредственно передать код
команды микросхеме Flash ROM, это делается косвенно, посредством блока регистров
OpCode Menu. Каждый байт 8-байтного блока OpCode Menu содержит один из кодов
команд для микросхемы Flash ROM (чтение идентификатора, чтение статуса, запись,
стирание, и т.п.). Этот блок инициализирует BIOS при старте платформы. Для
передачи команды, программа должна передать контроллеру номер байта в 8-байтном
блоке OpCode Menu, содержащего код этой команды. Так как расположение кодов в
ячейках OpCode Menu зависит от реализации BIOS и может быть произвольным,
программа сначала должна просканировать OpCode Menu и найти номер ячейки, в
которой хранится код требуемой команды (90h для Read ID). Эту функцию выполняет
подпрограмма Scan_OpCode_Menu. Затем, полученный 3-битный номер ячейки
используется как битовое поле COP (Cycle Opcode Pointer) при формировании
32-битного кода операции для контроллера SPI. Кроме COP, код операции также
содержит информацию о количестве передаваемых байт данных, частоте битовой
синхронизации и т.п. Сформированный 32-битный код операции является входным
параметром для подпрограммы SPI_Read, которая записывает его в регистр Software
Sequencing Flash Control Register, инициируя начало выполнения транзакции на
шине SPI. Перед этим необходимо записать адрес в регистр Flash Address Register.
Затем, циклически опрашиваем регистр Software Sequencing Flash Status Register
для определения момента завершения транзакции. После этого, из регистра Flash
Data 0 Register, считываем полученные данные, в нашем случае это два байта
идентификатора микросхемы Flash ROM. Подробности в [3,5].
9) Считываем и визуализируем регистр состояния микросхемы Flash ROM. Этот
регистр содержит один байт, его побитное описание приведено в [5]. Код команды
Read Status – 05h, количество читаемых байт – 1. В остальном, данная процедура
аналогична процедуре чтения идентификатора, описанной в пункте 8.
10) Восстанавливаем исходное значение регистра BIOS_CNTL, сохраненное перед
его перенастройкой в пункте 6.
11) Восстанавливаем исходное состояние адресной линии A20 и выключаем режим
32-битной адресации (Big Real Mode).
12) Вывод сообщения об успешном выполнении программы и завершение. Эта точка
выхода используется при отсутствии ошибок.
13) Начало последовательности, используемой для завершения программы при
ошибках. Восстанавливаем исходное значение регистра BIOS_CNTL, сохраненное перед
его перенастройкой в пункте 6. Сюда управление передается, если произошли ошибки
после перенастройки регистра BIOS_CNTL и требуется его восстановление перед
завершением программы.
14) Восстанавливаем исходное состояние адресной линии A20 и выключаем режим
32-битной адресации (Big Real Mode).
15) Вывод сообщения об ошибках и завершение программы. При передаче
управления на этот пункт, регистр BP должен содержать указатель на строку
сообщения об ошибке.
Пример 2. Процедура чтения Flash ROM.
Ассемблерный пример, выполняющий чтение содержимого микросхемы BIOS в файл,
находится в каталоге WORK\RD_FLASH. Программа выполняет
сохранение области адресного пространства FFF00000h-FFFFFFFFh в файл размером 1
Мб и фиксированным именем BIOS.BIN. Файл создается в текущем каталоге. Размер
сохраняемого блока не зависит от реального размера используемой микросхемы BIOS,
распознавание типа и размера микросхемы не реализовано в данной версии.
Поддерживаются только материнские платы с "южным мостом" Intel ICH8. Для
гарантированного включения полного объема микросхемы BIOS в адресное
пространство, программа использует установку битов FWH_F8_EN, FWH_F0_EN в
регистре FWH_DEC_EN1, чем и обусловлена ее привязка к конкретному чипсету.
Подробности в [3].
Отметим, что в большинстве платформ, для чтения содержимого SPI Flash можно
использовать "старый" метод доступа посредством окна в адресном пространстве,
это и реализовано в данном примере. А операции, требующие передачи команд
микросхеме SPI Flash (чтение идентификатора или статуса, запись, стирание) могут
быть выполнены только с использованием регистров контроллера SPI. Такой метод
использован в примерах 1 и 3.
Пример 3. Процедура стирания и перезаписи Flash ROM.
Ассемблерный пример, выполняющий стирание и перезапись микросхемы BIOS,
находится в каталоге WORK\WR_FLASH. Программа выполняет
запись содержимого файла с фиксированным именем BIOS.BIN и размером 1 Мб в
микросхему BIOS. Файл должен находиться в текущем каталоге.
Заключение
В очередной раз подчеркну, что целью данного цикла публикаций не является
обучение "вредителей". Материалы будут полезны специалистам по информационной
безопасности, разработчикам аппаратного и системного программного обеспечения.
Выработка механизмов для противодействия какой-либо угрозе невозможна без
детального изучения самой угрозы.
Вся приведенная информация получена из открытых источников, список которых
прилагается.
Источники информации
Электронные документы, доступные на сайте
developer.intel.com.
1) Intel Low Pin Count (LPC) Interface Specification. Revision 1.1. Document
Number 251289-001.
2) Intel P965 Express Chipset Family Datasheet – For the Intel 82P965 Memory
Controller Hub (MCH). Document Number: 313053-001.
3) Intel I/O Controller Hub 8 (ICH8) Family Datasheet – For the Intel 82801HB
ICH8 and 82801HR ICH8R I/O Controller Hubs. Document Number: 313056-001.
Электронные документы, доступные на сайте
www.superflash.com или
ssti.com.
4) 1 Mbit SPI Serial Flash SST25VF010 Data Sheet. Document Number:
S71233-01-000.
5) 8 Mbit SPI Serial Flash SST25VF080B Data Sheet. Document Number:
S71296-01-000.
Электронные документы, доступные на сайте
winbond.com.tw.
6) W25X10A, W25X20A, W25X40A, W25X80A 1M-bit, 2M-bit, 4M-bit and 8M-bit
Serial Flash Memory with 4KB sectors and dual output SPI Data Sheet.
Электронные документы, доступные на сайте
macronix.com.
7) MX25L802 8M-bit [8Mx1] CMOS Serial Flash EEPROM Data Sheet.
Электронные документы, доступные на сайте
datakey.com.
8) SPI EEPROM Interface Specification. Part Number 223-0017-004 Revision H.
Электронные документы, доступные на сайте
vtitechnologies.com.
9) SPI Interface Specification. Technical Note 15.
Электронные документы, доступные на сайте
pcisig.com.
Документы [11], [12] на сайте pcisig.com доступны только для членов PCI
Special Interest Group. Воспользовавшись поисковыми системами, можно найти
данные документы для свободной загрузки.
10) PCI BIOS Specification. Revision 2.1.
11) PCI Local Bus Specification. Revision 3.0.
12) PCI-to-PCI Bridge Architecture Specification. Revision 1.1.