Создание загрузочного образа операционной системы
В этой статье:
Создание образа операционной системы — многоэтапная процедура, которая зависит от оборудования и конфигурации целевой системы.
В этой главе рассматриваются этапы создания образа ОС и его передачи на целевую систему посредством загрузочного диска или дискеты, загрузки по сети, записи в микросхему EPROM или на устройство флеш-памяти. Мы также познакомимся с примерами интеграции различных драйверов и менеджеров ресурсов в целевые системы.
В ЗОСРВ «Нейтрино» термин "образ" имеет несколько значений:
Тип образа | Описание | Утилита для создания |
---|---|---|
Образ ОС | Загрузочная или не загрузочная структура, в которой хранятся файлы | mkifs |
Образ файловой системы флеш-памяти | Структура, которая формирует файловую систему флеш-памяти для чтения, чтения/записи или чтения/записи/освобождения | mkefs |
Образ встраиваемой транзакционной файловой системы | Двоичный файл образа, который содержит встраиваемую транзакционную файловую систему в виде последовательности транзакций | mketfs |
После создания исполняемых файлов (программ), которые предназначены для встраиваемой системы, необходимо помещать их в место, доступное для загрузки. Образ ОС представляет собой файл, в котором находятся операционная система, программы и их данные; фактически в образе хранится компактная файловая система с каталогами и файлами.
Существуют загрузочные и не загрузочные образы. Загрузочный образ содержит код запуска, который принимает управление от начального загрузчика (см. главу Модификация начальных загрузчиков этой книги). Как правило, небольшая встраиваемая система включает в себя один (загрузочный) образ ОС.
Не загрузочный образ обычно используется в качестве отдельной файловой системы с дополнительными файлами, которые зависят от конфигурации целевой системы (позже мы рассмотрим их подробнее). Как правило, не загрузочный образ не включает в себя ОС, файл запуска и т.д.
Как было сказано ранее, образ ОС представляет собой файловую систему. Фактически он содержит структуру каталогов, в которой для модуля procnto указаны имена и местоположения файлов, а также сами файлы. В процессе выполнения встраиваемой системы образ доступен как обычная файловая система для чтения:
# cd /proc/boot # ls .script ping cat data1 pidin ksh ls ftp procnto devc-ser8250-XXX # # # cat data1 Это файл данных с именем data1, который находится в образе. Таким способом удобно связывать файлы данных с программами.
В этом примере демонстрируются два аспекта использования образа ОС в качестве файловой системы. Когда мы ввели команду ls, операционная система загрузила утилиту ls из файловой системы образа (путевое имя /proc/boot/ls
). Затем, когда мы ввели команду cat, операционная система также загрузила утилиту cat из файловой системы образа и открыла файл data1
.
Теперь рассмотрим включение файлов в образ.
Для создания образа ОС используется утилита mkifs, которая получает информацию из двух основных источников: командной строки и файла построения загрузочного образа.
Рассмотрим элементарный файл построения загрузочного образа, с помощью которого был сгенерирован показанный выше образ ОС:
# ls, ping и командный интерпретатор.# Этот файл называется shell.bld[virtual=armle,srec] .bootstrap = {startup-XXXPATH=/proc/boot procnto -vv}[+script] .script = {procmgr_symlink ../../proc/boot/libc.so.3 /usr/lib/ldqnx.so.2devc-ser8250-XXX -F -e -c14745600 -b115200 0xc8000000 ^2,15 &reopendisplay_msg Serial Driver Started}[type=link] /dev/console=/dev/ser1[type=link] /tmp=/dev/shmemlibc.so.2libc.so[data=copy]devc-ser8250-XXXkshlscatdata1pingftppidin
![]() | В файле построения загрузочного образа символ # обозначает комментарий; все следующее за ним содержимое строки игнорируется. Между командой сборки и символом комментария должен находиться как минимум один пробел. |
Этот файл построения загрузочного образа включает в себя следующие разделы:
Несмотря на то, что три указанных выше раздела файл построения загрузочного образа выглядят по-разному, они фактически представляют собой списки файлов.
Файл построения загрузочного образа имеет следующую структуру:
необязательные_атрибуты имя файла необязательное_содержимое
Например, строка
[virtual=armle,srec] .bootstrap = {
содержит атрибут [virtual=armle,srec] и имя файла .bootstrap
. Компонент необязательное_содержимое называется встроенным файлом; утилита mkifs считывает его содержимое не из инструментальной системы, а непосредственно из файла построения загрузочного образа (между фигурными скобками). Содержимое встроенного файла нельзя размещать в одной строке с открывающей и закрывающей фигурными скобками.
Рассмотрим указанные компоненты подробнее.
В первом разделе загружаемого файла (который начинается с атрибута [virtual=armle,srec]) задано создание системы виртуальной адресации. Затем следует тип процессора; значение armle соответствует процессору ARM с прямым порядком байт. После запятой указано имя загружаемого файла — srec.
В последней части строки задан встроенный файл (посредством открывающей фигурной скобки) с именем .bootstrap
и следующим содержимым:
startup-XXXPATH=/proc/boot procnto -vv
![]() | Если в файле начальной загрузки задана переменная окружения PATH, модуль procnto присваивает значение конфигурационной строке _CS_PATH . Аналогично, если задана переменная окружения LD_LIBRARY_PATH, procnto присваивает значение конфигурационной строке _CS_LIBPATH . Эти переменные окружения не передаются сценарию, но их можно задавать в самом сценарии. |
Для подключения дополнительных модулей к procnto применяется атрибут [module=...]. Например, чтобы подключить менеджер адаптивного партиционирования, необходимо изменить строку procnto следующим образом:
[module=aps] PATH=/proc/boot procnto -vv
Имя файла IPL может быть любым, однако ссылки на файлы IPL и сценария не указываются в файле построения загрузочного образа, поскольку эти файлы включаются в образ автоматически благодаря атрибуту [virtual] или [physical].
Атрибут virtual (и его аналог physical) задает целевой процессор (в этом примере armle) и загрузочный файл (srec) — небольшой фрагмент кода между IPL и модулем startup-*. Целевой процессор указывается в переменной окружения $PROCESSOR и используется при раскрытии путевых имен. Если целевой процессор не задан, по умолчанию указывается процессор инструментальной системы. Например, строка
[virtual=bios] .bootstrap = {...
задает целевой процессор ARM, если разработка осуществляется в системе с процессором ARM.
В обоих примерах выполняется поиск файла $PROCESSOR/sys/bios.boot
(расширение .boot
автоматически добавляется утилитой mkifs), из которого извлекаются параметры конфигурации.
Можно сжимать конечный образ с помощью атрибута +compress. Сжатый образ автоматически распаковывается перед запуском. Чтобы сжать образ, необходимо изменить первую строку:
[virtual=armle,srec +compress] .bootstrap = {
Второй раздел файла построения загрузочного образа начинается с атрибута [+script], который указывает утилите mkifs, что в нем содержится файл сценария — последовательность команд, выполняемая модулем procnto по окончании его настройки.
![]() | Сценарии сборки внешне похожи на командно-строковые сценарии, но:
Для выполнения команды необходимо, чтобы был доступен соответствующий исполняемый файл. Этот файл можно помещать в образ или загружать из файловой системы, которая запускается перед выполнением команды. Второй способ уменьшает размер образа. |
В приведенном примере используется встроенный файл сценария (на это также указывает открывающая фигурная скобка) с именем .script
и следующим содержимым:
procmgr_symlink ../../proc/boot/libc.so.3 /usr/lib/ldqnx.so.2devc-ser8250-XXX -F -e -c14745600 -b115200 0xc8000000 ^2,15 &reopendisplay_msg Serial Driver Started
В начале этого сценария создается символьная ссылка с именем /usr/lib/ldqnx.so.2
на файл ../../proc/boot/libc.so.3
.
![]() | Для некоторых целевых систем необходимо создавать ссылку с именем ldqnx.so.3 вместо ldqnx.so.2 . |
Затем сценарий запускает вымышленный драйвер последовательного порта devc-ser8250-XXX на скорости передачи 115200 бит/с с указанным адресом физической памяти в режиме редактирования и с отключенным аппаратным контролем потока. Далее команда reopen перенаправляет стандартные потоки ввода, вывода и ошибок, а последняя строка отображает сообщение.
Как было отмечено ранее, с помощью файла IPL можно задавать конфигурационные строки _CS_PATH
и _CS_LIBPATH
, присваивая значения переменным окружения PATH, LD_LIBRARY_PATH и др., если их используют программы, которые запускаются из сценария.
![]() | Сценарии запуска позволяют выполнять программы в приоритетном и фоновом режимах; чтобы запустить программу в фоновом режиме, необходимо указать в командной строке символ & так же, как в командном интерпретаторе. Если программа, которая запущена в приоритетном режиме, не завершает работу, последующая часть сценария не выполняется, что может нарушить дальнейшее функционирование системы. |
Процессы, которые запускаются из сценария, можно привязывать к процессорам с помощью модификатора [CPU=].
Он используется так же, как любой другой модификатор. Если он указан перед командой, он задает процессор, на котором будет выполняться соответствующий процесс; если он находится в строке без команды, на заданном процессоре будут выполняться все последующие процессы. Процессор указывается с помощью индекса, начиная с 0:
[cpu=0] имя_программы
Значение * разрешает выполнение процессов на всех процессорах:
[cpu=*] имя_программы
Если процессор с указанным индексом отсутствует на этапе загрузки, отображается предупреждение, а команда выполняется без привязки к процессору.
![]() | Из-за ограничений структур данных, с которыми работает загрузочный образ, указанный синтаксис позволяет привязывать процессы только к одному процессору; маски выполнения не поддерживаются. Для запуска процесса с маской выполнения (runmask) используется утилита on. |
Файл сценария на целевой системе отличается от файла сценария в файле построения загрузочного образа. Утилита mkifs анализирует команды сценария, указанные в файле построения загрузочного образа, и сохраняет их на целевой системе в обработанном виде, а не в исходном формате ASCII. Это делается для того, чтобы минимизировать трудоемкость обработки файла сценария на этапе выполнения и устранить необходимость интеграции полнофункционального командного интерпретатора в менеджер процессов.
Вернемся к нашему примеру и рассмотрим список файлов, который находится между строками [type=link] /dev/console=/dev/ser1 и pidin.
Как было сказано ранее, в этом списке указаны файлы и библиотеки, которые включаются в состав образа. Содержимое образа зависит от функций встраиваемой системы; рекомендации по выбору файлов см. в статье Примеры компоновки загрузочных образов.
В рассмотренном выше примере мы указали список файлов образа в расчете на то, что утилита mkifs каким-то образом найдет их. Здесь нет никакого волшебства — mkifs просто считывает значение переменной окружения MKIFS_PATH, в которой перечислены каталоги для поиска указанных файлов. Если переменная MKIFS_PATH не существует, поиск осуществляется в следующих каталогах в указанном порядке:
${KPDA_TARGET}/${PROCESSOR}/sbin
${KPDA_TARGET}/${PROCESSOR}/usr/sbin
${KPDA_TARGET}/${PROCESSOR}/boot/sys
${KPDA_TARGET}/${PROCESSOR}/bin
${KPDA_TARGET}/${PROCESSOR}/usr/bin
${KPDA_TARGET}/${PROCESSOR}/lib
${KPDA_TARGET}/${PROCESSOR}/lib/dll
${KPDA_TARGET}/${PROCESSOR}/usr/lib
${KPDA_TARGET}/${PROCESSOR}/usr/photon/bin
Компонент $PROCESSOR заменяется именем процессора (например, arm).
Поскольку в нашем примере ни одно имя файла не начинается с символа /
, мы указываем утилите mkifs искать файлы в каталогах инструментальной системы, которые перечислены в переменной окружения MKIFS_PATH, как описано выше. Независимо от расположения на инструментальной системе все файлы помещаются в каталог /proc/boot
целевой системы (с несколькими нюансами, к которым мы вернемся позже).
В нашем примере менеджеру devc-con-hid присваивается путевое имя /proc/boot/devc-con-hid
на целевой системе, при этом он находится в каталоге ${KPDA_TARGET}/armle/sbin/devc-con-hid
инструментальной системы.
Существует несколько способов включения в образ файлов из каталогов, которые не указаны в переменной окружения MKIFS_PATH:
/
)
С помощью атрибута [search=новый_путь] мы указываем утилите mkifs выполнять поиск в каталогах, которые не заданы в переменной окружения MKIFS_PATH. Компонент новый_путь представляет собой список путевых имен, разделенных двоеточиями, и может включать в себя значения переменных окружения. Например, чтобы включить в поиск каталог /mystuff
в дополнение к каталогам, которые указаны в переменной MKIFS_PATH, следует указать атрибут
[search=${MKIFS_PATH}:/mystuff]
Предположим, что один из файлов, которые используются в примере, имеет путевое имя /release/data1
на инструментальной системе. Если в файле построения загрузочного образа просто указать путевое имя /release/data1
, утилита mkifs включает соответствующий файл в образ, но на целевой системе ему присваивается путевое имя /proc/boot/data1
вместо /release/data1
.
Иногда это то, что вам нужно, но в некоторых случаях требуется указывать точное путевое имя файла на целевой системе (т.е. переопределять префикс /proc/boot
). Например, файл /etc/passwd
на инструментальной системе, который указан в файле построения загрузочного образа как /etc/passwd
, на целевой системе получает путевое имя /proc/boot/passwd
, которое, скорее всего, не подходит для него. Чтобы решить эту проблему, можно включить в файл построения загрузочного образа строку
/etc/passwd = /etc/passwd
Она указывает утилите mkifs сохранить файл /etc/passwd
инструментальной системы как etc/passwd
на целевой системе.
Возможна и другая ситуация — например, требуется поместить в целевую встраиваемую систему файл паролей, который имеет путевое имя /home/username/embedded/passwd
на инструментальной системе. В этом случае следует включить в файл построения загрузочного образа строку
/etc/passwd = /home/username/embedded/passwd
Поскольку файл data1
имеет небольшой размер, можно поместить его содержимое непосредственно в файл построения загрузочного образа и не создавать файл data1
на инструментальной системе. Файл data1
, встроенный в файл построения загрузочного образа, имеет следующий вид:
data1 = {Это файл данных с именем data1, который находится вобразе. Таким способом удобно связывать файлы данных спрограммами.}
Следует обратить внимание на несколько аспектов. Если встроенный файл содержит закрывающую фигурную скобку (}
), необходимо экранировать ее обратной косой чертой (\
). По этой причине также необходимо экранировать обратные косые черты. Чтобы создать встроенный файл с содержимым
Здесь присутствуют символы {, } и \.
необходимо включить в файл построения загрузочного образа следующий текст (если встроенному файлу присваивается имя data2
):
data2 = {Здесь присутствуют символы {, \} и \\.}
Поскольку мы не помещаем пробелы в начало файла data2
, мы также не помещаем их в определение встроенного файла. Следующее содержимое выглядит "лучше", но является некорректным:
# Это определение некорректно, поскольку оно начинается с пробелов!data2 = {Здесь присутствуют символы {, \} и \\.}
Если имя файла содержит "необычные" символы, оно заключается в двойные кавычки. Например, чтобы создать файл с именем I "think" so
(с пробелами и кавычками), необходимо указать его следующим образом:
"I \"think\" so" = ...
Тем не менее, не рекомендуется присваивать файлам такие имена, поскольку их неудобно вводить в командной строке (помимо того, что они выглядят неестественно).
В рассмотренном выше примере файлы имеют одинакового владельца, идентификатор группы и права доступа на инструментальной и целевой системах. Идентификаторы пользователя и группы встроенных файлов (data1
и data2
) наследуются от пользователя, который запускает утилиту mkifs. Права доступа к файлам определяются параметром umask пользователя.
Чтобы явно назначать указанные параметры конкретным файлам, перед их именами в файле построения загрузочного образа указывается атрибут
[uid=0 gid=0 perms=0666] file1[uid=5 gid=1 perms=a+xr] file2
В этих строках файлу file1
назначается владелец root
(с идентификатором пользователя 0
), идентификатор группы 0
, а также предоставляются права чтения и записи всем пользователям (восьмеричный код 666
). Файлу file2
назначается владелец с идентификатором пользователя 5
, идентификатор группы 1
, а всем пользователям предоставляются права чтения и выполнения (a+xr
).
![]() | При выполнении в ОС Windows утилита mkifs не имеет доступа к правам выполнения (x ), задания идентификатора пользователя (setuid) и группы (setgid) файла. Чтобы явно задавать эти права, следует использовать атрибут perms. Для корректного назначения владельцев также может потребоваться использование атрибутов uid и gid. Чтобы узнать, необходимо ли устанавливать права setuid и setgid при использовании утилиты, см. ее описание. |
Можно объединять несколько атрибутов, помещая их в одни квадратные скобки. Следующая строка некорректна:
# некорректное указание атрибутов[uid=0] [gid=0] [perms=0666] file1
Чтобы применить эти атрибуты к набору файлов, удобнее всего указать атрибуты uid, gid и perms в одной строке, а затем задать список файлов:
[uid=5 gid=1 perms=0666]file1file2file3file4
Этот фрагмент эквивалентен следующим строкам:
[uid=5 gid=1 perms=0666] file1[uid=5 gid=1 perms=0666] file2[uid=5 gid=1 perms=0666] file3[uid=5 gid=1 perms=0666] file4
Если необходимо включить в образ большое количество файлов (например, из определенного каталога), достаточно указать имя этого каталога вместо списка файлов. Например, чтобы поместить в образ все файлы каталога /release_1.0
, можно добавить в файл построения загрузочного образа строку
/release_1.0
Все файлы каталога /release_1.0
будут помещены в каталог /proc/boot
целевой системы. Если каталог /release_1.0
содержит подкаталоги, они также копируются в каталог /proc/boot
целевой системы вместе со всеми файлами, которые находятся в них.
Такой режим копирования не всегда приводит к требуемому результату. Если необходимо поместить файлы каталога /release_1.0
в каталог /
, следует добавить строку
/=/release_1.0
Она указывает mkifs перeнести содержимое каталога /release_1.0
в каталог /
. Чтобы поместить все содержимое каталога /release_1.0
в каталог /product целевой системы, следует добавить в файл построения загрузочного образа строку
/product=/release_1.0
Чтобы сгенерировать образ из файла построения загрузочного образа, можно выполнить команду
mkifs shell.bld shell.ifs
Эта команда указывает утилите mkifs создать файл образа shell.ifs
из файла построения загрузочного образа с именем shell.bld
.
Утилита mkifs также принимает командно-строковые параметры. Поскольку они обрабатываются раньше, чем файл построения загрузочного образа, с их помощью можно передавать утилите mkifs строки, которые предшествуют файлу построения загрузочного образа. Этот метод используется в Makefile для внесения изменений в общий файл сборки по умолчанию.
Следующая команда устанавливает начальный адрес образа равным 64 Кбайт (0x10000 в шестнадцатеричном коде):
mkifs -l "[image=0x10000]" файл_сборки файл_образа
Дополнительную информацию см. в описании утилиты mkifs.
Для просмотра содержимого образа используется утилита dumpifs. Пример результатов ее работы:
Offset Size Name 0 100 Startup-header flags1=0x1 flags2=0 paddr_bias=0x80000000 100 a008 startup.* a108 5c Image-header mountpoint=/ a164 264 Image-directory ---- ---- Root-dirent ---- 12 usr/lib/ldqnx.so.2 -> /proc/boot/libc.so ---- 9 dev/console -> /dev/ser1 a3c8 80 proc/boot/.script b000 4a00 proc/boot/procnto 55000 5900 proc/boot/libc.so.3 ---- 9 proc/boot/libc.so -> libc.so.3 ae000 7340 proc/boot/devc-ser8250 b6000 4050 proc/boot/esh bb000 4a80 proc/boot/ls c0000 14f0 proc/boot/data1 d5000 22a0 proc/boot/data2 Checksums: image=0x94b0d37b startup=0xa3aeaf2
Чем больше параметров -v указано при вызове, тем подробнее отображаемая информация. Дополнительную информацию см. в описании утилиты dumpifs.
В состав ЗОСРВ «Нейтрино» входит POSIX-совместимый драйвер файловой системы флеш-памяти, который можно использовать, если на целевом устройстве необходимо записывать данные в файлы и работать с накопителями на флеш-памяти. Драйверы файловых систем флеш-памяти описаны в главе Файловые системы руководства по cистемной архитектуре. В разделе "Модификация файловой системы флеш-памяти" описано создание драйвера файловой системы флеш-памяти для конкретной встраиваемой системы.
Существуют два подхода к созданию файловой системы флеш-памяти:
В этом разделе рассматривается создание образа файловой системы флеш-памяти с помощью утилиты mkefs и файла построения загрузочного образа. Процесс передачи образа файловой системы флеш-памяти на целевую систему см. в параграфе "Встраивание образа" далее, а об использовании драйверов файловых систем флеш-памяти в их описании.
Утилита mkefs принимает файл построения загрузочного образа и генерирует файл образа файловой системы флеш-памяти. Файл построения загрузочного образа содержит список атрибутов и файлов, которые помещаются в файловую систему.
Файлы построения загрузочного образа для утилит mkifs и mkefs имеют схожий синтаксис, однако mkefs поддерживает другой набор атрибутов, в том числе:
Полное описание синтаксиса файла построения загрузочного образа и атрибутов утилиты см. в описании утилиты mkefs.
Ниже приведен простой пример файла построения загрузочного образа:
[block_size=128k spare_blocks=1 filter=deflate]/home/username/products/sp1/callp/imagedir
Атрибуты указывают, что размер блока устройств флеш-памяти составляет 128 Кбайт, резервируется один свободный блок и все файлы обрабатываются утилитой deflate, которая сжимает файлы. В файле построения загрузочного образа указан единственный каталог. Как и при использовании утилиты mkifs, все его файлы и подкаталоги включаются в генерируемый образ. Утилита mkefs также поддерживает большинство методов работы с именами файлов, которые используются в mkifs.
Следует задавать значение атрибута block_size с учетом размера физического блока устройства флеш-памяти, который указан в его технических характеристиках, и конфигурации флеш-накопителя (чередования).
Примеры:
Конфигурация | Значение атрибута block_size |
---|---|
8-разрядный интерфейс флеш-памяти и 8-разрядное устройство с размером блока 64 Кбайт | 64 Кбайт |
16-разрядный интерфейс флеш-памяти и два чередующихся 8-разрядных устройства с размером блока 64 Кбайт | 128 Кбайт |
16-разрядный интерфейс флеш-памяти и 16-разрядное устройство с размером блока 64 Кбайт | 64 Кбайт |
32-разрядный интерфейс флеш-памяти и четыре чередующихся 8-разрядных устройства с размером блока 64 Кбайт | 256 Кбайт |
Обратите внимание, что не требуется указывать никакие параметры устройств флеш-памяти системы, кроме размера блока.
Атрибут spare_blocks определяет количество резервируемых свободных блоков. Значение 0 соответствует файловой системе флеш-памяти для чтения/записи или однократной записи, а значение больше 0 — файловой системе для чтения/записи/освобождения.
По умолчанию этот атрибут равен 1, однако необходимое количество свободных блоков зависит от объема записываемых данных. Следует указывать нечетное количество свободных блоков (как правило, 1 или 3).
Файловая система не использует свободный блок до тех пор, пока не возникает необходимость выполнить операцию освобождения. Данные освобождаемого блока помещаются в непрерывную область свободного блока, освобождаемый блок удаляется и становится свободным, а прежний свободный блок занимает место освобожденного.
![]() | Если значение атрибута spare_blocks равно 0 (свободные блоки не резервируются), драйвер файловой системы не освобождает флеш-память, поскольку отсутствует место для размещения новой копии данных. В определенный момент это приведет к исчерпанию свободной памяти. |
Файловая система флеш-памяти ЗОСРВ «Нейтрино» включает в себя механизм сжатия файлов, который позволяет пользователям экономить на флеш-накопителях. Для быстрого и эффективного сжатия/распаковки в файловой системе используются широко распространенные алгоритмы.
Утилита deflate сжимает файлы во флеш-памяти и вызывается из командного интерпретатора или атрибута filter утилиты mkefs. Алгоритм deflate обеспечивает исключительно эффективное сжатие файлов данных и программ без потерь.
Драйверы файловых систем флеш-памяти используют утилиту inflator для распаковки файлов, сжатых с помощью утилиты deflate, прозрачно для пользователя; это означает, что для доступа к сжатым файлам во флеш-памяти не требуется распаковывать их.
![]() | Сжатие файлов обеспечивает значительную экономию памяти, однако замедляет доступ к сжатым файлам. Замедление доступа к сжатым данным и увеличение нагрузки на процессор необходимо учитывать при проектировании системы. Мы наблюдали многократное ускорение загрузки систем с ограниченным объемом флеш-памяти при использовании сжатия. |
Можно сжимать файлы:
Первый метод является ресурсоемким. Можно использовать утилиту deflate в качестве фильтра mkefs для сжатия файлов, которые помещаются в файловую систему флеш-памяти. Например, следующий файл построения загрузочного образа позволяет сгенерировать файловую систему размером 16 Мбайт со сжатием:
[block_size=128K spare_blocks=1 min_size=16m filter=deflate]/bin/
Также можно сжимать файлы заранее, непосредственно используя утилиту deflate. Если утилита mkefs обнаруживает сигнатуру сжатия в файле, который она помещает в файловую систему, она определяет, что файл уже сжат, и не сжимает его повторно. В любом случае утилита mkefs помещает данные в файловую систему флеш-памяти и устанавливает в метаданных бит, который указывает файловой системе, что необходимо распаковать файл.
Второй метод заключается в сжатии файлов с помощью утилиты deflate и их непосредственном сохранении в файловой системе флеш-памяти. В следующем примере утилита deflate запускается из командной строки, сжимает файл ls, который находится в файловой системе образа, и помещает его в файловую систему флеш-памяти:
$ deflate /proc/boot/ls -o /fs0p0/ls
Файловая система флеш-памяти никогда не сжимает файлы; она обнаруживает сжатые файлы на накопителе и распаковывает их с помощью утилиты inflator по мере доступа к ним. Уровень абстракции утилиты inflator обеспечивает эффективность распаковки и соблюдение стандарта POSIX. Файлы, которые находятся на флеш-накопителе, включают в себя специальные заголовки сжатых данных, которые обеспечивают высокую скорость поиска.
Этот уровень устроен несложно — специальные функции ввода/вывода обрабатывают три основных обращения к сжатым файлам:
Неочевидный аспект сжатия заключается в том, что сжатый файл имеет два размера:
Например, не имеет практического смысла определять использование диска с помощью утилиты du для каталога флеш-памяти, если хранящиеся в нем данные распаковываются на лету. Полученный результат не характеризует объем данных на накопителе.
Утилита inflator обеспечивает удобный доступ к сжатому файлу путем добавления точки и трех символов тильды (.~~~
) к имени несжатого файла. При обращении к файлу в таком формате его содержимое считывается в не распакованном виде. Например, чтобы узнать виртуальный размер сжатого файла, введите команду
ls -l my_file
а чтобы узнать размер хранения — команду
ls -l my_file.~~~
При чтении файла с расширением .~~~
его содержимое не распаковывается, как при чтении обычного файла. Существуют правила выполнения операций над сжатыми файлами. Считывать файлы и определять их размер несложно; проблемы начинаются при записи в эти файлы:
Исключением из вышеописанных правил является усечение файла. Если сжатый файл открывается с флагом O_TRUNC
из обычного виртуального пространства имен, он переходит в такое же состояние, как если бы он был создан в этом же пространстве имен. В этом режиме доступны все функции POSIX без ограничений, которые применяются по отношению к сжатым файлам.
Следует отметить, что функция ftruncate() не обрабатывает сжатые файлы, но обрабатывает обычные файлы.
После создания загрузочного образа ЗОСРВ «Нейтрино» на инструментальной системе необходимо перенести его на целевую систему и загрузить ее. Различные способы загрузки ОС на целевой системе описаны в статье Руководство по разработке начального загрузчика (IPL).
Созданный образ (загрузочный образ ОС или образ файловой системы флеш-памяти) необходимо записать на флеш-накопитель.
В зависимости от требований к целевой системе и ее конфигурации разработчику может потребоваться включить в нее:
Загрузочный образ и файловая система флеш-памяти могут размещаться как на одном, так и на разных накопителях флеш-памяти. Чтобы поместить загрузочный образ и файловую систему флеш-памяти на одно устройство, можно объединить их в один файл с помощью утилиты mkimage.
На начальном этапе разработки может возникать необходимость записывать образ во флеш-память с помощью программатора или утилиты для скачивания образов. Если позже на целевой системе запускается файловая система флеш-памяти, можно записывать файл образа в неразмеченный раздел флеш-накопителя.
Если программатор работает с образами недвоичного формата, можно преобразовывать формат образа с помощью утилиты mkrec.
Утилита mkimage компонует несколько файлов образов в один. Она обнаруживает загрузочный образ и помещает его в начало результирующего образа. Некоторые разработчики используют программатор флеш-памяти вместо утилиты mkimage и записывают образы по отдельности с необходимым смещением.
Например, команда
mkimage nto.ifs fs.ifs > flash.ifs
объединяет файлы образов nto.ifs
и fs.ifs
в файл образа flash.ifs
. Чтобы более гибко управлять объединением образов, можно использовать другие утилиты:
Утилита mkrec преобразует двоичный файл образа в записи Motorola S или шестнадцатеричные записи Intel, которые можно передавать программатору флеш-памяти или EPROM.
Например, команда
mkrec -s 256k flash.ifs > flash.srec
преобразует файл образа flash.ifs
в файл с S-записями flash.srec
. Параметр -s 256k указывает, что размер устройства EPROM составляет 256 Кбайт.
Если необходимо скачивать несколько файлов образов, можно сначала объединять их в общий файл с помощью утилиты mkimage. Кроме того, некоторые программаторы флеш-памяти/EPROM позволяют скачивать несколько файлов образов с различными смещениями.
Существует множество способов передачи образа во флеш память:
Подробное описание передачи образа вышеперечисленными методами, кроме последнего, выходит за рамки настоящего документа. Библиотека файловых систем флеш-памяти поддерживает использование неструктурированных точек монтирования, с помощью которых удобно передавать образы во флеш-память. Можно читать и записывать неструктурированные разделы так же, как обычные файлы, но при использовании неструктурированной точки монтирования необходимо:
Для примера воспользуемся драйвером devf-ram, который имитирует флеш-накопитель в оперативной памяти. Чтобы запустить его, войдите в систему как пользователь root и введите команду
# devf-ram &
Можно удалять раздел с помощью команды flashctl, при этом не обязательно обладать привилегиями пользователя root
. Пример:
$ flashctl -p /dev/fs0 -e
![]() | Будьте внимательны при использовании этой команды, поскольку на флеш-накопителе может находиться важное содержимое (например, BIOS). |
Обработка обычного флеш-накопителя командой flashctl занимает некоторое время (около 1 секунды на каждый удаляемый блок). Эта команда стирает двоичный массив флеш-памяти /dev/fs0
. После стирания его байты должны содержать значения 0xff
; это можно проверить с помощью команды hd:
$ hd /dev/fs0 0000000: ff ff ff ff ff ff ff ff ff ff ff .......... *
Для примера создадим прототип IPL:
$ echo Hello, World! > ipl $ mkrec -s 128k -f full ipl > ipl_image Reset jmps to 0x1FFE0 (jmp 0xFFED) ROM offset is 0x1FFE0
Разумеется, этот прототип не выполняет реальную работу, а только демонстрирует использование файловой системы флеш-памяти. В любом случае, присутствие такого IPL в оперативной памяти не приносит большой пользы. Создадим прототип файловой системы флеш-памяти (^D
означает Ctrl - D
):
$ mkefs -v - flash_image [block_size=128k spare_blocks=1 min_size=384k] /bin/ls /bin/cat ^D writing directory entry -> writing file entry -> ls ** writing file entry -> cat * Filesystem size = 384K block size = 128K 1 spare block(s)
В отличие от IPL, эта файловая система действительно работает. Теперь можно передать образы разделов флеш-памяти на флеш-накопитель с помощью любой утилиты обмена файлами (например, cp или ftp). Мы создали образ IPL, выровненный по границе стирания блока, посредством утилиты mkrec, и образ флеш-памяти посредством утилиты mkefs. Мы можем объединить эти образы утилитой cat и поместить их во флеш-память:
$ cat ipl_image flash_image > /dev/fs0
Если еще раз проверить неструктурированную точку монтирования утилитой hd, можно убедиться, что флеш-память содержит образы разделов вместо единичных битов (0xFF
). Чтобы воспользоваться разделом файловой системы флеш-памяти, необходимо перезапустить драйвер, чтобы он обнаружил новые разделы, и смонтировать их. Перезапуск драйвера devf-ram выглядит следующим образом:
$ slay devf-ram $ devf-ram &
Теперь в системе существует точка монтирования /fs0p1
, которая фактически представляет собой каталог с файлами образа, созданного утилитой mkefs. Точка монтирования /fs0p0
не существует, поскольку файловая система флеш-памяти не распознает загрузочный образ. Тем не менее, доступ к загрузочному образу обеспечивается неструктурированной точкой монтирования /dev/fs0p0
. Над точкой монтирования /dev/fs0p0
можно выполнять те же операции, что и над точкой монтирования /dev/fs0
. Несмотря на наличие доступа к точке монтирования /dev/fs0p1
не следует выполнять запись в этот раздел, когда приложения используют файловую систему флеш-памяти /fs0p1
. Выполните команду
$ /fs0p1/ls /fs0p1
Эта команда запускает утилиту ls из файловой системы флеш-памяти и отображает ее содержимое. Действия, которые были описаны в этом разделе, наглядно демонстрируют начальный этап адаптации файловой системы флеш-памяти для конкретной платформы. Они представляют собой первые шаги на пути к использованию полнофункциональной файловой системы на целевом устройстве.
В этом разделе мы рассмотрим несколько методов конфигурирования ЗОСРВ «Нейтрино». Более подробные примеры см. в статье Примеры компоновки загрузочных образов.
Разумеется, конкретные действия зависят от особенностей разрабатываемой встраиваемой системы. Настоящий раздел содержит общие принципы конфигурирования и помогает разработчику определять, какие программы следует использовать в конкретных условиях и какие совместно используемые библиотеки требуются для работы исполняемых файлов.
В самом общем виде процесс конфигурирования состоит из следующих этапов:
Одним из первых действий в файле построения загрузочного образа является запуск драйвера, которому перенаправляются стандартные потоки ввода, вывода и ошибок. Все последующие драйверы и приложения получают возможность отображать информационные и диагностические сообщения при запуске, а разработчик — читать их на каком-либо устройстве.
Как правило, запускается драйвер консоли или последовательного порта. Драйвер консоли используется при разработке в "настольной" среде, а драйвер последовательного порта — во "встраиваемой".
Если в глубоко встраиваемой системе не предусмотрены устройства для вывода информации, можно пропустить этот этап. Если для вывода информации используется другое устройство, необходимо найти и запустить соответствующий специализированный драйвер. При отсутствии драйвера устройства данные передаются драйверу отладочного вывода, который задан в коде запуска.
В этом примере запускается драйвер стандартной консоли в режиме редактирования (параметр -e, который используется по умолчанию). Чтобы настроить устройство вывода, можно включить его драйвер в сценарий запуска (файл [+script]). Например, команды
devc-con-hid -e & reopen /dev/con1
запускают драйвер последовательного порта 8250 в режиме редактирования (параметр -e) с начальной скоростью передачи 115200 бит/с (параметр -b):
devc-ser8250 -e -b115200 & reopen /dev/ser1
В обоих случаях команда reopen перенаправляет стандартные потоки ввода, вывода и ошибок по указанному путевому имени (в вышеуказанных примерах — /dev/con1
или /dev/ser1
). Это перенаправление действует до выполнения другой команды reopen.
![]() | В приведенном примере reopen является внутренней командой утилиты mkifs, а не встроенной командой командного интерпретатора. |
На следующем этапе запускаются драйверы и/или файловые системы, которые обеспечивают разработчику доступ к оборудованию. Ранее установленный драйвер консоли или последовательного порта также входит в их число, однако отличается от них тем, что обычно запускается первым.
ЗОСРВ «Нейтрино» поддерживает драйверы/файловые системы различных типов:
Обычно первым устанавливается драйвер устройства, на котором расположены исполняемые файлы. Поскольку образ должен быть максимально компактным, в него не следует помещать все исполняемые файлы и совместно используемые библиотеки; обычно они хранятся на другом носителе — накопителе на флеш-памяти, жестком диске или в сетевой файловой системе. В этом случае для доступа к программам необходимо запускать соответствующий драйвер. Как только программы на накопителе становятся доступными, можно запускать с него другие драйверы.
Альтернативный подход, который часто применяется в глубоко встраиваемых системах, заключается в том, что все исполняемые файлы и совместно используемые библиотеки помещаются непосредственно в образ. Это целесообразно, если в системе отсутствует второе хранилище или требуется прямой доступ к файлам без использования драйвера.
Рассмотрим этапы запуска драйверов дисков, флеш-памяти и сетевых плат. У этих драйверов имеется общая черта — каждый из них представляет собой процесс, который загружает один или несколько файлов .so в соответствии с командно-строковыми параметрами или при автоматическом определении конфигурации системы.
![]() | Поскольку многие из рассматриваемых здесь драйверов используют файлы .so (не только собственные, но и стандартные — например, библиотеку языка C), эти файлы должны быть доступны к моменту запуска драйвера. Очевидно, что файл .so нельзя размещать на накопителе, драйвер которого требуется запустить! Рекомендуется включать указанные файлы .so в образ системы. |
Сначала необходимо определить контроллер дискового интерфейса. ЗОСРВ «Нейтрино» поддерживает множество интерфейсов, в том числе различные контроллеры SCSI и EIDE. Подробнее о поддерживаемых контроллерах интерфейсов см. в описаниях драйверов devb-*.
В файле построения загрузочного образа достаточно запустить драйвер (например, devb-ahci), который динамически загружает необходимые модули (в следующем порядке):
Документацию к файлам .so
библиотеки общих методов доступа см. в описаниях драйверов cam-*. На текущий момент ЗОСРВ «Нейтрино» поддерживает устройства чтения/записи компакт-дисков ( cam-cdrom.so), жесткие диски ( cam-disk.so) и оптические диски ( cam-optical.so).
Модуль io-blk.so отвечает за операции с конкретными блоками диска и поддерживает кеширование.
Модули fs-* работают со структурой конкретной файловой системы. На текущий момент поддерживаются следующие файловые системы:
Файловая система | Модуль |
---|---|
MS-DOS | fs-dos.so |
Linux | fs-ext2.so |
Macintosh HFS и HFS Plus | fs-mac.so |
Windows NT | fs-nt.so |
QNX 4 | fs-qnx4.so |
Файловая система с защитой от сбоев питания | fs-qnx6.so |
ISO-9660 CD-ROM, Universal Disk Format (UDF) | fs-udf.so |
Чтобы запустить файловую систему флеш-памяти, необходимо выбрать подходящий драйвер для флеш-накопителя целевого устройства. Подробнее о поддерживаемых драйверах флеш-памяти см. в описаниях драйверов devf-*.
![]() | Драйвер devf-generic представляет собой универсальный драйвер, который совместим с большинством накопителей флеш-памяти. |
Поскольку драйверы файловых систем флеш-памяти не используют специальные файлы .so
для поддержки конкретных накопителей, единственным обязательным модулем является стандартная библиотека C ( libc.so).
Поскольку драйверы файловых систем флеш-памяти специально написаны для конкретных целевых систем, они обычно запускаются без командно-строковых параметров и обнаруживают в системе накопитель, для которого они предназначены.
Сетевые службы запускаются командой io-pkt-*, которая загружает необходимые файлы .so
.
![]() | Для динамического запуска и останова сетевых драйверов в командной строке можно использовать команды mount и umount. Пример:
mount -T io-pkt devn-ne2000.so Дополнительную информацию см. в описании утилиты mount. |
Командно-строковые параметры io-pkt-* запускают два уровня файлов .so
:
.so
драйвера .so
протокола Параметр -d позволяет задавать драйвер конкретной платы. Например, параметр -d ne2000 указывает менеджеру io-pkt-* загрузить модуль devn-ne2000.so для доступа к сетевой плате, которая совместима с NE-2000. После параметра -d можно задавать дополнительные командно-строковые параметры (например, вектор прерываний платы).
Параметр -p позволяет выбирать драйвер конкретного протокола. Как и при использовании параметра -d, после параметра -p указываются командно-строковые параметры драйвера, такие как IP-адрес конкретного интерфейса.
Дополнительную информацию о сетевых службах см. в описании компонентов devn-* и io-pkt-*.
ЗОСРВ «Нейтрино» поддерживает два типа сетевых файловых систем:
![]() | Протокол CIFS не соответствует стандарту POSIX. |
Несмотря на то, что файловая система NFS используется преимущественно в ОС семейства UNIX, существуют ее версии для Windows.
Для запуска приложений не требуется специальная подготовка системы. Как правило, приложения запускаются в сценарии после запуска всех драйверов. Чтобы дождаться доступности и готовности конкретного драйвера, можно воспользоваться в сценарии командой waitfor.
Например, если для запуска приложения peelmaster необходимо, чтобы драйвер driver-spud был готов к работе, можно задать в сценарии следующую типовую последовательность команд:
driver-spud & waitfor /dev/spud peelmaster
С помощью символа &
драйвер driver-spud запускается в фоновом режиме и перед началом работы регистрирует путевое имя /dev/spud
. Команда waitfor периодически проверяет наличие этого путевого имени с помощью функции stat() и приостанавливает выполнение сценария до тех пор, пока не появляется имя /dev/spud
или не истекает интервал ожидания. Предполагается, что после появления этого имени в пространстве путевых имен драйвер готов принимать запросы. В этот момент команда waitfor разблокируется и сценарий запускает следующую программу в списке — peelmaster.
Без команды waitfor программа peelmaster запускается немедленно после драйвера, и отсутствие путевого имени /dev/spud
может привести к ее аварийному завершению.
При разработке встраиваемых систем с другими ОС часто возникает необходимость использования аппаратного отладчика — физического устройства, которое подключается к оборудованию целевой системы через интерфейс JTAG (Joint Test Action Group). Аппаратный отладчик требуется при разработке драйверов и некоторых пользовательских приложений, поскольку они находятся в одном адресном пространстве с ядром. Сбой в драйвере или приложении может выводить из строя ядро и систему в целом. Это усложняет применение программных отладчиков, поскольку они работают в функционирующей системе.
Отладка целевых систем под управлением ЗОСРВ «Нейтрино» выполняется иначе, поскольку ее архитектура отличается от архитектуры других встраиваемых ОСРВ:
Как правило, в ЗОСРВ «Нейтрино»
Другими словами, если встраиваемая система разрабатывается с помощью одного из пакетов поддержки плат, аппаратный отладчик с интерфейсом JTAG почти не используется.
![]() | Тем не менее, при наличии проблем с аппаратной составляющей, могут возникать условия для потери программной управляемости. В этом случае аппаратный отладчик становится безальтернативным как на этапе диагностики, так и при отладке. |
В состав ЗОСРВ «Нейтрино» входит агент отладки pdebug, который облегчает отладку системных драйверов и пользовательских приложений. Программа pdebug выполняется на целевой системе и взаимодействует с отладчиком инструментальной системы через Ethernet-соединение.
Основное ограничение применения агента pdebug заключается в том, что ядро операционной системы должно уже выполняться на целевом устройстве. Другими словами, pdebug можно использовать только при условии, что IPL и код запуска успешно запустили ядро.
Тем не менее, поскольку IPL и модуль startup-* выполняются в физическом режиме, можно отлаживать их с помощью традиционных аппаратных отладчиков. В этом состоит основная функция JTAG-отладчика на этапе разработки программного обеспечения ЗОСРВ «Нейтрино». Для отладки BSP (IPL и модуль startup-*) используется аппаратный отладчик, а для отладки драйверов и приложений после запуска ядра — агент pdebug. С помощью аппаратного отладчика также можно изучать содержимое регистров и памяти во время работы ядра и приложений, если известны соответствующие физические адреса.
Такие аппаратные отладчики как Lauterbach или AMC оснащены встроенными функциями поддержки ЗОСРВ «Нейтрино» (OS awareness) и с их помощью можно отлаживать приложения через интерфейс JTAG. Эти отладчики интерпретируют информацию ядра и позволяют изучать данные приложений, выполняя преобразования между виртуальными и физическими адресами.
Можно отлаживать IPL и модуль startup-* с помощью аппаратных отладчиков без какой-либо дополнительной информации. Тем не менее, такая отладка выполняется только на уровне ассемблера, и ассемблерные символы (например, имена подпрограмм) скрыты от разработчика. Для полноценной отладки на уровне исходного кода необходимо предоставлять аппаратному отладчику символьную информацию и код программ на языке C.
В этом разделе рассматривается процедура генерации символов для отладки на уровне исходного кода с помощью аппаратного отладчика. Указанная процедура относится к пакету поддержки платы PPC (PowerPC) с IPL и модулем startup-* для базовой аппаратной платформы Motorola Sandpoint MPC750.
Предполагается, что разработчик находится в среде разработки с привилегиями пользователя root
.
Чтобы сгенерировать символьную информацию для IPL, необходимо перекомпилировать его и библиотеку libipl. Выполните следующие действия:
sandpoint.lnk
![]() | Синхронизируйте исходный код, IPL во флеш-памяти и его отладочные символы. |
Чтобы выполнить сборку библиотеки libipl с включением в нее отладочной информации, введите команды
cd bsp_working_dir/src/hardware/ipl/lib/ppc/a.be make clean make CCOPTS=-g cp libipl.a bsp/sandpoint/install/ppcbe/lib make install
В результате выполнения этих команд в библиотеку libipl PowerPC (libipl.a
) включается отладочная информация DWARF, а сама библиотека копируется в установочный каталог. В настройках BSP указано, что поиск этой библиотеки начинается с установочного каталога. Необязательная команда
make install
копирует файл libipl.a
в каталог /ppcbe/usr/lib
.
BSP работает с файлами формата SREC, однако для генерации отладочной и символьной информации, которая загружается в аппаратного отладчика, необходимо генерировать файлы формата ELF.
Измените формат вывода на ELF в файле sandpoint.lnk
:
cd bsp/sandpoint/src/hardware/ipl/boards/sandpoint
Отредактируйте файл sandpoint.lnk
, изменив его первые строки
TARGET(elf32-powerpc) OUTPUT_FORMAT(srec) ENTRY(entry_vec)
на
TARGET(elf32-powerpc) OUTPUT_FORMAT(elf32-powerpc) ENTRY(entry_vec)
Пересоберите IPL, включив в него генерацию символьной и отладочной информации в формате ELF:
cd bsp/sandpoint/src/hardware/ipl/boards cd sandpoint/ppc/be make clean make CCOPTS=-g
Теперь файл ipl-sandpoint имеет формат ELF и включает в себя отладочные символы библиотеки libipl и IPL.
![]() | Чтобы пересобрать BSP, необходимо заново указать формат вывода SREC в файле sandpoint.lnk . Также важно, чтобы IPL, который находится во флеш-памяти, соответствовал сгенерированой отладочной информации; при изменении исходного кода IPL необходимо пересобирать BSP, записывать обновленного IPL во флеш-память и пересобирать символьную и отладочную информацию начального загрузчика. |
Для просмотра информации ELF можно использовать утилиту objdump. Например, чтобы просмотреть символьную информацию, которая содержится в файле ipl-sandpoint, следует ввести команду
objdump -t ipl-sandpoint | less
Теперь можно импортировать файл ipl-sandpoint с символьной информацией в аппаратного отладчика. Аппаратному отладчику также необходимы исходные коды, которые размещены в следующих каталогах:
bsp/sandpoint/src/hardware/ipl/boards/sandpoint
bsp/src/hardware/ipl/lib
bsp/src/hardware/ipl/lib/ppc
Чтобы сгенерировать символьную информацию для модуля startup-*, необходимо перекомпилировать ее и libstartup. Выполните следующие действия:
Чтобы выполнить сборку libstartup с включением в нее отладочной информации, введите следующие команды:
cd bsp/src/hardware/startup/lib/ppc/a.be make clean make CCOPTS=-g cp libstartup.a bsp/sandpoint/install/ppcbe/lib make install
В результате выполнения вышеуказанных команд в libstartup PowerPC (libstartup.a
) включается отладочная информация DWARF, а сама библиотека копируется в установочный каталог. В настройках BSP указано, что поиск этой библиотеки начинается с установочного каталога. Необязательная команда
make install
копирует файл libstartup.a
в каталог /ppcbe/usr/lib
.
Чтобы собрать модуль startup-* с отладочной информацией, выполните следующие команды:
cd bsp/sandpoint/src/hardware/startup/boards/ cd sandpoint/ppc/be make clean make CCOPTS=-g make install
Вышеуказанные команды генерируют файл startup-sandpoint с символьной и отладочной информацией. Вместо параметра отладки -g можно указать параметр -gstabs+. Команда
make install
является обязательной и копирует файл startup-sandpoint в установочный каталог bsp/sandpoint/install/ppcbe/boot/sys
.
![]() | Невозможно получить отладочные символы, загрузив ELF-файл startup-sandpoint в аппаратный отладчик, поскольку утилита mkifs добавляет к адресам, которые указаны в символах, смещение, заданное в файле построения загрузочного образа. |
Назначьте атрибут +keeplinked модулю startup-* в файле построения загрузочного образа:
cd bsp/sandpoint/images
Измените строку модуля startup-* в файле построения загрузочного образа следующим образом:
[image=0x10000][virtual=ppcbe,binary +compress] .bootstrap = {[+keeplinked] startup-sandpoint -vvv -D8250PATH=/proc/boot procnto-600 -vv}
Параметр +keeplinked указывает утилите mkifs сгенерировать символьный файл с отладочной информацией, которая находится в файловой системе образа с заданным смещением.
Чтобы пересобрать образ для генерации символьного файла, выполните команды
cd bsp/sandpoint/images make clean
Если используется один из штатных файлов .build
:
make all
В противном случае:
mkifs -v -r ../install myfile.build image
Вышеуказанные файлы создают символьный файл startup-sandpoint.sym
. Для просмотра информации ELF можно использовать утилиту objdump.
Чтобы отобразить символьную информацию, которая содержится в файле startup-sandpoint.sym
, следует ввести команду
objdump -t startup-sandpoint.sym | less
Теперь можно импортировать файл startup-sandpoint.sym
с символьной информацией для отладки модуля startup-* в аппаратном отладчике. Аппаратному отладчику также необходим исходный код, который размещен в следующих каталогах:
bsp/src/hardware/startup/lib
bsp/src/hardware/startup/lib/public/ppc
bsp/src/hardware/startup/lib/public/sys
bsp/src/hardware/startup/lib/ppc
bsp/sandpoint/src/hardware/startup/boards/sandpoint
Предыдущий раздел: перейти