Операционная система ЗОСРВ «Нейтрино» > Руководство разработчика > Основные принципы системной разработки > Запуск системы, быстрая активация устройств > Построение встраиваемых систем > Статьи руководства > Создание загрузочного образа



Создание загрузочного образа

Создание загрузочного образа операционной системы

В этой статье:

Типы образов
Что такое образ ОС
Образ ОС как файловая система
Настройка образа ОС
Простой файл построения загрузочного образа
Встроенные файлы
Файл начальной загрузки (.bootstrap)
Сжатие образа
Файл сценария
Атрибуты ограниченной многопроцессорной обработки
Файл сценария на целевой системе
Списки файлов образа
Включение файлов из различных каталогов
Изменение пути поиска
Явное указание путевого имени
Создание встроенного файла
Указание владельца файла и прав доступа к нему
Включение множества файлов в образ
Генерация образа
Отображение списка содержимого образа
Создание образа файловой системы флеш-памяти
Использование утилиты mkefs
Файл построения загрузочного образа для утилиты mkefs
Размер блока
Свободные блоки
Сжатие файлов
Уровень абстракции
Два размера
Правила сжатия
Исключение
Встраивание образа
Объединение файлов образов с помощью утилиты mkimage
Преобразование образов с помощью утилиты mkrec
Передача образа во флеш-память
Конфигурирование системы
Активизация устройства вывода
Простой пример для настольной системы
Запуск драйверов/файловых систем
Драйверы устройств хранения
Файловые системы флеш-памяти
Сетевые драйверы
Сетевые файловые системы
Запуск приложений
Отладка встраиваемой системы
Агент отладки программ pdebug
Аппаратные JTAG-отладчики
Генерация отладочных символов для IPL и startup
Генерация отладочных символов для IPL
Генерация отладочных символов для startup

Создание образа операционной системы — многоэтапная процедура, которая зависит от оборудования и конфигурации целевой системы.

В этой главе рассматриваются этапы создания образа ОС и его передачи на целевую систему посредством загрузочного диска или дискеты, загрузки по сети, записи в микросхему 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, которая получает информацию из двух основных источников: командной строки и файла построения загрузочного образа.


Note: Дополнительную информацию см. в описании утилиты mkifs.

Простой файл построения загрузочного образа

Рассмотрим элементарный файл построения загрузочного образа, с помощью которого был сгенерирован показанный выше образ ОС:

# ls, ping и командный интерпретатор.
# Этот файл называется shell.bld
[virtual=armle,srec] .bootstrap = {
startup-XXX
PATH=/proc/boot procnto -vv
}
[+script] .script = {
procmgr_symlink ../../proc/boot/libc.so.3 /usr/lib/ldqnx.so.2
devc-ser8250-XXX -F -e -c14745600 -b115200 0xc8000000 ^2,15 &
reopen
display_msg Serial Driver Started
}
[type=link] /dev/console=/dev/ser1
[type=link] /tmp=/dev/shmem
libc.so.2
libc.so
[data=copy]
devc-ser8250-XXX
ksh
ls
cat
data1
ping
ftp
pidin


Note: В файле построения загрузочного образа символ # обозначает комментарий; все следующее за ним содержимое строки игнорируется. Между командой сборки и символом комментария должен находиться как минимум один пробел.

Этот файл построения загрузочного образа включает в себя следующие разделы:

Встроенные файлы

Несмотря на то, что три указанных выше раздела файл построения загрузочного образа выглядят по-разному, они фактически представляют собой списки файлов.

Файл построения загрузочного образа имеет следующую структуру:

необязательные_атрибуты имя файла необязательное_содержимое

Например, строка

[virtual=armle,srec] .bootstrap = {

содержит атрибут [virtual=armle,srec] и имя файла .bootstrap. Компонент необязательное_содержимое называется встроенным файлом; утилита mkifs считывает его содержимое не из инструментальной системы, а непосредственно из файла построения загрузочного образа (между фигурными скобками). Содержимое встроенного файла нельзя размещать в одной строке с открывающей и закрывающей фигурными скобками.

Рассмотрим указанные компоненты подробнее.

Файл начальной загрузки (.bootstrap)

В первом разделе загружаемого файла (который начинается с атрибута [virtual=armle,srec]) задано создание системы виртуальной адресации. Затем следует тип процессора; значение armle соответствует процессору ARM с прямым порядком байт. После запятой указано имя загружаемого файла — srec.

В последней части строки задан встроенный файл (посредством открывающей фигурной скобки) с именем .bootstrap и следующим содержимым:

startup-XXX
PATH=/proc/boot procnto -vv


Note: Если в файле начальной загрузки задана переменная окружения 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 по окончании его настройки.


Note: Сценарии сборки внешне похожи на командно-строковые сценарии, но:
  • перед командами можно указывать специальные модификаторы
  • некоторые команды являются встроенными
  • утилита mkifs обрабатывает содержимое файла сценария перед тем, как включать его в образ

Для выполнения команды необходимо, чтобы был доступен соответствующий исполняемый файл. Этот файл можно помещать в образ или загружать из файловой системы, которая запускается перед выполнением команды. Второй способ уменьшает размер образа.


В приведенном примере используется встроенный файл сценария (на это также указывает открывающая фигурная скобка) с именем .script и следующим содержимым:

procmgr_symlink ../../proc/boot/libc.so.3 /usr/lib/ldqnx.so.2
devc-ser8250-XXX -F -e -c14745600 -b115200 0xc8000000 ^2,15 &
reopen
display_msg Serial Driver Started

В начале этого сценария создается символьная ссылка с именем /usr/lib/ldqnx.so.2 на файл ../../proc/boot/libc.so.3.


Note: Для некоторых целевых систем необходимо создавать ссылку с именем ldqnx.so.3 вместо ldqnx.so.2.

Затем сценарий запускает вымышленный драйвер последовательного порта devc-ser8250-XXX на скорости передачи 115200 бит/с с указанным адресом физической памяти в режиме редактирования и с отключенным аппаратным контролем потока. Далее команда reopen перенаправляет стандартные потоки ввода, вывода и ошибок, а последняя строка отображает сообщение.

Как было отмечено ранее, с помощью файла IPL можно задавать конфигурационные строки _CS_PATH и _CS_LIBPATH, присваивая значения переменным окружения PATH, LD_LIBRARY_PATH и др., если их используют программы, которые запускаются из сценария.


Note: Сценарии запуска позволяют выполнять программы в приоритетном и фоновом режимах; чтобы запустить программу в фоновом режиме, необходимо указать в командной строке символ & так же, как в командном интерпретаторе. Если программа, которая запущена в приоритетном режиме, не завершает работу, последующая часть сценария не выполняется, что может нарушить дальнейшее функционирование системы.

Атрибуты ограниченной многопроцессорной обработки

Процессы, которые запускаются из сценария, можно привязывать к процессорам с помощью модификатора [CPU=].

Он используется так же, как любой другой модификатор. Если он указан перед командой, он задает процессор, на котором будет выполняться соответствующий процесс; если он находится в строке без команды, на заданном процессоре будут выполняться все последующие процессы. Процессор указывается с помощью индекса, начиная с 0:

[cpu=0] имя_программы

Значение * разрешает выполнение процессов на всех процессорах:

[cpu=*] имя_программы

Если процессор с указанным индексом отсутствует на этапе загрузки, отображается предупреждение, а команда выполняется без привязки к процессору.


Note: Из-за ограничений структур данных, с которыми работает загрузочный образ, указанный синтаксис позволяет привязывать процессы только к одному процессору; маски выполнения не поддерживаются. Для запуска процесса с маской выполнения (runmask) используется утилита on.

Файл сценария на целевой системе

Файл сценария на целевой системе отличается от файла сценария в файле построения загрузочного образа. Утилита mkifs анализирует команды сценария, указанные в файле построения загрузочного образа, и сохраняет их на целевой системе в обработанном виде, а не в исходном формате ASCII. Это делается для того, чтобы минимизировать трудоемкость обработки файла сценария на этапе выполнения и устранить необходимость интеграции полнофункционального командного интерпретатора в менеджер процессов.

Списки файлов образа

Вернемся к нашему примеру и рассмотрим список файлов, который находится между строками [type=link] /dev/console=/dev/ser1 и pidin.

Как было сказано ранее, в этом списке указаны файлы и библиотеки, которые включаются в состав образа. Содержимое образа зависит от функций встраиваемой системы; рекомендации по выбору файлов см. в статье Примеры компоновки загрузочных образов.

Включение файлов из различных каталогов

В рассмотренном выше примере мы указали список файлов образа в расчете на то, что утилита mkifs каким-то образом найдет их. Здесь нет никакого волшебства — mkifs просто считывает значение переменной окружения MKIFS_PATH, в которой перечислены каталоги для поиска указанных файлов. Если переменная MKIFS_PATH не существует, поиск осуществляется в следующих каталогах в указанном порядке:

  1. текущий рабочий каталог, если имя файла содержит косую черту, но не начинается с нее.
  2. ${KPDA_TARGET}/${PROCESSOR}/sbin
  3. ${KPDA_TARGET}/${PROCESSOR}/usr/sbin
  4. ${KPDA_TARGET}/${PROCESSOR}/boot/sys
  5. ${KPDA_TARGET}/${PROCESSOR}/bin
  6. ${KPDA_TARGET}/${PROCESSOR}/usr/bin
  7. ${KPDA_TARGET}/${PROCESSOR}/lib
  8. ${KPDA_TARGET}/${PROCESSOR}/lib/dll
  9. ${KPDA_TARGET}/${PROCESSOR}/usr/lib
  10. ${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).


Note: При выполнении в ОС 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]
file1
file2
file3
file4

Этот фрагмент эквивалентен следующим строкам:

[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

Утилита mkefs принимает файл построения загрузочного образа и генерирует файл образа файловой системы флеш-памяти. Файл построения загрузочного образа содержит список атрибутов и файлов, которые помещаются в файловую систему.

Файл построения загрузочного образа для утилиты mkefs

Файлы построения загрузочного образа для утилит mkifs и mkefs имеют схожий синтаксис, однако mkefs поддерживает другой набор атрибутов, в том числе:

block_size=размер_блока
Задает размер блока на используемом устройстве флеш-памяти (по умолчанию 64 Кбайт). Мы рассмотрим аспекты чередования для флеш-устройств далее в этой главе.
max_size=макс_размер
Задает максимальный размер устройства флеш-памяти для проверки его переполнения (по умолчанию 4 Гбайт).
spare_blocks=количество_свободных_блоков
Задает количество свободных блоков, резервируемых для файловой системы флеш-памяти; см. параграф "Свободные блоки" далее в этой главе.
min_size=мин_размер
Задает минимальный размер файловой системы. Если размер сгенерированного образа меньше мин_размер, образ расширяется до минимального размера. Этот параметр не имеет значения по умолчанию (образ не расширяется).

Полное описание синтаксиса файла построения загрузочного образа и атрибутов утилиты см. в описании утилиты 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).

Файловая система не использует свободный блок до тех пор, пока не возникает необходимость выполнить операцию освобождения. Данные освобождаемого блока помещаются в непрерывную область свободного блока, освобождаемый блок удаляется и становится свободным, а прежний свободный блок занимает место освобожденного.


Note: Если значение атрибута spare_blocks равно 0 (свободные блоки не резервируются), драйвер файловой системы не освобождает флеш-память, поскольку отсутствует место для размещения новой копии данных. В определенный момент это приведет к исчерпанию свободной памяти.

Сжатие файлов

Файловая система флеш-памяти ЗОСРВ «Нейтрино» включает в себя механизм сжатия файлов, который позволяет пользователям экономить на флеш-накопителях. Для быстрого и эффективного сжатия/распаковки в файловой системе используются широко распространенные алгоритмы.

Утилита deflate сжимает файлы во флеш-памяти и вызывается из командного интерпретатора или атрибута filter утилиты mkefs. Алгоритм deflate обеспечивает исключительно эффективное сжатие файлов данных и программ без потерь.

Драйверы файловых систем флеш-памяти используют утилиту inflator для распаковки файлов, сжатых с помощью утилиты deflate, прозрачно для пользователя; это означает, что для доступа к сжатым файлам во флеш-памяти не требуется распаковывать их.


Note: Сжатие файлов обеспечивает значительную экономию памяти, однако замедляет доступ к сжатым файлам. Замедление доступа к сжатым данным и увеличение нагрузки на процессор необходимо учитывать при проектировании системы. Мы наблюдали многократное ускорение загрузки систем с ограниченным объемом флеш-памяти при использовании сжатия.

Можно сжимать файлы:

Первый метод является ресурсоемким. Можно использовать утилиту 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. Файлы, которые находятся на флеш-накопителе, включают в себя специальные заголовки сжатых данных, которые обеспечивают высокую скорость поиска.

Этот уровень устроен несложно — специальные функции ввода/вывода обрабатывают три основных обращения к сжатым файлам:

Два размера

Неочевидный аспект сжатия заключается в том, что сжатый файл имеет два размера:

Виртуальный размер
С точки зрения конечного пользователя — фактический размер распакованных данных, который возвращается функцией stat().
Размер хранения
Объем флеш-памяти, которую фактически занимает файл.

Например, не имеет практического смысла определять использование диска с помощью утилиты du для каталога флеш-памяти, если хранящиеся в нем данные распаковываются на лету. Полученный результат не характеризует объем данных на накопителе.

Утилита inflator обеспечивает удобный доступ к сжатому файлу путем добавления точки и трех символов тильды (.~~~) к имени несжатого файла. При обращении к файлу в таком формате его содержимое считывается в не распакованном виде. Например, чтобы узнать виртуальный размер сжатого файла, введите команду

ls -l my_file

а чтобы узнать размер хранения — команду

ls -l my_file.~~~

Правила сжатия

При чтении файла с расширением .~~~ его содержимое не распаковывается, как при чтении обычного файла. Существуют правила выполнения операций над сжатыми файлами. Считывать файлы и определять их размер несложно; проблемы начинаются при записи в эти файлы:

Исключение

Исключением из вышеописанных правил является усечение файла. Если сжатый файл открывается с флагом O_TRUNC из обычного виртуального пространства имен, он переходит в такое же состояние, как если бы он был создан в этом же пространстве имен. В этом режиме доступны все функции POSIX без ограничений, которые применяются по отношению к сжатым файлам.

Следует отметить, что функция ftruncate() не обрабатывает сжатые файлы, но обрабатывает обычные файлы.

Встраивание образа

После создания загрузочного образа ЗОСРВ «Нейтрино» на инструментальной системе необходимо перенести его на целевую систему и загрузить ее. Различные способы загрузки ОС на целевой системе описаны в статье Руководство по разработке начального загрузчика (IPL).

Созданный образ (загрузочный образ ОС или образ файловой системы флеш-памяти) необходимо записать на флеш-накопитель.

fs_create.png
Рисунок 1. Конфигурирование флеш-памяти встраиваемой системы

В зависимости от требований к целевой системе и ее конфигурации разработчику может потребоваться включить в нее:

Загрузочный образ и файловая система флеш-памяти могут размещаться как на одном, так и на разных накопителях флеш-памяти. Чтобы поместить загрузочный образ и файловую систему флеш-памяти на одно устройство, можно объединить их в один файл с помощью утилиты mkimage.

На начальном этапе разработки может возникать необходимость записывать образ во флеш-память с помощью программатора или утилиты для скачивания образов. Если позже на целевой системе запускается файловая система флеш-памяти, можно записывать файл образа в неразмеченный раздел флеш-накопителя.

Если программатор работает с образами недвоичного формата, можно преобразовывать формат образа с помощью утилиты mkrec.

Объединение файлов образов с помощью утилиты mkimage

Утилита mkimage компонует несколько файлов образов в один. Она обнаруживает загрузочный образ и помещает его в начало результирующего образа. Некоторые разработчики используют программатор флеш-памяти вместо утилиты mkimage и записывают образы по отдельности с необходимым смещением.

Например, команда

mkimage nto.ifs fs.ifs > flash.ifs

объединяет файлы образов nto.ifs и fs.ifs в файл образа flash.ifs. Чтобы более гибко управлять объединением образов, можно использовать другие утилиты:

Преобразование образов с помощью утилиты mkrec

Утилита 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


Note: Будьте внимательны при использовании этой команды, поскольку на флеш-накопителе может находиться важное содержимое (например, BIOS).

Обработка обычного флеш-накопителя командой flashctl занимает некоторое время (около 1 секунды на каждый удаляемый блок). Эта команда стирает двоичный массив флеш-памяти /dev/fs0. После стирания его байты должны содержать значения 0xff; это можно проверить с помощью команды hd:

$ hd /dev/fs0 0000000: ff ff ff ff ff ff ff ff ff ff ff .......... *


Note: Дополнительную информацию см. в описании утилиты flashctl.

Для примера создадим прототип 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 из файловой системы флеш-памяти и отображает ее содержимое. Действия, которые были описаны в этом разделе, наглядно демонстрируют начальный этап адаптации файловой системы флеш-памяти для конкретной платформы. Они представляют собой первые шаги на пути к использованию полнофункциональной файловой системы на целевом устройстве.

Конфигурирование системы

В этом разделе мы рассмотрим несколько методов конфигурирования ЗОСРВ «Нейтрино». Более подробные примеры см. в статье Примеры компоновки загрузочных образов.

Разумеется, конкретные действия зависят от особенностей разрабатываемой встраиваемой системы. Настоящий раздел содержит общие принципы конфигурирования и помогает разработчику определять, какие программы следует использовать в конкретных условиях и какие совместно используемые библиотеки требуются для работы исполняемых файлов.

В самом общем виде процесс конфигурирования состоит из следующих этапов:

  1. активизация устройства вывода
  2. запуск драйверов
  3. запуск приложений

Активизация устройства вывода

Одним из первых действий в файле построения загрузочного образа является запуск драйвера, которому перенаправляются стандартные потоки ввода, вывода и ошибок. Все последующие драйверы и приложения получают возможность отображать информационные и диагностические сообщения при запуске, а разработчик — читать их на каком-либо устройстве.

Как правило, запускается драйвер консоли или последовательного порта. Драйвер консоли используется при разработке в "настольной" среде, а драйвер последовательного порта — во "встраиваемой".

Если в глубоко встраиваемой системе не предусмотрены устройства для вывода информации, можно пропустить этот этап. Если для вывода информации используется другое устройство, необходимо найти и запустить соответствующий специализированный драйвер. При отсутствии драйвера устройства данные передаются драйверу отладочного вывода, который задан в коде запуска.

Простой пример для настольной системы

В этом примере запускается драйвер стандартной консоли в режиме редактирования (параметр -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.


Note: В приведенном примере reopen является внутренней командой утилиты mkifs, а не встроенной командой командного интерпретатора.

Запуск драйверов/файловых систем

На следующем этапе запускаются драйверы и/или файловые системы, которые обеспечивают разработчику доступ к оборудованию. Ранее установленный драйвер консоли или последовательного порта также входит в их число, однако отличается от них тем, что обычно запускается первым.

ЗОСРВ «Нейтрино» поддерживает драйверы/файловые системы различных типов:

Обычно первым устанавливается драйвер устройства, на котором расположены исполняемые файлы. Поскольку образ должен быть максимально компактным, в него не следует помещать все исполняемые файлы и совместно используемые библиотеки; обычно они хранятся на другом носителе — накопителе на флеш-памяти, жестком диске или в сетевой файловой системе. В этом случае для доступа к программам необходимо запускать соответствующий драйвер. Как только программы на накопителе становятся доступными, можно запускать с него другие драйверы.

Альтернативный подход, который часто применяется в глубоко встраиваемых системах, заключается в том, что все исполняемые файлы и совместно используемые библиотеки помещаются непосредственно в образ. Это целесообразно, если в системе отсутствует второе хранилище или требуется прямой доступ к файлам без использования драйвера.

Рассмотрим этапы запуска драйверов дисков, флеш-памяти и сетевых плат. У этих драйверов имеется общая черта — каждый из них представляет собой процесс, который загружает один или несколько файлов .so в соответствии с командно-строковыми параметрами или при автоматическом определении конфигурации системы.


Note: Поскольку многие из рассматриваемых здесь драйверов используют файлы .so (не только собственные, но и стандартные — например, библиотеку языка C), эти файлы должны быть доступны к моменту запуска драйвера. Очевидно, что файл .so нельзя размещать на накопителе, драйвер которого требуется запустить! Рекомендуется включать указанные файлы .so в образ системы.

Драйверы устройств хранения

Сначала необходимо определить контроллер дискового интерфейса. ЗОСРВ «Нейтрино» поддерживает множество интерфейсов, в том числе различные контроллеры SCSI и EIDE. Подробнее о поддерживаемых контроллерах интерфейсов см. в описаниях драйверов devb-*.

В файле построения загрузочного образа достаточно запустить драйвер (например, devb-ahci), который динамически загружает необходимые модули (в следующем порядке):

  1. libcam.so — библиотека общих методов доступа
  2. cam-*.so — модули общих методов доступа
  3. io-blk.so — модуль блочного ввода/вывода
  4. fs-*.so — модули файловых систем

Документацию к файлам .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-*.


Note: Драйвер devf-generic представляет собой универсальный драйвер, который совместим с большинством накопителей флеш-памяти.

Поскольку драйверы файловых систем флеш-памяти не используют специальные файлы .so для поддержки конкретных накопителей, единственным обязательным модулем является стандартная библиотека C ( libc.so).

Поскольку драйверы файловых систем флеш-памяти специально написаны для конкретных целевых систем, они обычно запускаются без командно-строковых параметров и обнаруживают в системе накопитель, для которого они предназначены.

Сетевые драйверы

Сетевые службы запускаются командой io-pkt-*, которая загружает необходимые файлы .so.


Note: Для динамического запуска и останова сетевых драйверов в командной строке можно использовать команды mount и umount. Пример:

mount -T io-pkt devn-ne2000.so

Дополнительную информацию см. в описании утилиты mount.


Командно-строковые параметры io-pkt-* запускают два уровня файлов .so:

Параметр -d позволяет задавать драйвер конкретной платы. Например, параметр -d ne2000 указывает менеджеру io-pkt-* загрузить модуль devn-ne2000.so для доступа к сетевой плате, которая совместима с NE-2000. После параметра -d можно задавать дополнительные командно-строковые параметры (например, вектор прерываний платы).

Параметр -p позволяет выбирать драйвер конкретного протокола. Как и при использовании параметра -d, после параметра -p указываются командно-строковые параметры драйвера, такие как IP-адрес конкретного интерфейса.

Дополнительную информацию о сетевых службах см. в описании компонентов devn-* и io-pkt-*.

Сетевые файловые системы

ЗОСРВ «Нейтрино» поддерживает два типа сетевых файловых систем:

Несмотря на то, что файловая система 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 почти не используется.


Caution: Тем не менее, при наличии проблем с аппаратной составляющей, могут возникать условия для потери программной управляемости. В этом случае аппаратный отладчик становится безальтернативным как на этапе диагностики, так и при отладке.

Агент отладки программ pdebug

В состав ЗОСРВ «Нейтрино» входит агент отладки pdebug, который облегчает отладку системных драйверов и пользовательских приложений. Программа pdebug выполняется на целевой системе и взаимодействует с отладчиком инструментальной системы через Ethernet-соединение.

Аппаратные JTAG-отладчики

Основное ограничение применения агента pdebug заключается в том, что ядро операционной системы должно уже выполняться на целевом устройстве. Другими словами, pdebug можно использовать только при условии, что IPL и код запуска успешно запустили ядро.

Тем не менее, поскольку IPL и модуль startup-* выполняются в физическом режиме, можно отлаживать их с помощью традиционных аппаратных отладчиков. В этом состоит основная функция JTAG-отладчика на этапе разработки программного обеспечения ЗОСРВ «Нейтрино». Для отладки BSP (IPL и модуль startup-*) используется аппаратный отладчик, а для отладки драйверов и приложений после запуска ядра — агент pdebug. С помощью аппаратного отладчика также можно изучать содержимое регистров и памяти во время работы ядра и приложений, если известны соответствующие физические адреса.

Такие аппаратные отладчики как Lauterbach или AMC оснащены встроенными функциями поддержки ЗОСРВ «Нейтрино» (OS awareness) и с их помощью можно отлаживать приложения через интерфейс JTAG. Эти отладчики интерпретируют информацию ядра и позволяют изучать данные приложений, выполняя преобразования между виртуальными и физическими адресами.

Генерация отладочных символов для IPL и startup

Можно отлаживать IPL и модуль startup-* с помощью аппаратных отладчиков без какой-либо дополнительной информации. Тем не менее, такая отладка выполняется только на уровне ассемблера, и ассемблерные символы (например, имена подпрограмм) скрыты от разработчика. Для полноценной отладки на уровне исходного кода необходимо предоставлять аппаратному отладчику символьную информацию и код программ на языке C.

В этом разделе рассматривается процедура генерации символов для отладки на уровне исходного кода с помощью аппаратного отладчика. Указанная процедура относится к пакету поддержки платы PPC (PowerPC) с IPL и модулем startup-* для базовой аппаратной платформы Motorola Sandpoint MPC750.

Предполагается, что разработчик находится в среде разработки с привилегиями пользователя root.

Генерация отладочных символов для IPL

Чтобы сгенерировать символьную информацию для IPL, необходимо перекомпилировать его и библиотеку libipl. Выполните следующие действия:

  1. измените исходный код IPL
  2. выполните сборку библиотеки libipl и IPL
  3. поместите IPL во флеш-память платы с помощью программатора или интерфейса JTAG
  4. измените формат вывода на ELF в файле sandpoint.lnk
  5. перекомпилируйте библиотеку libipl и код IPL с включением в них отладочной информации
  6. загрузите ELF-файл IPL с отладочной информацией в аппаратный отладчик


Note: Синхронизируйте исходный код, 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.


Note: Чтобы пересобрать BSP, необходимо заново указать формат вывода SREC в файле sandpoint.lnk. Также важно, чтобы IPL, который находится во флеш-памяти, соответствовал сгенерированой отладочной информации; при изменении исходного кода IPL необходимо пересобирать BSP, записывать обновленного IPL во флеш-память и пересобирать символьную и отладочную информацию начального загрузчика.

Для просмотра информации ELF можно использовать утилиту objdump. Например, чтобы просмотреть символьную информацию, которая содержится в файле ipl-sandpoint, следует ввести команду

objdump -t ipl-sandpoint | less

Теперь можно импортировать файл ipl-sandpoint с символьной информацией в аппаратного отладчика. Аппаратному отладчику также необходимы исходные коды, которые размещены в следующих каталогах:

Генерация отладочных символов для startup

Чтобы сгенерировать символьную информацию для модуля startup-*, необходимо перекомпилировать ее и libstartup. Выполните следующие действия:

  1. измените исходный код модуля startup-*
  2. соберите libstartup и модуль startup-* с отладочной информацией
  3. пересоберите образ и символьный файл
  4. загрузите символьный файл в программу аппаратного отладчика
  5. поместите образ на целевую систему (запишите во флеш-память или передайте через последовательный порт)

Чтобы выполнить сборку 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.


Note: Невозможно получить отладочные символы, загрузив ELF-файл startup-sandpoint в аппаратный отладчик, поскольку утилита mkifs добавляет к адресам, которые указаны в символах, смещение, заданное в файле построения загрузочного образа.

Назначьте атрибут +keeplinked модулю startup-* в файле построения загрузочного образа:

cd bsp/sandpoint/images

Измените строку модуля startup-* в файле построения загрузочного образа следующим образом:

[image=0x10000]
[virtual=ppcbe,binary +compress] .bootstrap = {
[+keeplinked] startup-sandpoint -vvv -D8250
PATH=/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-* в аппаратном отладчике. Аппаратному отладчику также необходим исходный код, который размещен в следующих каталогах:




Предыдущий раздел: перейти