Обращение к BIOS из операционной системы Глава 9

advertisement
Глава 9
Обращение к BIOS
из операционной системы
Введение
В данной главе мы рассмотрим, как получить доступ к содержимому чипа
BIOS, включая содержимое чипов ROM BIOS расширения, непосредственно
из операционной системы. В первом разделе излагаются основные принципы,
а далее рассматриваются конкретные вопросы, связанные с операционной
системой, и соответствующие интерфейсы. Наконец, демонстрируется принципиальная возможность воплощения этой идеи для Linux{ XE "Linux" } и
Windows{ XE "Windows" }.
9.1. Общий способ доступа
Реализация прямого доступа к содержимому чипа BIOS из операционной
системы может показаться задачей не из легких, но в действительности это
проще, чем кажется на первый взгляд. Прямой доступ к содержимому чипа
BIOS и манипулирование этим содержимым из операционной системы можно реализовать только в случае с чипами типа EEPROM{ XE "EEPROM" }
(electrically erasable programmable ROM{ XE "electrically erasable
programmable ROM" } — электрически стираемое программируемое ПЗУ)
или флэш-ROM{ XE "флэш-ROM" }. К счастью, начиная с конца 1990-х, во
всех материнских платах применяются именно эти виды чипов ROM BIOS.
В разных операционных системах имеются разные уровни программного
обеспечения. Однако, благодаря единой модели программирования для архитектуры х86, логические действия для доступа к содержимому BIOS с любого
уровня почти одинаковы. В большинстве операционных систем архитектуры
х86 аппаратными средствами реализуется два уровня привилегий для предоставления прикладным программам прямого доступа к системным ресурсам.
Эти уровни привилегий известны как кольцо 0{ XE "кольцо 0" } (ring 0{ XE
360
Часть IV. Внесение изменений в код BIOS
"ring 0" }), или режим ядра{ XE "режим ядра" } (kernel mode{ XE "kernel
mode" }) и кольцо 3{ XE "кольцо 3" } (ring 3{ XE "ring 3" }), или пользовательский режим{ XE "пользовательский режим" } (user mode{ XE "user mode" }).
Любое программное обеспечение, исполняющееся в режиме ядра, может обращаться напрямую к аппаратным средствам, включая чип ROM BIOS, и манипулировать ими. Таким образом, общая процедура для получения доступа
к чипу ROM BIOS материнской платы из операционной системы состоит из
следующих шагов:
1. В операционной системе входим в режим ядра. В большинстве случаев, чтобы выполнить этот шаг, необходимо разработать драйвер устройства для
конкретной операционной системы. Специальный драйвер необходим по
следующим двум причинам. Во-первых, операционная система предоставляет доступ к режиму ядра только драйверам устройств. Во-вторых,
в большинстве случаев, операционные системы не предоставляют четко определенного интерфейса для манипуляции чипом BIOS (если такой интерфейс предоставляется вообще). С первого взгляда, может показаться, что для
предоставления пользовательскому приложению доступа к чипу ROM BIOS
посредством драйвера устройства для Linux и Windows необходимо применять разные подходы. Но это совсем не так, по причине уже упомянутой
единой системной архитектуры программного обеспечения. Основным назначением драйвера устройства является предоставление приложениям
пользовательского режима прямого доступа к адресному пространству
чипа ROM BIOS. Как показано в разд. 9.2, для Linux нет даже необходимости создавать драйвер устройства для реализации этой идеи, так как ядро
этой операционной системы предоставляет доступ к адресному пространству чипа ROM BIOS посредством виртуального файла в каталоге /dev/mem.
Общий способ для "экспортирования" адресного пространства чипа ROM
BIOS в пользовательское приложение заключается в следующем:
• Отображаем физический диапазон адресов чипа ROM BIOS (т. е. ад-
ресное пространство, примыкающее к пределу памяти в 4 Гбайт) на
виртуальное адресное пространство процесса 1, которому нужно предоставить доступ к содержимому чипа ROM BIOS.
• Создаем указатель на начало отображенного содержимого чипа ROM
BIOS в виртуальном адресном пространстве процесса.
• С помощью указателя, созданного на предыдущем шаге, манипулируем
содержимым чипа ROM BIOS непосредственно из пользовательского
приложения. Это означает, что содержимое чипа можно считывать при
1
В данном контексте процесс — это один из экземпляров приложения пользовательского режима, исполняющихся в настоящее время.
Глава 9. Обращение к BIOS из операционной системы
361
помощи оператора разыменования 2. Однако, так как чип BIOS является
памятью ROM, для выполнения операций записи, как и для стирания
чипа, необходимо выполнить определенные подготовительные действия.
2. Осуществляется аппаратно-зависимая часть операций, необходимых для
получения доступа к содержимому чипа ROM BIOS и манипулирования
этим содержимым. Для выполнения этого шага необходимо точно знать,
каким способом производится доступ к чипу BIOS на уровне аппаратных
средств. Эту информацию можно найти в технической документации на
чипсет и на чип ROM BIOS. Как правило, чтобы получить аппаратный
доступ к чипу BIOS, необходимо выполнить следующие действия:
• Регистры чипсета конфигурируются таким образом, чтобы разрешить
доступ к адресному пространству чипа ROM BIOS с правом чтения и
записи. В архитектуре х86 адресное пространство чипа ROM BIOS отображается в область общесистемного адресного пространства, примыкающую к верхней границе первых 4 Гбайт. Регистры чипсета, управляющие доступом к чипу ROM BIOS, обычно находятся в южном
мосте.
• Далее необходимо прочитать байты идентификаторов производителя
и чипа, расположенные по стандартным адресам. Эта информация
необходима, чтобы решить, каким методом пользоваться для обращения к содержимому чипа ROM BIOS. Обратите внимание, что чипы
ROM BIOS разных производителей имеют индивидуальные наборы команд для доступа к их содержимому. Некоторые команды приведены к
общему стандарту ассоциацией JEDEC 3 (http://jedec.org/).
• Двоичный код записывается в чип и считывается из него согласно спецификации производителя чипа.
Только что описанный способ представляет технику доступа к содержимому
чипа ROM BIOS и манипулирования этим содержимым из операционной системы. В последующих разделах рассматривается практическая реализация
принципов доступа к чипу BIOS из конкретных операционных систем.
2
Операция разыменования (indirection operator) — унарная операция, операндом которой является указатель, а значением — указываемый объект.
3
Joint Electronic Device Engineering Council — Объединенный инженерный совет по
электронным устройствам.
362
Часть IV. Внесение изменений в код BIOS
9.2. Доступ к содержимому BIOS
материнской платы из Linux
В разд. 9.1 мы ознакомились с общими принципами получения прямого доступа к чипу ROM BIOS из операционной системы. Для подтверждения этой
концепции рассмотрим, как выполнить поставленную задачу в Linux{ XE
"Linux" }. Эксперимент я проводил на устаревшей материнской плате Iwill
VD133{ XE "Iwill VD133" }, выпущенной в 2000 году. Я выбрал данную плату по двум причинам. Во-первых, я хотел показать, что поставленная задача
осуществима даже с устаревшими материнскими платами. Во-вторых, так как
эта материнская плата морально устарела, бесплатную документацию 4 на ее
чипсет
можно
без
труда
найти
в Интернете. Техническая документация на чипсет, а также на соответствующий чип ROM BIOS необходима для реализации доступа к содержимому BIOS
и манипулирования им. Технические характеристики системы, на которой я
проводил эксперимент, следующие:
Материнская плата Iwill VD133 с северным мостом VIA 693A и южным
мостом VIA 596B. Первоначальная BIOS датируется 28 июля 2000 года.
Чип BIOS — флэш-ROM Winbond{ XE "Winbond" } W49F002U.
Операционная система — Linux Slackware 9.1{ XE "Linux Slackware 9.1" },
версия ядра 2.4.24. Обратите внимание, что при инсталляции необходимо
установить и исходный код ядра. Исходный код требуется для перекомпиляции программного обеспечения, предназначенного для прямого доступа
к содержимому чипа ROM BIOS.
В дальнейшем я буду называть эту систему целевой.
Чтобы выполнить нашу задачу, нам также потребуется следующая документация:
Техническая документация на чипсет, в особенности — на его южный
мост. В материнских платах архитектуры х86 южный мост управляет доступом к чипу BIOS. В данном случае, нам нужна техническая документация на южный мост VIA 596B. Ее можно скачать бесплатно по адресу
http://www.megaupload.com/?d=FF297JQD.
Так как каждый чип ROM BIOS имеет свой собственный набор команд
(см. разд. 9.1), нам будет необходима техническая документация на
наш чип ROM BIOS. В данном случае, это техническая документация
4
Компании Intel и AMD обычно предоставляют спецификации технических характеристик для скачивания сразу же после выпуска чипсета на рынок. Компании VIA,
Nvidia, SiS и многие другие производители чипсетов этого не делают.
Глава 9. Обращение к BIOS из операционной системы
363
на чип ROM Winbond W49F002U. Ее можно скачать по адресу
http://www.winbond.com/e-winbondhtm/partner/_Memory_F_PF.htm.
Кроме того, потребуется и утилита, с помощью которой можно будет осуществлять прямой доступ к чипу ROM BIOS. Я предпочитаю создавать такие
утилиты сам, так как это позволяет мне реализовать все возможности управления системой, требующиеся для решения конкретной задачи, не дожидаясь,
пока кто-то создаст необходимый мне инструмент. К счастью, для решения
рассматриваемой задачи уже имеется готовая утилита для прошивки 5 BIOS из
Linux от разработчиков проекта Freebios (http://sourceforge.net/
cvs/?group_id=3206). Называется она flash_n_burn{ XE "flash_n_burn:для
Linux" }. Исходный код утилиты можно скачать по адресу
http://freebios.cvs.sourceforge.net/freebios/freebios/
util/flash_and_burn/. Плохо то, что эта утилита не является стандартным
компонентом дистрибутива Freebios{ XE "Freebios" }. С помощью этого
инструмента можно сделать дамп двоичного файла BIOS из чипа ROM BIOS
и прошить его обратно в чип из Linux. Я рекомендую вам добавить эту утилиту, которую можно приспособить для выполнения ваших конкретных задач, в
ваш набор инструментов.
9.2.1. Знакомство с утилитой flash_n_burn
Начнем
наше
знакомство с утилитой flash_n_burn{ XE "утилита
с рассмотрения процедур компиляции ее исходного кода.
Скопируйте исходный код в каталог ~/Project/freebios_flash_n_burn.
Компиляция производится с помощью утилиты make, результаты работы которой показаны в листинге 9.1. Вывод информации о результатах процесса
компиляции можно подавить, запустив компиляцию с помощью команды
make clean вместо просто make из каталога, в котором находится исходный
код.
flash_n_burn" }
Листинг 9.1. Компилирование утилиты flash_n_burn
pinczakko@opunaga:~/Project/freebios_flash_n_burn> make
gcc -O2 -g -Wall -Werror
-c -o flash_rom.o flash_rom.c
gcc -O2 -g -Wall -Werror
-c -o jedec.o jedec.c
5
Под "прошивкой" BIOS имеется в виду запись содержимого двоичного файла в чип
ROM BIOS. Английский глагол для этой операции будет "flash", сама операция называется "flashing", а утилита для прошики — "flasher". Для более ранних чипов ROM
(не флэш) применялось слово "burn" и его производные "bruning" и "burner". Термин
"burn" и его производные также применяются в отношении чипов флэш-ROM.
364
Часть IV. Внесение изменений в код BIOS
gcc -O2 -g -Wall -Werror
-c -o sst28sf040.o sst28sf040.c
gcc -O2 -g -Wall -Werror
-c -o am29f040b.o am29f040b.c
gcc -O2 -g -Wall -Werror
-c -o sst39sf020.o sst39sf020.c
gcc -O2 -g -Wall -Werror
-c -o m29f400bt.o m29f400bt.c
gcc -O2 -g -Wall -Werror
-c -o w49f002u.o w49f002u.c
gcc -O2 -g -Wall -Werror
-c -o 82802ab.o 82802ab.c
gcc -O2 -g -Wall -Werror
-c -o msys_doc.o msys_doc.c
gcc -O2 -g -Wall -Werror -o flash_rom flash_rom.c jedec.o
sst28sf040.o am29f040b.o mx29f002.c sst39sf020.o m29f400bt.o
w49f002u.o 82802ab.o msys_doc.o -lpci
gcc -O2 -g -Wall -Werror -o flash_on flash_on.c
pinczakko@opunaga:~/Project/freebios_flash_n_burn>
Результатом работы команды make будут два исполняемых файла — flash_on
и flash_rom (листинг 9.2). Для ясности, я оставил только эти два файла в листинге содержимого каталога (листинг 9.2).
Листинг 9.2. Исполняемые файлы утилиты flash_n_burn
pinczakko@opunaga:~/Project/freebios_flash_n_burn> ls -l
...
-rwxr-xr-x
1 pinczakko users
25041 Aug
5 11:49 flash_on*
-rwxr-xr-x
1 pinczakko users
133028 Aug
5 11:49 flash_rom*
...
Вообще говоря, в файле flash_on нет необходимости, так как его функциональность включена в файл flash_rom. Назначение файла flash_on — активировать доступ к чипу ROM BIOS через южный мост чипсета SiS. Эта
функциональность была впоследствии интегрирована в файл flash_rom, и,
таким образом, файл flash_on стал ненужным. Поэтому я рассматриваю
только применение утилиты flash_rom. Утилита запускается на исполнение
обычным способом — для этого достаточно ввести в терминале ее название
и указать необходимые параметры, как показано в листинге 9.3. Если введены
неправильные параметры, утилита flash_rom сообщает об этом и предоставляет информацию по ее использованию, включая правильное указание необходимых параметров (см. листинг 9.3).
Листинг 9.3. Использование утилиты flash_rom
pinczakko@opunaga:~/Project/A-List_Publishing/freebios_flash_n_burn>
./flash_rom --help
Глава 9. Обращение к BIOS из операционной системы
365
./flash_rom: invalid option -- ; ./flash_rom: invalid option -- -
Недействительная опция
usage: ./flash_rom [-rwv] [-c chipname][file]
; использование: ./flash_rom [-rwv] [-c имя_чипа][файл]
-r: read flash and save into file
; -r: считать содержимое чипа флэш и сохранить в файл
-w: write file into flash (default when file is specified)
; -w: записать файл в чип флэш (по умолчанию, когда указан файл)
-v: verify flash against file
; -v: сверить содержимое чипа флэш с содержимым файла
-c: probe only for specified flash chip
; -c: исследовать только указанный чип флэш
If no file is specified, then all that happens
is that flash info is dumped
; Если не указано файла, тогда выводится
; только информация о чипе флэш
Чтобы воспользоваться возможностями flash_rom в полном объеме, утилиту
следует запускать, зарегистрировавшись от имени пользователя root, так как в
противном случае, вы даже не сможете прочитать содержимое чипа ROM
BIOS. Причина этого состоит в том, что для запуска этой программы необходим определенный уровень привилегий ввода-вывода.
Снимем дамп двоичного файла BIOS целевой системы. Не забудьте, что для
успешного выполнения этой операции необходимо войти в систему под
учетной записью администратора (root). Результаты процесса снятия дампа
показаны в листинге 9.4. Обратите внимание, что для краткости в листинге 9.4 показана урезанная часть дампа, содержащая только информацию, необходимую для понимания происходящего.
Листинг 9.4. Считывание двоичного файла BIOS из чипа ROM BIOS
в файл в Linux
root@opunaga:/home/pinczakko/Project/freebios_flash_n_burn#
./flash_rom -r dump.bin
Calibrating timer since microsleep sucks ... takes a second
// Калибрируем таймер, так как функция microsleep никуда не годится.
// Это займет всего лишь секунду.
Setting up microsecond timing loop
// Устанавливаем цикл замера микросекунды.
128M loops per second
// 128 миллионов циклов в секунду.
366
Часть IV. Внесение изменений в код BIOS
OK, calibrated, now do the deed
// Таймер откалиброван. Выполняем задание.
Enabling flash write on VT82C596B ... OK
// Разрешаем запись в VT82C596B. Разрешение успешно.
Trying Am29F040B, 512 KB
// Пробуем чип Am29F040B, 512 Кбайт
probe_29f040b: id1 0x25, id2 0xf2
Trying At29C040A, 512 KB
// Пробуем чип Am29F040C, 512 Кбайт
probe_jedec: id1 0xda, id2 0xb
Trying Mx29f002, 256 KB
// Пробуем чип Mx29f002, 256 Кбайт
probe_29f002: id1 218, id2 11
...
Trying W49F002U, 256 KB
// Пробуем чип W49F002U, 256 Кбайт
probe_49f002: id1 0xda, id2 0xb
flash chip manufacturer id = 0xda
// Идентификатор производителя чипа = 0xda
W49F002U found at physical address: 0xfffc0000
// Нашли чип W49F002U по физическому адресу - 0xfffc0000
Part is W49F002U
// Номер детали - W49F002U
Reading flash ... Done
// Считывание чипа флэш-ROM завершено
В первую очередь необходимо разобраться, что именно происходит во время
считывания содержимого чипа ROM BIOS в файл. Процесс начинается с конфигурирования регистров южного моста VIA 956B таким образом, чтобы
разрешить доступ к чипу ROM BIOS. Затем утилита выполняет проверку на
наличие чипа ROM BIOS из числа поддерживаемых ею. В данном случае, обнаружен чип Winbond{ XE "Winbond" } W49F002U, и его содержимое считано
и
сохранено
в файл dump.bin. Инструкции для выполнения именно этих действий были
указаны параметром — r при запуске утилиты flash_rom (см. листинг 9.3).
Файл, считанный из чипа ROM BIOS, сохраняется в двоичном формате, и для
его просмотра нужна специальная утилита Linux, называющаяся hexdump. Эта
утилита, соответствующая стандарту POSIX{ XE "POSIX" } (Portable
Operating System Interface — интерфейс переносимых операционных систем),
включена в боль-шинство дистрибутивов Linux. Формат команды для просмотра содержимого двоичного файла BIOS с помощью этой утилиты в тер-
Глава 9. Обращение к BIOS из операционной системы
минале
в листинге 9.5.
367
Linux
показан
Листинг 9.5. Просмотр сохраненного двоичного файла BIOS в Linux
root@opunaga:/home/pinczakko/Project/
freebios_flash_n_burn# hexdump -f fmt dump.bin | less
Вывод команды hexdump форматируется при помощи специального файла форматирования, fmt, который указывается как опция при вызове команды. Это —
обычный текстовый файл, содержимое которого показано в листинге 9.6.
Листинг 9.6. Содержимое файла форматирования fmt
"%06.6_ax
"
"
12/1 "%02X "
" "%_p "
"\n"
Если у вас возникают затруднения с пониманием листинга 9.6, обратитесь
к объяснению листинга 7.11 в разд. 7.3.4. Содержимое обоих файлов одинаково. Результат выполнения команды hexdump, заданной в листинге 9.5, показан в листинге 9.7.
Листинг 9.7. Содержимое файла dump.bin
Адрес
Шестнадцатеричные значения
Значения ASCII
000000
25 F2 2D 6C 68 35 2D 85 3A 00 00 C0
% . - l h 5 - . : . . .
00000c
57 00 00 00 00 00 41 20 01 0C 61 77
W . . . . . A
000018
61 72 64 65 78 74 2E 72 6F 6D DB 74
a r d e x t . r o m . t
000024
20 00 00 2C F8 8E FB DF DD 23 49 DB
. . , . . . . . # I .
00 00 00 00 00 00 00 00 00 00 00 00
. . . . . . . . . . . .
03ffe4
00 00 00 00 32 41 36 4C 47 49 33 43
. . . . 2 A 6 L G I 3 C
03fff0
EA 5B E0 00 F0 2A 4D 52 42 2A 02 00
. [ . . . * M R B * . .
03fffc
00 00 FF FF
. . . .
. . a w
......
03ff90
*
Шестнадцатеричный дамп файла dump.bin, показанный в листинге 9.7, показывает лишь часть информации настоящего дампа, выводимого в терминале
Linux, а именно — первый сжатый модуль двоичного файла BIOS в конце
области кода блока начальной загрузки.
Download