Руководство по разработке проектов в Yocto Project (часть 2)

Часть 1

3.13. Использование x32 psABI

Двоичный интерфейс приложений x32 ABI (x32 psABI) является естественным ABI для архитектуры Intel® 64 (x86-64) и определяет соглашения о вызовах функций в среде обработки, задавая используемые регистры и размеры различных типов данных C.

Некоторые среды обработки предпочитают использовать 32-битовые приложения даже на 64-разрядных платформах Intel. Рассмотрим i386 psABI, который является самым старым из 32-битовых ABI для платформ Intel 64. i386 psABI не обеспечивает эффективного использования и доступа ко всем ресурсам 64-битовых процессоров Intel 64, оставляя процессоры недогруженными. По сравнению с этим интерфейс x86_64 psABI более новый и использует 64 бита для размеров данных и указателей. Дополнительные биты увеличивают размер программ и библиотек, а также потребности в памяти и дисковом пространстве. Работа в среде x32 psABI позволяет позволяет программам более эффективно использовать ресурсы CPU и системы, а также снижать размер приложений. Дополнительные биты используются для регистров, но не для адресации.

YP поддерживает финальную спецификацию x32 psABI, как показано ниже.

  • Создание пакетов и образов в формате x32 psABI для целевых платформ x86_64.
  • Возможность собирать задания, с использованием инструментария x32.
  • Возможность создавать и загружать образы core-image-minimal и core-image-sato images.
  • Поддержка менеджером RPM имеющихся двоичных файлов x32.
  • Поддержка больших образов.

Для использования x32 psABI нужно включить в файл conf/local.conf приведенные ниже строки.

     MACHINE = "qemux86-64"
     DEFAULTTUNE = "x86-64-x32"
     baselib = "${@d.getVar('BASE_LIB_tune-' + (d.getVar('DEFAULTTUNE') \
        or 'INVALID')) or 'lib'}"

После этого можно применять BitBake для сборки образов с поддержкой x32 psABI, например. bitbake core-image-sato.

3.14. Включение поддержки GObject Introspection

GObject introspection является стандартным механизмом доступа к программам на основе Gobject из рабочей среды. GObject является свойством библиотеки Glib, которое предоставляет объектную среду на GNOME и связанных с этой средой программ. GObject Introspection добавляет в GObject информацию, которая позволяет представлять созданные механизмом объекты в разных языках программирования. Если нужно создать конвейеры GStreamer с помощью Python или управлять инфраструктурой UPnP с использованием Javascript и GUPnP, GObject introspection обеспечивает единственный способ сделать это.

В этом разделе описаны средства YP для генерации и упаковки данных GObject introspection, которые представляют собой описание API, обеспечиваемого библиотеками, собранными на основе инфраструктуры GLib, в частности, механизм GObject. Файлы репозитория GObject Introspection (GIR) помещаются в пакеты -dev, файлы typelibв основные пакеты, поскольку они упаковываются вместе с библиотеками, которые подвергаются самоанализу.

Данные создаются при сборке библиотеки путем компоновки библиотеки с небольшим исполняемым модулем, запрашивающим у библиотеки ее описание, а затем выполняющим обработку этого описания. Генерация таких данных в среде кросс-компиляции осложняется тем, что библиотека предназначена для целевой архитектуры, а код должен выполняться на хосте сборки. Эта проблема решается в системе сборки OE запуском кода в QEMU. К сожалению, QEMU не всегда работает хорошо.

3.14.1. Генерация данных самоанализа

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

  1. Наследование класса gobject-introspection.
  2. Проверка отсутствия блокировки самоанализа в задании и включаемых файлах. Следует проверить также отсутствие gobject-introspection-data в переменной DISTRO_FEATURES_BACKFILL_CONSIDERED и qemu-usermode в переменной MACHINE_FEATURES_BACKFILL_CONSIDERED, отключающих самоанализ.
  3. Сборка образа. При возникновении ошибок, похожих на невозможность найти библиотеки .so следует найти эти библиотеки в дереве кода и добавить в задание строку вида GIR_EXTRA_LIBS_PATH = «${B}/something/.libs». Примеры использования переменной можно найти в репозитории oe-core.
  4. Другие ошибки могут быть связаны с не совсем стандартной поддержкой самоанализа в пакете, приводящим к проблемам кросс-компиляции. Такие вопросы часто обсуждаются в почтовых конференциях YP.

3.14.2. Запрет генерации данных самоанализа

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

  • Добавить в конфигурацию дистрибутива строку DISTRO_FEATURES_BACKFILL_CONSIDERED = «gobject-introspection-data», которая отключит генерацию данных самоанализа с помощью QEMU, но сохранит сборку инструментов и библиотек для самоанализа (для этого не требуется QEMU).
  • Добавить в конфигурацию машины строку MACHINE_FEATURES_BACKFILL_CONSIDERED = «qemu-usermode», которая отключит использование QEMU при сборке пакетов для машины. В настоящее время этот вариант применяется только заданиями с самоанализом и дает такой же эффект, как предыдущий вариант. В будущих выпусках YP этот вариант может влиять и на другие свойства.

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

3.14.3. Тестирование данных самоанализа для образа

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

  1. Проверка отсутствия gobject-introspection-data в переменной DISTRO_FEATURES_BACKFILL_CONSIDERED и qemu-usermode в переменной MACHINE_FEATURES_BACKFILL_CONSIDERED.
  2. Сборка образа core-image-sato.
  3. Запуск терминальной сессии и Python в этой сессии.
  4. Ввод на терминале команд
         >>> from gi.repository import GLib
         >>> GLib.get_host_name()
  5. Более полное описание доступно по ссылке http://python-gtk-3-tutorial.readthedocs.org/en/latest/introduction.html.

3.14.4. Известные проблемы

С поддержкой GObject Introspection связан ряд проблем, указанных ниже.

  • «Падение» qemu-ppc64, не позволяющее собрать данные самоанализа для архитектуры.
  • Отсутствие поддержки x32 в QEMU и связанное с этим отключение данных самоанализа.
  • «Падение» временных библиотек GLib в musl и связанное с этим отключение данных самоанализа.
  • Отключение данных самоанализа для некоторых пакетов в результате неспособности QEMU корректно выполнять некоторые двоичные файлы для определенной архитектуры (например, gcr, libsecret, webkit).
  • Некорректная работа QEMU в пользовательском режиме при запуске 64-битовых программ на 32-битовом хосте сборки. В частности, qemumips64 не работает с i686.

3.15. Использование внешних инструментов

Для использования в процесс разработки внешних инструментов следует выполнить ряд действий.

  • Разобраться с местоположением инструментов. Для их сборки потребуются дополнительные действия.
  • Добавить уровень с инструментами в файл bblayers.conf через переменную BBLAYERS.
  • Указать в переменной EXTERNAL_TOOLCHAIN файла local.conf местоположение инструментов.

Хорошим примером использования внешних инструментов в YP является Mentor Graphics® Sourcery G++. Информация об использовании инструментов приведена в файле README на странице http://github.com/MentorEmbedded/meta-sourcery/. Дополнительная информация приведена также в описании переменной TCMODE [3].

3.16. Создание образов с дисковыми разделами с помощью Wic

Создание образа для определенной аппаратной платформы с использованием системы сборки не обязательно ведет к возможности загрузки этого образа на устройстве. Физические устройства принимают и загружают образы разными способами с учетом своих возможностей. Обычно информация об устройстве может подсказать нужный формат. Если для устройства нужны несколько разделов на SD-карте, флэш-диске или HDD, можно использовать OE Image Creator (Wic) для создания образа с разделами.

Команда wic создает образы с разделами из результатов сборки OE. Генерация образа управляется командами разбиения из файла OE kickstart (.wks), заданного в команде напрямую или выбранного из стандартных файлов, которые можно увидеть по команде wic list images (3.16.5. Использование имеющихся файлов Kickstart). Использование команды для имеющихся результатов сборки приводит к созданию одного или нескольких образов, которые можно записать на носитель и поместить в устройство. Описание файлов kickstart приведено в разделе OpenEmbedded Kickstart (.wks) Reference [3].

Команда wic и инфраструктура, на которой она основана, по определению неполны. Задача команды — разрешить создание настраиваемых образов, поэтому команда проектировалась для расширения через интерфейс подключаемых модулей, описанных в параграфе 3.16.6. Использование интерфейса подключаемых модулей Wic.

3.16.1. Основы

Здесь приведены некоторые сведения об утилите Wic, которые могут быть интересны, хотя и не требуются для работы.

  • Имя Wic образовано от oeic1, где дифтонг oe произносится как w, поскольку oeic сложней запомнить и сказать.
  • Wic базируется на платформе Meego Image Creator (mic), но реализация Wic существенно переработана для прямого использования результатов сборки OE вместо установки и настройки пакетов, которые уже включены в результаты OE.
  • Wic является независимой автономной утилитой, которая является более простой и гибкой в сравнении с классом OE-Core image-live. Функциональность Wic реализована базовым языком разбиения, основанным на синтаксисе Redhat kickstart.

3.16.2. Требования

Для использования Wic в системе сборки OE нужно выполнить приведенные ниже требования.

  • Дистрибутив Linux на хосте сборки должен поддерживать YP (см. раздел Supported Linux Distributions [3]).
  • На хосте сборки должны быть установлены стандартные системные утилиты, такие как cp.
  • Следует выполнить сценарий инициализации среды (oe-init-build-env) из каталога сборки.
  • Результаты сборки должны быть доступны, что обычно означате наличие собранного с помощью OE образа (например, core-image-minimal). Создание образа для генерации образа с помощью Wic модет показаться избыточным, но для текущей версии Wic нужны результаты работы системы сборки OE.
  • Нужно собрать несколько естественных инструментов для работы на хосте сборки с помощью команды bitbake parted-native dosfstools-native mtools-native.
  • Нужно включить wic в переменную IMAGE_FSTYPES.
  • Нужно включить имя файла kickstart в переменную WKS_FILE.

3.16.3. Доступ к справочной информации

Можно получить справку о работе с командой с помощью команды wic с опцией wic -h, wic —help или wic help. В настоящее время Wic поддерживает 7 команд — cp, create, help, list, ls, rm, write. Для получения справки по работе с ними служат команды вида wic help command. Например, команда wic help write выведет справку о работе с командой write. Wic поддерживает 3 темы справок — overview, plugins и kickstart. Можно получить справку по любой из тем командой вида wic help topic. Например, для получения обзорной справки служит команды wic help overview.

Имеется дополнительный вид справок для Wic, показывающий список доступных образов Wic.

     $ wic list images
       mpc8315e-rdb     	Create SD card image for MPC8315E-RDB
       genericx86       	Create an EFI disk image for genericx86*
       beaglebone-yocto 	Create SD card image for Beaglebone
       edgerouter       	Create SD card image for Edgerouter
       qemux86-directdisk	Create a qemu machine 'pcbios' direct disk image
       directdisk-gpt   	Create a 'pcbios' direct disk image
       mkefidisk        	Create an EFI disk image
       directdisk       	Create a 'pcbios' direct disk image
       systemd-bootdisk 	Create an EFI disk image with systemd-boot
       mkhybridiso      	Create a hybrid ISO image
       sdimage-bootpart 	Create SD card image with a boot partition
       directdisk-multi-rootfs	Create multi rootfs image using rootfs plugin
       directdisk-bootloader-config	Create a 'pcbios' direct disk image with custom bootloader config

Зная список образов, можно получить справку по конкретному образу с помощью команды вида

     $ wic list beaglebone-yocto help
     Creates a partitioned SD card image for Beaglebone.
     Boot files are located in the first vfat partition.

3.16.4. Режимы работы

В зависимости от уровня управления результатами вывода системы сборки OE доступны 2 режима — Raw и Cooked:

  • режим Raw позволяет явно указать результаты сборки параметрами команды Wic;
  • режим Cooked использует текущую установку MACHINE и имя образа для автоматического выбора результатов сборки, включаемых в образ; нужно лишь указать файл kickstart и имя образа для включения результатов сборки.

В любом случае результаты сборки должны быть доступны в момент ввода команды.

3.16.4.1. Режим Raw

Запуск Wic в режиме raw позволяет указать все разделы в строке команды. Основным применением этого режима является создание образов при сборке ядра за пределами дерева YP. Иными словами, можно указать произвольное ядро, размещение корневой файловой системы и т. п. В режиме cooked просматривается лишь каталог сборки (например, tmp/deploy/images/machine). Команда wic имеет вид wic create wks_file options

wks_file

Файл OpenEmbedded kickstart. Можно использовать свой файл или один из имеющихся в системе сборки.

Дополнительные аргументы рассмотрены ниже.

-h, —helpshow

выводит справочную информацию и завершает работу.

-o OUTDIR, —outdir OUTDIR

каталог для создания образа.

-e IMAGE_NAME, —image-name IMAGE_NAME

имя образа для использования результатов сборки (например, core-image-sato).

-r ROOTFS_DIR, —rootfs-dir ROOTFS_DIR

путь к каталогу /rootfs для использования в качестве источника .wks rootfs.

-b BOOTIMG_DIR, —bootimg-dir BOOTIMG_DIR

путь к каталогу с элементами загрузки (например, /EFI или /syslinux) для использования в .wks bootimg.

-k KERNEL_DIR, —kernel-dir KERNEL_DIR

путь к каталогу с ядром для использования в .wks bootimg

-n NATIVE_SYSROOT, —native-sysroot NATIVE_SYSROOT

путь к native sysroot с инструментами, использованными при сборке образа.

-s, —skip-build-check

задает пропуск проверки сборки.

-f, —build-rootfs

rootfs для сборки.

-c {gzip,bzip2,xz}, —compress-with {gzip,bzip2,xz}

задает алгоритм сжатия образа.

-m, —bmapgenerate

.bmap

—no-fstab-update

отключает изменения файла fstab.

-v VARS_DIR, —vars VARS_DIR

каталог с файлами <image>.env. Содержащими переменные bitbake.

-D, —debug

задает вывод отладочной информации.

Для запуска Wic не нужны полномочия root и даже не следует использовать утилиту от имени root.

3.16.4.2. Режим Cooked

Wic в режиме cooked использует элементы из каталога сборки. Иными словами, не нужно указывать размещение ядра и корневой файловой системы, достаточно указать файл kickstart и образ из которого берутся результаты сборки, с помощью опции -e. Wic в режиме Cooked запускается командой вида wic create wks_file -e IMAGE_NAME.

wks_file

Имя файла OE kickstart. Можно использовать свой файл или один из файлов в составе выпуска YP.

Обязательный аргумент

-e IMAGE_NAME, —image-name IMAGE_NAME — имя образа для использования результатов сборки (например, core-image-sato)

3.16.5. Использование имеющихся файлов Kickstart

Можно не создавать свой файл kickstart, воспользовавшись готовыми из состава Wic. Эти файлы можно найти в репозитории YP (каталог poky/meta-yocto-bsp/wic или poky/scripts/lib/wic/canned-wks). Для просмотра доступных файлов можно использовать команду wic list images.

     $ wic list images
       mpc8315e-rdb     	Create SD card image for MPC8315E-RDB
       genericx86       	Create an EFI disk image for genericx86*
       beaglebone-yocto 	Create SD card image for Beaglebone
       edgerouter       	Create SD card image for Edgerouter
       qemux86-directdisk	Create a qemu machine 'pcbios' direct disk image
       directdisk-gpt   	Create a 'pcbios' direct disk image
       mkefidisk        	Create an EFI disk image
       directdisk       	Create a 'pcbios' direct disk image
       systemd-bootdisk 	Create an EFI disk image with systemd-boot
       mkhybridiso      	Create a hybrid ISO image
       sdimage-bootpart 	Create SD card image with a boot partition
       directdisk-multi-rootfs	Create multi rootfs image using rootfs plugin
       directdisk-bootloader-config	Create a 'pcbios' direct disk image with custom bootloader config

При использовании имеющегося файла не нужно указывать расширение .wks. Ниже приведен пример использования файла directdisk в режиме Raw.

$ wic create directdisk -r rootfs_dir -b bootimg_dir -k kernel_dir -n native_sysroot

Фактические команды языка разбиения, используемые в файле genericx86.wks для создания образа, показаны ниже.

# short-description: Create an EFI disk image for genericx86*
# long-description: Creates a partitioned EFI disk image for genericx86* machines
part /boot --source bootimg-efi --sourceparams="loader=grub-efi" --ondisk sda --label msdos --active --align 1024
part / --source rootfs --ondisk sda --fstype=ext4 --label platform --align 1024 --use-uuid
part swap --ondisk sda --size 44 --label swap1 --fstype=swap

bootloader --ptable gpt --timeout=5 --append="rootfstype=ext4 console=ttyS0,115200 console=tty0"

3.16.6. Использование интерфейса подключаемых модулей Wic

Можно расширить и настроить Wic с помощью подключаемых модулей (plug-in). Плагины Wic состоят из двух частей — source и imager (не рассматриваются здесь). Модули source обеспечивают механизм настройки содержимого разделов в процессе генерации образа. Можно использовать модули source для отображения значений, указываемых командами —source в файлах *.wks на реализацию модуля, применяемого для заполнения раздела.

При использовании модулей, связанных зависимостями (например, от инструментов native, загрузчиков и т. п.) во время построения образа Wic, нужно указать эти зависимости в переменной WKS_FILE_DEPENDS. Модули source являются субклассом, определяемым в файлах plug-in. Некоторые из таких файлов входят в состав YP. Каждый файл содержит плагины source, предназначенные для заполнения разделов в образах Wic. Класс SourcePlugin, к которому относятся модули source, определен в файле poky/scripts/lib/wic/pluginbase.py.

Можно реализовать модули source на уровне, лежащем вне репозитория исходных кодов (внешний уровень). При этом они должны находиться в каталоге scripts/lib/wic/plugins/source/ внутри этого уровня, чтобы быть доступными для Wic.

Когда реализации Wic нужно вызвать зависящую от раздела реализацию, просматриваются плагины с именем, указанным параметром —source в файле kickstart для этого раздела. Например, при установке раздела с помощью команды part /boot —source bootimg-pcbios —ondisk sda —label boot —active —align 1024 используются методы, определенные как члены класса соответствующего подключаемого модуля source (bootimg-pcbios) в файле bootimg-pcbios.py.

Ниже приведено соответствующее определение плагина из the bootimg-pcbios.py для предыдущей команды вместе с примером метода, вызываемого реализацией Wic для подготовки раздела с зависимой от реализации функцией.

      ...
     class BootimgPcbiosPlugin(SourcePlugin):
         """
         Create MBR boot partition and install syslinux on it.
         """

         name = 'bootimg-pcbios'
      ...
         @classmethod
         def do_prepare_partition(cls, part, source_params, creator, cr_workdir,
          oe_builddir, bootimg_dir, kernel_dir,
          rootfs_dir, native_sysroot):
 """
 Called to do the actual content population for a partition i.e. it
 'prepares' the partition to be incorporated into the image.
 In this case, prepare content for legacy bios boot partition.
 """
      ...

Если субкласс (plug-in) сам не реализует определенную функцию, Wic находит и использует принятую по умолчанию версию надкласса (superclass). По этой причине все модули source выводятся из класса SourcePlugin. Этот класс, определенный в pluginbase.py, включает набор методов, которые модули source plug-ins могут использовать или переопределять. Все плагины (субкласс SourcePlugin), не реализующие тот или иной метод, наследуют его реализацию от класса SourcePlugin. Описание SourcePlugin можно найти в файле pluginbase.py, а ниже приведен список реализованных в этом классе методов.

  • do_prepare_partition() вызывается для заполнения раздела содержимым. Иными словами, метод готовит окончательный образ раздела для встраивания в образ диска.
  • do_configure_partition() вызывается перед do_prepare_partition() для создания конфигурационных файлов раздела (например, для syslinux или grub).
  • do_install_disk() вызывается после того, как все разделы подготовлены и собраны в образ диска. Этот метод обеспечивает завершение записи образа диска (например, запись MBR).
  • do_stage_partition()специальный метод подготовки содержимого перед вызовом do_prepare_partition(). Обычно этот метод пуст. Раздел, как правило, просто использует переданные параметры (например, неизменное значение bootimg_dir), однако в некоторых случаях может потребоваться особый подход. Например, могут потребоваться некоторые файлы из bootimg_dir + /boot. Этот метод позволяет размещать такие файлы индивидуально. Метод get_bitbake_var() обеспечивает доступ к нестандартным переменным, которые могут применяться в таких случаях.

Механизм модулей source можно расширить путем добавления «ловушек», создания дополнительных методов в SourcePlugin и соответствующих производных субклассов. Код, вызывающий методы, использует функцию plugin.get_source_plugin_methods() для поиска требуемых методов. Поиск реализуется с помощью ключей, содержащих имена методов.

3.16.7. Примеры

В этом разделе приведено несколько примеров использования утилиты Wic. Предполагается, что выполнены все требования раздела 3.16.2. Требования и применяется заранее созданный образ core-image-minimal.

3.16.7.1. Создание образа с имеющимся файлом Kickstart

Здесь используется режим Cooked с kickstart-файлом mkefidisk.

$ wic create mkefidisk -e core-image-minimal
INFO: Building wic-tools...
   .
   .
   .
INFO: The new image(s) can be found here:
  ./mkefidisk-201804191017-sda.direct

The following build artifacts were used to create the image(s):
ROOTFS_DIR: /home/stephano/build/master/build/tmp-glibc/work/qemux86-oe-linux/core-image-minimal/1.0-r0/rootfs
BOOTIMG_DIR: /home/stephano/build/master/build/tmp-glibc/work/qemux86-oe-linux/core-image-minimal/1.0-r0/recipe-sysroot/usr/share
KERNEL_DIR: /home/stephano/build/master/build/tmp-glibc/deploy/images/qemux86
NATIVE_SYSROOT: /home/stephano/build/master/build/tmp-glibc/work/i586-oe-linux/wic-tools/1.0-r0/recipe-sysroot-native

INFO: The image(s) were created using OE kickstart file:
       /home/stephano/build/master/openembedded-core/scripts/lib/wic/canned-wks/mkefidisk.wks

Это простейший способ создать образ в режиме cooked с указанием kickstart-файла и опции -e для задания имеющихся результатов сборки. В файле local.conf переменная MACHINE должна указывать используемую машину (qemux86).

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

Полученный образ можно записать из каталога сборки на USB-носитель или иную среду и загрузить систему с нее. Для записи можно использовать команду bmaptool или dd, как показано ниже.

$ oe-run-native bmaptool copy mkefidisk-201804191017-sda.direct /dev/sdX

или

$ sudo dd if=mkefidisk-201804191017-sda.direct of=/dev/sdX

Информация об использовании bmaptool приведена в разделе 3.17. Запись образов с помощью bmaptool.

3.16.7.2. Использование измененного файла Kickstart

Поскольку созданием образа с разделами управляет файл kickstart, изменение параметров файле позволяет влиять на получаемый образ. Ниже приведен пример этого с использованием файла directdisk-gpt.

Как было отмечено, команда wic list images выводит список имеющихся kickstart-файлов. Файл directdisk-gpt.wks размещается в каталоге scripts/lib/image/canned-wks/ внутри дерева исходных кодов (например, poky). В этом каталоге размещаются другие файлы и можно создать свой kickstart-файл. Имеющийся файл directdisk-gpt содержит почти все, что нужно для примера. Однако для загрузки образа в примере будет применяться устройство sdb вместо sda, указанного в файле directdisk-gpt.

В примере сначала создается копия файла directdisk-gpt.wks с другим именем в каталоге scripts/lib/image/canned-wks.

     $ cp /home/stephano/poky/scripts/lib/wic/canned-wks/directdisk-gpt.wks \
          /home/stephano/poky/scripts/lib/wic/canned-wks/directdisksdb-gpt.wks

Затем ф копии directdisksdb-gpt.wks строка «—ondisk sda» заменяется на «—ondisk sdb«, как показано ниже.

part /boot --source bootimg-pcbios --ondisk sdb --label boot --active --align 1024
part / --source rootfs --ondisk sdb --fstype=ext4 --label platform --align 1024 --use-uuid

Этот файл будет создавать образ directdisksdb-gpt с результатами сборки core-image-minimal для машины Next Unit of Computing (nuc), указанной переменной MACHINE в файле local.conf.

$ wic create directdisksdb-gpt -e core-image-minimal
INFO: Building wic-tools...
...
Initialising tasks: 100% |#######################################| Time: 0:00:01
NOTE: Executing SetScene Tasks
NOTE: Executing RunQueue Tasks
NOTE: Tasks Summary: Attempted 1161 tasks of which 1157 didn't need to be rerun and all succeeded.
INFO: Creating image(s)...

INFO: The new image(s) can be found here:
       ./directdisksdb-gpt-201710090938-sdb.direct

The following build artifacts were used to create the image(s):
ROOTFS_DIR: /home/stephano/build/master/build/tmp-glibc/work/qemux86-oe-linux/core-image-minimal/1.0-r0/rootfs
BOOTIMG_DIR: /home/stephano/build/master/build/tmp-glibc/work/qemux86-oe-linux/core-image-minimal/1.0-r0/recipe-sysroot/usr/share
KERNEL_DIR:       /home/stephano/build/master/build/tmp-glibc/deploy/images/qemux86
NATIVE_SYSROOT:   /home/stephano/build/master/build/tmp-glibc/work/i586-oe-linux/wic-tools/1.0-r0/recipe-sysroot-native

INFO: The image(s) were created using OE kickstart file:
  /home/stephano/poky/scripts/lib/wic/canned-wks/directdisksdb-gpt.wks

В продолжение примера образ записывается с помощью команды dd на накопитель USB или иную среду для загрузки.

     $ sudo dd if=directdisksdb-gpt-201710090938-sdb.direct of=/dev/sdb
     140966+0 records in
     140966+0 records out
     72174592 bytes (72 MB, 69 MiB) copied, 78.0282 s, 925 kB/s
     $ sudo eject /dev/sdb
3.16.7.3. Использование измененного файла Kickstart и работа в режиме Raw

В следующем примере вручную задаются все включаемые в образ результаты сборки (режим Raw) и используется измененный файл kickstart. Применяется также опция -o, заставляющая Wic создавать в отличном от принятого по умолчанию каталоге.

$ wic create /home/stephano/my_yocto/test.wks -o /home/stephano/testwic \
--rootfs-dir /home/stephano/build/master/build/tmp/work/qemux86-poky-linux/core-image-minimal/1.0-r0/rootfs \
--bootimg-dir /home/stephano/build/master/build/tmp/work/qemux86-poky-linux/core-image-minimal/1.0-r0/recipe-sysroot/usr/share \
--kernel-dir /home/stephano/build/master/build/tmp/deploy/images/qemux86 \
--native-sysroot /home/stephano/build/master/build/tmp/work/i586-poky-linux/wic-tools/1.0-r0/recipe-sysroot-native

INFO: Creating image(s)...

INFO: The new image(s) can be found here:
  /home/stephano/testwic/test-201710091445-sdb.direct

The following build artifacts were used to create the image(s):
ROOTFS_DIR:       /home/stephano/build/master/build/tmp-glibc/work/qemux86-oe-linux/core-image-minimal/1.0-r0/rootfs
BOOTIMG_DIR:      /home/stephano/build/master/build/tmp-glibc/work/qemux86-oe-linux/core-image-minimal/1.0-r0/recipe-sysroot/usr/share
KERNEL_DIR:       /home/stephano/build/master/build/tmp-glibc/deploy/images/qemux86
NATIVE_SYSROOT:   /home/stephano/build/master/build/tmp-glibc/work/i586-oe-linux/wic-tools/1.0-r0/recipe-sysroot-native

INFO: The image(s) were created using OE kickstart file:
  /home/stephano/my_yocto/test.wks

В этом примере переменная MACHINE не задана в файле local.conf, поэтому результаты сборки указываются вручную.

3.16.7.4. Использование Wic для манипуляций с образом

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

В рассматриваемом ниже примере предполагается наличие на хосте разработки установленного пакета mtools. В примере из образа Wic удаляется удаляется ядро, затем в образ помещается новое ядро.

  1. Просмотр списка разделов с помощью команды wic ls.
         $ wic ls tmp/deploy/images/qemux86/core-image-minimal-qemux86.wic
         Num     Start        End          Size      Fstype
          1       1048576     25041919     23993344  fat16
          2      25165824     72157183     46991360  ext4    

    Вывод показывает два раздела в образе core-image-minimal-qemux86.wic.

  2. Проверка отдельного раздела с помощью команды wic ls.
         $ wic ls tmp/deploy/images/qemux86/core-image-minimal-qemux86.wic:1
         Volume in drive : is boot
          Volume Serial Number is E894-1809
         Directory for ::/
    
         libcom32 c32    186500 2017-10-09  16:06
         libutil  c32     24148 2017-10-09  16:06
         syslinux cfg       220 2017-10-09  16:06
         vesamenu c32     27104 2017-10-09  16:06
         vmlinuz        6904608 2017-10-09  16:06
     5 files           7 142 580 bytes
          16 582 656 bytes free    

    Вывод команды показывает 5 файлов и файл vmlinuz содержит ядро. Если при работе команды возникает показанная ниже ошибка, следует обновить файл ~/.mtoolsrc, убедившись в наличии там строки “mtools_skip_check=1“, и повторить команду Wic.

    ERROR: _exec_cmd: /usr/bin/mdir -i /tmp/wic-parttfokuwra ::/ returned '1' instead of 0
    output: Total number of sectors (47824) not a multiple of sectors per track (32)!
    Add mtools_skip_check=1 to your .mtoolsrc file to skip this test
  3. Удаление имеющегося ядра (vmlinuz) с помощью команды wic rm.
         $ wic rm tmp/deploy/images/qemux86/core-image-minimal-qemux86.wic:1/vmlinuz
  4. Добавление нового ядра с помощью команды wic cp. Местоположение нового ядра зависит от способа его сборки. При использовании devtool и SDK ядро записывается в каталог tmp/work directory расширяемого SDK, а при использовании команды makeв каталог workspace/sources. В примере предполагается, что ядро собрано с помощью devtool.
    wic cp ~/poky_sdk/tmp/work/qemux86-poky-linux/linux-yocto/4.12.12+git999-r0/linux-yocto-4.12.12+git999/arch/x86/boot/bzImage \
    ~/poky/build/tmp/deploy/images/qemux86/core-image-minimal-qemux86.wic:1/vmlinuz 

    После возврата файла ядра в образ можно использовать команду dd или bmaptool для записи образа на карту SD или носитель USB. Отметим, что bmaptool работает в 10 — 20 быстрее, нежели dd.

3.17. Запись образов с помощью bmaptool

Быстрый и простой способ записи образа на загрузочное устройство обеспечивает программа Bmaptool из состава системы сборки OE. Bmaptool является инструментом общего назначения, создающим отображение блоков (bmap) и применяющим его для копирования файла. По сравнению с традиционными средствами, такими как dd и cp, Bmaptool может копировать (записывать) большие файлы существенно быстрее.

При работе с Ubuntu или Debian можно установить пакет bmap-tools и после этого использовать инструмент без указания PATH даже от имени root. Если установить bmap-tools невозможно, потребуется собрать Bmaptool с помощью команды bitbake bmap-tools-native.

Ниже приведен пример записи образа Wic с использованием Bmaptool.

  1. Обновление файла local.conf путем включения строки IMAGE_FSTYPES += «wic wic.bmap».
  2. Подготовка образа. Если образе не был собран заранее с использованием указанной выше переменной IMAGE_FSTYPES, его нужно собрать с помощью команды bitbake image.
  3. Запись образа на устройство с использованием Bmaptool зависит от конкретных настроек. Здесь предполагается, что образ хранится в каталоге deploy/images/ внутри каталога сборки.
    • При наличии прав записи в среду используется команда вида (devX нужно заменить реальным именем).
      $ oe-run-native bmap-tools-native bmaptool copy build-directory/tmp/deploy/images/machine/image.wic /dev/sdX
    • Если прав записи в среду нет, нужно сначала предоставить их с помощью команды sudo chmod 666 /dev/sdX, а затем ввести приведенную выше команду записи.

Для получения справки о работе с bmaptool служит команда bmaptool —help.

3.18. Повышение защищенности образов

Безопасность важна для встраиваемых систем. Ниже приведен ряд ссылок по этим вопросам.

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

3.18.1. Общие вопросы

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

  • Проверка кода, добавляемого в систему (например, приложений), с помощью инструментов статического анализа позволит обнаружить переполнение буферов и другие возможные уязвимости.
  • Особое внимание к защите административных web-интерфейсов, которые зачастую работают с повышенными привилегиями. Это ведет к росту рисков в результате нарушения защиты таких интерфейсов. Следует обратить внимание на основные уязвимости web-систем, такие как кросс-сайтовые сценарии (XSS), непроверяемый ввод и т. п. Как и для системных паролей учетные данные для доступа к web-интерфейсу не должны быть одинаковыми на всех системах. Это особенно важно в тех случаях, когда интерфейс включен по умолчанию, поскольку не все пользователи поменяют сразу учетные записи.
  • Возможность обновления программ на устройстве для устранения обнаруженных уязвимостей, что особо важно для устройств с доступом в сеть.
  • Удаление или запрет функций отладки в окончательном образ, как описано в параграфе 3.18.3. Вопросы, связанные с системой сборки OE.
  • Отключение или удаление ненужных сетевых служб.
  • Удаление из образа ненужных программ.
  • Включение аппаратной поддержки защищенной загрузки, если устройство имеет ее.

3.18.2. Флаги защиты

YP поддерживает флаги защиты, которые позволяют повысить уровень безопасности образов. Флаги защиты определены в файле meta/conf/distro/include/security_flags.inc дерева источников (например, poky). В зависимости от заданий некоторые флаги могут быть установлены или сброшены по умолчанию. Для использования флагов защиты следует включить в файл local.conf или конфигурацию дистрибутива строку require conf/distro/include/security_flags.inc.

3.18.3. Вопросы, связанные с системой сборки OE

Ниже перечислены некоторые действия по повышению уровня защиты образов, связанные с системой сборки OE.

  • Следует исключить debug-tweaks из выбранных в IMAGE_FEATURES свойств. При создании нового проекта в local.conf по умолчанию включается строка EXTRA_IMAGE_FEATURES = «debug-tweaks», для отключения которой достаточно поместить в начало строки символ комментария или исключить из строки debug-tweaks. Эта установка делает пустым пароль root, что может быть полезно при отладке в процессе разработки.
  • Можно установить пароль root для образа, а также пароли иных пользователей (например, администраторов). При установке не следует задавать один пароль для разных образов или пользователей. Предпочтительным методом установки паролей является наследование класса extrausers (см. раздел extrausers.bbclass [3]).
  • Следует рассмотреть вопрос включения инфраструктуры обязательного контроля доступа (MAC), такой как SMACK или SELinux и ее соответствующей настройки на устройстве (см. уровень meta-selinux).

3.18.4. Средства усиления защиты образа

YP включает средства защиты создаваемых образов, которые можно найти на уровне meta-security в Yocto Project Source Repositories.

3.19. Создание своего дистрибутива

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

  • Создание уровня для нового дистрибутива, позволяющего хранить метаданные и код. Использование отдельного уровня упрощает воспроизведение конфигурации сборки для разных машин. Создание уровней общего назначения описано в параграфе 3.1.8. Создание базового уровня с помощью сценария bitbake-layers.
  • Создание файла конфигурации дистрибутива в каталоге conf/distro на уровне дистрибутива. Файл следует назвать в соответствии с именем дистрибутива (например, mydistro.conf). Имя дистрибутива указывается в переменной DISTRO файла local.conf. Можно выделить часть конфигурации во включаемые файлы и затем «требовать» (require) их в файле конфигурации дистрибутива. Включаемые файлы следует размещать в каталоге conf/distro/include. Типичным примером использования включаемых файлов является разделения заданий по номеру версии и выпуску. В файле конфигурации должны быть заданы переменные DISTRO_NAME и DISTRO_VERSION. Переменные DISTRO_FEATURES, DISTRO_EXTRA_RDEPENDS, DISTRO_EXTRA_RRECOMMENDS, TCLIBC не обязательны, но обычно включаются в файл конфигурации дистрибутива.Можно создать файл на основе базовой конфигурации из OE-Core (файл conf/distro/defaultsetup.conf) и просто изменить соответствующие переменные. Другим вариантом является создание файла конфигурации с нуля с использованием defaultsetup.conf или файла конфигурации из другого дистрибутива как образца.
  • Включение переменных, которые задают принятые по умолчанию значения или устанавливают значения как часть конфигурации дистрибутива. Можно включать почти все переменные из файла local.conf.
  • Указание файла конфигурации дистрибутива в файле local.conf каталога сборки через переменную DISTRO. Например, если файл конфигурации называется mydistro.conf, указывается строка DISTRO = «mydistro».
  • Добавление других компонент уровня.
    • Добавление заданий для установки специфических для дистрибутива файлов конфигурации, которые не включены в другие задания. Если такие файлы уже имеются в других заданиях, следует создать для них файлы дополнения (.bbappend). Общее описание и рекомендации по добавлению заданий на уровень приведены в параграфах 3.1.1. Создание своего уровня и 3.1.2. Рекомендации по организации уровней.
    • Добавление заданий, относящихся к дистрибутиву.
    • Включение файла дополнения psplash для фирменной заставки, как описано в параграфе 3.1.5. Использование файлов .bbappend на уровне.
    • Включение других файлов дополнения, вносящих изменения в имеющиеся задания.

3.20. Создание шаблона каталога конфигурации

При распространении своей системы сборки другим пользователям может возникнуть желание изменить сообщение, выводимое сценарием установки, а изменить шаблоны файлов конфигурации (local.conf и bblayers.conf) в каталоге сборки.

Система сборки OE использует переменную TEMPLATECONF для указания каталога с данными конфигурации, которые в конечном итоге попадают в каталог conf внутри каталога сборки. По умолчанию задано TEMPLATECONF=${TEMPLATECONF:-meta-poky/conf}. Этот каталог используется системой сборки для хранения шаблонов, из которых создаются некоторые файлы конфигурации. В частности, там содержатся файлы bblayers.conf.sample, local.conf.sample и conf-notes.txt, из которых система сборки создает файлы bblayers.conf и local.conf, а также список целей BitBake.

Для переопределения принятых по умолчанию конфигураций в каждом новом каталоге сборки нужно лишь указать каталог в TEMPLATECONF в файле .templateconf на верхнем уровне дерева источников (например, poky).

Практика рекомендует помещать каталог шаблонов конфигурации на уровень дистрибутива. Например, для уровня meta-mylayer в домашнем каталоге можно создать каталог шаблонов конфигурации myconf. Описанное изменение .templateconf заставит систему сборки OE просматривать каталог и создавать файлы конфигурации на основе найденных файлов *.sample. Окончательные файлы конфигурации (local.conf и bblayers.conf) в конечно итоге будут помещены в каталог сборки, но созданы будут на основе файлов *.sample.

     TEMPLATECONF=${TEMPLATECONF:-meta-mylayer/myconf}

Кроме файлов *.sample в принятом по умолчанию каталоге meta-poky/conf хранится также файл conf-notes.txt. Сценарий организации среды сборки (oe-init-build-env) использует этот файл для вывода целей BitBake в процессе выполнения сценария. Редактирование conf-notes.txt обеспечивает возможность указать нужные цели. Ниже показан список целей, выводимых в результате работы сценария.

     You can now run 'bitbake <target>'

     Common targets are:
         core-image-minimal
         core-image-sato
         meta-toolchain
         meta-ide-support

3.21. Экономия дискового пространства при сборке

Для экономии дискового пространства при сборке можно добавить в файл local.conf каталога сборки строку INHERIT += «rm_work» для удаления рабочего каталога задания после сборки этого задания (см. rm_work [3]).

3.22. Работа с пакетами

3.22.1. Исключение пакетов из образа

Иногда возникает потребность исключить некоторые пакеты из образа, для чего имеется несколько переменных, указывающих системе сборки необходимость игнорировать рекомендуемые пакеты или совсем не устанавливать пакет. Каждая из перечисленных ниже переменных работает только с пакетами IPK и RPM, но не работает с Debian. Эти переменные можно указывать в файле local.conf file или привязывать к заданию для конкретного образа путем переопределения имени задания. Более подробная информация о переменных представлена в [3].

  • BAD_RECOMMENDATIONS указывает пакеты, которые не следует устанавливать.
  • NO_RECOMMENDATIONS отменяет установку всех пакетов recommended-only.
  • PACKAGE_EXCLUDE исключает пакет из образа независимо от установки recommended-only. Следует помнить, что это может приводить к отказу, если пакет требуется для установки другого пакета.

3.22.2. Инкрементирование версии пакета

Здесь рассматривается управление нумерацией версий двоичных пакетов и рассмотрены некоторые переменные и термины. Для понимания нумерации версий пакетов нужно принимать во внимание ряд аспектов, указанных ниже.

  • Двоичный пакет — это то, что в конечном итоге устанавливается в образ.
  • Версия двоичного пакета состоит из двух компонент — версия и выпуск (revision).
  • Эпоха (PE) также рассматривается, но в большинстве случаев PE игнорируется.
  • Версия и выпуск берутся из переменных PV и PR.
  • PV указывает версию задания и представляет версию программы. Не следует путать PV с версией двоичного пакета.
  • PRвыпуск задания.
  • SRCPVстрока, используемая системой сборки OE для помощи в определении значения PV, когда нужно включить выпуск исходного кода.
  • PR Serviceсетевая служба, помогающая автоматизировать запись пакетов в хранилища, совместимые с имеющимися менеджерами пакетов, такими как RPM, APT, OPKG.

При каждом изменении содержимого двоичного пакета номер его версии должен меняться. Это обеспечивается путем изменения (bumping) значений PR и/или PV, которое может выполняться одним из двух способов:

  • автоматически с использованием службы выпусков пакетов (PR Service);
  • вручную путем инкрементирования значений переменных PR и/или PV.

С учетом того, что основной задачей системы сборки и ее пользователей является поддержка хранилища пакетов, совместимого с имеющимися менеджерами пакетов, такими как RPM, APT и OPKG, предпочтительно использование автоматизированной системы управления версиями. В любой системе основным требованием к версиям двоичных пакетов является монотонное возрастание и наличие компонент версии, поддерживающих это. Поддержка монотонного роста версий описана в параграфе 3.22.2.3. Автоматическое инкрементирование номера версии пакета.

3.22.2.1. Работа с сервисом PR

Как уже отмечалось, попытка сохранять номера выпусков в метаданных подвержена ошибкам, неточна и создает проблемы для людей, представляющих задания. Служба PR автоматически создает возрастающие номера, в частности для выпуска. Информация о службе PR доступна на странице PR Service.

В YP для упрощения нумерации версий используются переменные PE, PV и PR для эпохи, версии и выпуска. Значения переменных зависят от правил и процедур дистрибутива и хранилища пакетов.

Поскольку система сборки OE использует подписи, которые уникальны для данной сборки, она знает, когда нужно заново собрать пакет. Весь ввод в данную задачу представляется подписью и ее изменение может служить сигналом для повторной сборки. Таким образом, система сборки не использует переменные PR, PV, PE для запуска повторной сборки, однако для создания значений этих переменных могут применяться подписи.

Служба PR работает с генераторами OEBasic и OEBasicHash. Значение PR увеличивается при изменении контрольной суммы, а эти изменения вызываются механизмами генератора. Система сборки включает значения из службы PR в поле PR как дополнение, используя форму .x, так что r0 становится r0.1, r0.2 и т. д. Эта схема позволяет использовать имеющиеся значения PR в всех случаях, включая увеличение PR вручную, когда это требуется.

По умолчанию служба PR выключена и не запущена. В результате пакеты генерируются как «самосогласованные». Система сборки добавляет и удаляет пакеты и нет никаких гарантий по части обновления, но образы будут соответствовать внесенным изменениям. Простейшей формой службы PR является ее организация на хосте сборки, где создаются пакеты для хранилища. В этом случае локальную службу PR можно включить, указав в файле local.conf внутри каталога сборки значение PRSERV_HOST = «localhost:0». После запуска службы пакеты будут автоматически получать возрастающие значения PR и BitBake будет обеспечивать запуск и остановку службы.

При наличии нескольких хостов разработки, работающих с одним хранилищем пакетов, будет использоваться общая служба PR для всех систем сборки. В этом случае службу PR нужно запускать командой bitbake-prserv —host ip —port port —start. Кроме того, нужно обновить файл local.conf на каждом хосте сборки, как описано выше, указав сервер и порт.

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

     # It is recommended to activate "buildhistory" for testing the PR service
     INHERIT += "buildhistory"
     BUILDHISTORY_COMMIT = "1"

История сборки описана в разделе 3.28. Поддержка качества вывода сборки.

Система сборки OE не поддерживает данные PR как часть общего состояния (sstate). Если sstate поддерживается, все системы сборки должны использовать общую службу PR или эта служба должна быть отключена на всех хостах сборки. Информация о sstate приведена в разделе Shared State Cache [1].

3.22.2.2. Увеличение PR вручную

Вместо установки службы PR можно вручную увеличивать переменную PR. Если зафиксированные изменения приводят в изменению вывода пакета, значение переменной PR должно быть увеличено при фиксации изменений. Для новых заданий следует устанавливать принятое по умолчанию значение r0. Хотя значение r0 задано по умолчанию, его добавление в новое задание снижает вероятность забыть об увеличении переменной при обновлении задания.

При использовании файла .inc для нескольких заданий можно использовать также переменную INC_PR, чтобы все использующие этот файл задания собирались заново при изменении файла .inc. В этом файле должна устанавливаться переменная INC_PR (исходно r0), а в заданиях нужно установить изначально PR = «${INC_PR}.0», увеличивая последнюю часть при обновлении задания. При обновлении файла .inc увеличивается INC_PR.

При обновлении версии двоичного пакета, предполагающем изменение PV, переменную PR следует сбрасывать в r0 (или ${INC_PR}.0 при использовании INC_PR). Обычно увеличение версии происходит лишь для двоичных пакетов. Однако при изменении PV без увеличения можно увеличить переменную PE (эпоха пакета), для которой по умолчанию установлено значение 0.

Нумерацию версий пакетов рекомендуется вести в соответствии с Debian Version Field Policy Guidelines, где определен механизм сравнения версий и понятие увеличения.

3.22.2.3. Автоматическое инкрементирование номера версии пакета

При выборке из репозитория BitBake использует переменную SRCREV для определения конкретного выпуска кода, который будет служить для сборки. Можно установить SRCREV = «${AUTOREV}», чтобы система сборки OE автоматически применяла последний выпуск программы. Кроме того, нужно указать SRCPV в переменной PV для автоматического обновления версии при изменении выпуска исходного кода, например, PV = «1.0+git${SRCPV}». Система сборки OE будет подставлять вместо SRCPV значение AUTOINC+source_code_revision, заменяя AUTOINC числом в зависимости от состояния службы PR.

  • Если служба PR включена, система сборки инкрементирует номер, подобно поведению PR. Это ведет к монотонному росту номера версии пакета, например,
         hello-world-git_0.0+git0+b6558dd387-r0.0_armv7a-neon.ipk
         hello-world-git_0.0+git1+dd2f5c3565-r0.0_armv7a-neon.ipk    
  • Если служба PR выключена, система сборки заменяет AUTOINC нулем (0). Это ведет к смене версии пакета, поскольку включается выпуск программы, но изменение номера версии не будет монотонным, например,
         hello-world-git_0.0+git0+b6558dd387-r0.0_armv7a-neon.ipk
         hello-world-git_0.0+git0+dd2f5c3565-r0.0_armv7a-neon.ipk    

3.22.3. Обработка пакетов с необязательными модулями

Многие программы включают необязательные модули (plug-in), сборка которых зависит от опций конфигурации. Чтобы избежать дублирования логики включения модулей в задание и необходимости указывать модули вручную, система сборки OE поддерживает функции динамической упаковки модулей, для чего нужно:

  • обеспечить действительную сборку модулей;
  • обеспечить выполнение заданием всех зависимостей модулей от других заданий.
3.22.3.1. Обеспечение сборки модулей

Обеспечить реальное создание пакетов с модулями можно с помощью функции do_split_packages внутри функции Python populate_packages в задании. Функция отыскивает шаблоны файлов и каталогов по указанному пути и создает пакет для найденного, добавляя его в переменную PACKAGES и устанавливая нужные значения FILES_packagename, RDEPENDS_packagename, DESCRIPTION_packagename и т. д. Например, для задания lighttpd

     python populate_packages_prepend () {
         lighttpd_libdir = d.expand('${libdir}')
         do_split_packages(d, lighttpd_libdir, '^mod_(.*)\.so$',
  'lighttpd-module-%s', 'Lighttpd module for %s',
   extra_depends='')
     }

В примере заданно множество параметров при вызове do_split_packages:

  • каталог в котором do_install ищет файлы, устанавливаемые заданием;
  • регулярное выражение для сопоставления с файлами модулей в каталоге поиска; в примере следует обратить внимание на () для указания части выражения, из которой выводится имя модуля;
  • шаблон для имен пакетов;
  • описание каждого пакета;
  • пустая строка для extra_depends отключает заданные по умолчанию зависимости основного пакета lighttpd, поэтому при нахождении файла в ${libdir} с именем mod_alias.so создается пакет для него, а в переменной DESCRIPTION устанавливается значение «Lighttpd module for alias».

Для более сложных случаев имеются другие опции do_split_packages. При необходимости можно расширить логику путем задания функции-ловушки, вызываемой для каждого пакета. Можно вызывать do_split_packages несколько раз если для пакета имеется не один набор модулей. Примеры использования do_split_packages приведены в файле connman.inc file каталога meta/recipes-connectivity/connman/ в репозитории poky, а также в meta/classes/kernel.bbclass.

Ниже перечислены обязательные и дополнительные аргументы do_split_packages.

Обязательные аргументы

root

Путь поиска.

file_regex

Регулярное выражения для сопоставления файлов. Скобки () служат для маркировки части выражения, которую следует применять для вывода имени модуля (для подстановки вместо %s в других аргументах).

output_pattern

Шаблон для имен пакетов (должен включать %s).

description

Описание для каждого пакета (должно включать %s).

Дополнительные аргументы

postinst

Сценарий пост-установки для всех пакетов (как строка).

recursive

True для рекурсивного поиска (принято по умолчанию).

hook

Функция ловушка, вызываемая для каждого совпадения с перечисленными ниже аргументами в заданном порядке:

f

полный путь к файлу или каталогу для сопоставления;

pkg

имя пакета;

file_regex

см. выше;

output_pattern

см. выше;

modulename

Имя модуля, полученное с использованием file_regex.

extra_depends

Дополнительные зависимости при работе (RDEPENDS), устанавливаемые для всех пакетов. Принятое по умолчанию значение None задает зависимость от основного пакета (${PN}). Если такая зависимость не нужна, следует указать пустую строку в этом параметре.

aux_files_pattern

Элементы, добавляемые в FILES для каждого пакета (одна строка или список строк для нескольких пакетов с обязательным включением %s).

postrm

Сценарий postrm для использования со всеми пакетами (как строка).

allow_dirs

True для сопоставления с каталогами (по умолчанию False).

prepend

True задает добавление пакетов в начало PACKAGES, False (принято по умолчанию) — в конец.

match_path

Сопоставление file_regex со всем относительным путем к корню, а не только с именем файла.

aux_files_pattern_verbatim

Элементы, добавляемые в FILES для каждого пакета с выведенными именами модулей вместо преобразования в пригодные для имени пакета (строка или список строк для нескольких пакетов с обязательным включением %s).

allow_links

True разрешает сопоставление символьных ссылок (по умолчанию False).

summary

Резюме для каждого пакета (должно включать %s), значения по умолчанию не задано.

3.22.3.2. Выполнение зависимостей

Второй частью обработки пакетов с необязательными модулями является выполнение зависимостей этих модулей от других заданий. Это можно обеспечить с помощью переменной PACKAGES_DYNAMIC. Например, для упомянутого выше задания lighttpd это будет иметь вид PACKAGES_DYNAMIC = «lighttpd-module-.*».

Имя в регулярном выражении может быть любым. В примере задано имя lighttpd-module-, которое будет префиксом во всех RDEPENDS и RRECOMMENDS для пакетов, имена которых начинаются с этого префикса. При использовании do_split_packages в соответствии с предыдущим параграфом значение, помещаемое в PACKAGES_DYNAMIC, должно соответствовать шаблону имени при вызове do_split_packages.

3.22.4. Управление пакетами в процессе работы

При сборке BitBake преобразует задание в один или несколько пакетов. Например, BitBake принимает задание bash и создает пакеты bash, bash-bashbug, bash-completion, bash-completion-dbg, bash-completion-dev, bash-completion-extra, bash-dbg и т. п. В образ включаются не все созданные пакеты.

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

  • нужно обеспечить обновление развернутых устройств в «полевых» условиях (например, безопасность);
  • нужен быстрый цикл разработки одного или нескольких приложений на целевом устройстве;
  • нужно временно установить отладочные пакеты разных приложений для ускорения отладки;
  • нужно развернуть на устройстве минимальный выбор пакетов с возможностью расширения в «поле».

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

Простая сборка для единственного устройства создает не одну базу данных о пакетах, т. е. созданные при сборке пакеты разделяются по нескольким группам на основе таких критериев, как архитектура CPU, целевая плата и применяемая там библиотека C. Например, сборка для устройства qemux86 создает 3 базы данных — noarch, i586, qemux86. Если нужно сообщить устройству qemux86 о всех доступных пакетах, потребуется отдельно указать каждую из этих баз, как это обычно делается в традиционных дистрибутивах Linux.

Управление пакетами при работе не является обязательным и не требуется для сборки и разработки. Однако для использования такого управления потребуется сделать некоторые дополнительные шаги, описанные ниже.

3.22.4.1. Вопросы сборки

При создании пакетов BitBake нужно знать об используемых форматах пакетов, которые указываются в переменной PACKAGE_CLASSES. Для этого в файле local.conf каталога сборки (например, ~/poky/build/conf/local.conf), указывается переменная вида PACKAGE_CLASSES ?= “package_packageformat”, где packageformat может включать значении ipk, rpm, deb и tar в соответствии с поддерживаемыми типами пакетов. Поскольку YP поддерживает четыре формата, в переменной можно указать несколько значений, однако система сборки OE будет применять лишь первый при создании образа или SDK.

Если нужно иметь базовые данные о пакетах в текущей сборке, а также иметь на платформе соответствующий инструмент управления пакетами при работе, можно включить значение package-management в переменную IMAGE_FEATURES. Однако делать это совсем не обязательно и можно создать образ без баз данных и добавить лишь инструменты для управления пакетами при работе. Например, можно включить opkg в переменную IMAGE_INSTALL, если планируется использовать пакеты IPK. Потом можно будет инициализировать базы данных на целевой системе.

Всякий раз, когда при сборке может быть создан новый пакет или изменен существующий, рекомендуется обновить индекс пакетов после сборки с помощью команды bitbake package-index. Можно возникнуть желание обновить индекс пакетов при сборке того или иного пакета с помощью bitbake some-package package-index, но лучше этого не делать, поскольку BitBake не планирует обновление индекса по завершении сборки пакета и не обеспечивается гарантии того, что собранный пакет будет включен в индекс. Лучше обновлять индекс отдельной командой после сборки пакетов.

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

По завершении сборки пакеты размещаются в каталоге ${TMPDIR}/deploy/packageformat. Например, при ${TMPDIR} = tmp и выборе формата RPM пакеты RPM будут доступны в каталоге tmp/deploy/rpm.

3.22.4.2. Организация сервера

Обычно для работы с пакетами применяют сервер HTTP, который может работать на основе Apache 2, lighttpd, SimpleHTTPServer и т. п. Для простоты здесь описана организация сервера на основе SimpleHTTPServer, хотя это и не является лучшим решением для производственной среды.

Сервер можно запустить из каталога сборки, где хранятся файлы выбранного варианта пакетов (PACKAGE_CLASSES). Ниже приведен пример с каталогом ~/poky/build/tmp/deploy/rpm, где PACKAGE_CLASSES имеет значение package_rpm.

     $ cd ~/poky/build/tmp/deploy/rpm
     $ python -m SimpleHTTPServer
3.22.4.3. Установка цели

Настройка целевой платформы зависит от выбранного менеджера пакетов. Здесь даны сведения для RPM, IPK и DEB.

3.22.4.3.1. Использование RPM

Пакет Dandified Packaging Tool (DNF) обеспечивает управление пакетами RPM в процессе работы. Для этого требуется выполнить начальную установку, если переменные PACKAGE_FEED_ARCHS, PACKAGE_FEED_BASE_PATHS и PACKAGE_FEED_URIS не были установлены до сборки целевого образа.

На целевой платформе нужно уведомить DNF о доступности баз данных о пакетах путем создания файла /etc/yum.repos.d/oe-packages.repo и указания пакетов. Предположим в качестве примера возможность использования на устройстве пакетов i586 и qemux86 с сервера my.server. Важно, чтобы идентификаторы URI в конфигурации репозиториев на платформе корректно указывали удаленные хранилища. Для разработки можно использовать машину сборки, но в рабочей среде лучше вынести пакеты за пределы области сборки и указать их местоположение. Это предотвратит ситуации переписывания системой сборки пакетов в репозитории.

При указании DNF местоположения баз данных о пакетах нужно отдельно указать место для каждой архитектуры или общее место для всех пакетов. Совмещение приведенных ниже вариантов недопустимо.

  • Создание явного списка архитектур путем определения базовых URL для местоположения пакетов:
    [oe-packages]
    baseurl=http://my.server/rpm/i586 http://my.server/rpm/qemux86 http://my.server/rpm/all

    Это указывает DNF базы данных для пакетов трех вариантов архитектуры.

  • Создание одного (полного) индекса пакетов с одним URL для базы данных обо всех пакетах.
         [oe-packages]
         baseurl=http://my.server/rpm

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

После указания базы данных можно собрать информацию о пакетах с помощью команды

     # dnf makecache

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

3.22.4.3.2. Использование IPK

Приложение opkg выполняет управление пакетами IPK при работе системы. Для этого требуется выполнить начальную установку, если переменные PACKAGE_FEED_ARCHS, PACKAGE_FEED_BASE_PATHS и PACKAGE_FEED_URIS не были установлены до сборки целевого образа. Программа opkg использует файлы конфигурации для поиска доступных баз данных о пакетах, поэтому нужно создать эти файлы в каталоге /etc/opkg/ для указания репозиториев.

Предположим, например, что обслуживаются пакеты из каталога ipk/, содержащего базы данных для архитектуры i586, all и qemux86, через сервер HTTPmy.server. На целевой платформе файл конфигурации (например, my_repo.conf) в каталоге /etc/opkg/ будет иметь вид

     src/gz all http://my.server/ipk/all
     src/gz i586 http://my.server/ipk/i586
     src/gz qemux86 http://my.server/ipk/qemux86

После этого выполняется команда извлечения данных из репозитория

     # opkg update

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

3.22.4.3.3. Использование DEB

Приложение apt выполняет управление пакетами DEB при работе системы. Для этого требуется выполнить начальную установку, если переменные PACKAGE_FEED_ARCHS, PACKAGE_FEED_BASE_PATHS и PACKAGE_FEED_URIS не были установлены до сборки целевого образа.

Для информирования apt о репозитории можно создать файл со списком (например, my_repo.list) в каталоге /etc/apt/sources.list.d/. Например, для обслуживания пакетов из каталога deb/ с базами данных для i586, all, qemux86 с помощью сервера HTTP my.server в список следует включить приведенные ниже строки.

     deb http://my.server/deb/all ./
     deb http://my.server/deb/i586 ./
     deb http://my.server/deb/qemux86 ./

После этого выполняется команда извлечения данных из репозитория

     # apt-get update

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

3.22.5. Создание и использование подписанных пакетов

Для улучшения защиты пакетов RPM можно использовать подписи. После проверки подписи система сборки OE может использовать пакет, но если подпись не соответствует, сборка будет прервана.

3.22.5.1. Подписывание пакетов RPM

Для подписывания пакетов RPM нужно добавить в файл local.conf или distro.conf приведенные ниже строки.

# Inherit sign_rpm.bbclass to enable signing functionality
     INHERIT += " sign_rpm"
     # Define the GPG key that will be used for signing.
     RPM_GPG_NAME = "key_name" # Provide passphrase for the key RPM_GPG_PASSPHRASE = "passphrase"

Вместо key_name и passphrase следует указать действительное имя ключа и пароль. Кроме указанных переменных RPM_GPG_NAME и RPM_GPG_PASSPHRASE с подписями связаны две необязательных переменных:

  • GPG_BIN задает двоичный файл gpg, выполняемый при подписывании пакета;
  • GPG_PATH указывает домашний каталог gpg, используемый при подписывании пакета.
3.22.5.2. Подписывание хранилища пакетов

Можно организовать подписанные хранилища для пакетов IPK и RPM. Для этого нужно включить в local.conf или distro.conf приведенные ниже строки.

INHERIT += "sign_package_feed"
     PACKAGE_FEED_GPG_NAME = "key_name" PACKAGE_FEED_GPG_PASSPHRASE_FILE = "path_to_file_containing_passphrase"

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

Кроме переменных PACKAGE_FEED_GPG_NAME и PACKAGE_FEED_GPG_PASSPHRASE_FILE есть три необязательных переменных, относящихся к подписыванию пакетов:

  • GPG_BIN задает двоичный файл gpg, выполняемый при подписывании пакета;
  • GPG_PATH указывает домашний каталог gpg, используемый при подписывании пакета;
  • PACKAGE_FEED_GPG_SIGNATURE_TYPE задает тип подписи gpg. Переменная применима лишь к хранилищам пакетов RPM и IPK, а возможные значения включают ASC (принято по умолчанию) и BIN.

3.22.6. Тестирование пакетов с помощью ptest

Проверка пакетов (ptest) работает с пакетами, созданными системой сборки OE, на целевой платформе и содержит по меньшей мере два элемента — реальный тест и shell-сценарий (run-ptest) для запуска теста. Включение теста в сценарий запуска не разрешается. Сам тест может быть любым — от shell-сценария, запускающего двоичный файл и проверяющего результат, до сложной системы двоичных файлов для тестирования и файлов данных.

Вывод таста имеет формат, применяемый Automake, — result: testname, где result может принимать значение PASS, FAIL или SKIP, а testname может быть строкой идентификации. Список заданий YP, для которых уже включен ptest, приведен на странице Ptest. Такие задания наследуют класс ptest.

3.22.6.1. Добавление ptest в сборку

Для добавления тестирования пакетов в сборку нужно задать DISTRO_FEATURES и EXTRA_IMAGE_FEATURES в файле local.conf в каталоге сборки, как показано ниже.

     DISTRO_FEATURES_append = " ptest"
     EXTRA_IMAGE_FEATURES += "ptest-pkgs"

По завершении сборки файлы ptest размещаются в каталоге /usr/lib/package/ptest внутри образа (packageимя пакета).

3.22.6.2. Запуск ptest

Пакет ptest-runner устанавливает сценарий, который выполняет все установленные наборы тестов ptest в заданном порядке. Имеет смысл включать этот пакет в образ.

3.22.6.3. Подготовка пакета

Чтобы включить тесты ptest на целевом оборудовании, нужно подготовить задания к сборке.

  • Наследование класса ptest требует включения в задание строки inherit ptest.
  • Создание сценария run-ptest для запуска теста. Сценарий указывается в переменной SRC_URI. Например, для запуска теста dbus сценарий может иметь вид
         #!/bin/sh
         cd test
         make -k runtest-TESTS    
  • Контроль соблюдения зависимостей. Если тест добавляет зависимости при сборке или работе, которых обычно нет для пакета (например, запуск make при тестировании), нужно использовать переменные DEPENDS и RDEPENDS в задании для указания зависимостей. Например зависимость от make при работе задается строкой RDEPENDS_${PN}-ptest += «make».
  • Добавление функции для сборки теста. Не все пакеты поддерживают кросс-компиляцию своих тестов и может потребоваться добавление функции кросс-компиляции в пакет. Многие пакеты на основе Automake компилируют и запускают свои тесты с использованием одной команды, такой как make check. Однако на хосте сборки эта команда создаст и запустит тесты локально, тогда как кросс-компиляция требует сборки пакета на хосте и запуска на целевой системе. Версия Automake из состава YP включает исправления, разделяющие сборку и выполнение. Поэтому для пакетов кросс-компиляция make check выполняется автоматически. Тем не менее, все равно нужно добавить функцию do_compile_ptest для сборки теста в задание.
         do_compile_ptest() {
            oe_runmake buildtest-TESTS
         }    
  • Установка нужной конфигурации (если она нужна для компиляции тестового кода) с помощью функции do_configure_ptest в задании.
  • Установка тестов. Класс ptest автоматически копирует run-ptest в целевую систему, а затем запускает make install-ptest для инициирования тестов. Если этого не достаточно, нужно создать функцию do_install_ptest и обеспечить ее вызов по завершении make install-ptest.

3.22.7. Создание пакетов NPM

NPM является менеджером пакетов для JavaScript. YP поддерживает сборщик NPM (fetcher), который можно применять с devtool для подготовки заданий, создающих пакеты NPM. Имеется два метода создания пакетов NPM с помощью devtool — реестр модулей NPM и код проекта NPM. Можно создавать задания NPM вручную, но с devtool это проще.

3.22.7.1. Требования и предостережения

Перед использованием devtool для создания пакетов NPM нужно выполнить указанные ниже действия.

  • Можно использовать один из двух методов создания пакетов NPM и подход с реестром несколько проще. Однако можно рассмотреть и вариант с проектом поскольку модель может не публиковаться в общедоступном реестре NPM (npm-registry).
  • Следует ознакомиться с devtool.
  • На хосте сборки нужен пакет nodejs-npm, являющийся частью среды OE, который можно получить клонированием репозитория https://github.com/openembedded/meta-openembedded. Путь к локальной копии нужно указать в файле bblayers.conf.
  • devtool не может обнаруживать естественные библиотеки в зависимостях модуля, поэтому нужно вручную добавлять пакеты в задание.
  • При развертывании пакетов NPM devtool не может определить отсутствие нужного пакета на целевой платформе (например, nodejs), поэтому нужно проверять самостоятельно.
  • Хотя NPM может не требоваться для пакета, лучше иметь NPM (nodejs-npm) на целевой платформе.
3.22.7.2. Реестр модулей NPM

Здесь рассматривается пример модуля cute-files, который является программой web-браузера. Нужно знать версию модуля. Первым делом нужно использовать devtool и сборщик NPM для подготовки задания

     $ devtool add "npm://registry.npmjs.org;name=cute-files;version=1.0.2"

Команда devtool add запускает recipetool create и использует тот же URI выборки для загрузки каждой зависимости и деталей лицензирования, когда это возможно. Файл задания достаточно прост и содержит все лицензии, найденные recipetool, а также лицензии из переменных LIC_FILES_CHKSUM. Нужно проверить переменные на предмет значений unknown в поле LICENSE и добавить соответствующую информацию вручную.

Команда recipetool файлы shrinkwrap и lockdown для задания. Файлы shrinkwrap включают версии всех зависимых модулей, но многие пакеты не включают файлов shrinkwrap и recipetool создает их. Можно заменить файл shrinkwrap своим файлом, задав переменную NPM_SHRINKWRAP. Файлы lockdown содержат контрольные суммы каждого модуля, чтобы определить загрузку тех же файлов при сборке задания. Файлы lockdown обеспечивают сохранение зависимостей и сохранение в реестре NPM того же файла.

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

$ devtool edit-recipe cute-files
SUMMARY = "Turn any folder on your computer into a cute file browser, available on the local network."
LICENSE = "BSD-3-Clause & Unknown & MIT & ISC"
LIC_FILES_CHKSUM = "file://LICENSE;md5=71d98c0a1db42956787b1909c74a86ca \
 file://node_modules/content-disposition/LICENSE;md5=c6e0ce1e688c5ff16db06b7259e9cd20 \
 file://node_modules/express/LICENSE;md5=5513c00a5c36cd361da863dd9aa8875d \
 ...

SRC_URI = "npm://registry.npmjs.org;name=cute-files;version=${PV}"
NPM_SHRINKWRAP := "${THISDIR}/${PN}/npm-shrinkwrap.json"
NPM_LOCKDOWN := "${THISDIR}/${PN}/lockdown.json"
inherit npm
# Must be set after inherit npm since that itself sets S
S = "${WORKDIR}/npmpkg"

LICENSE_${PN}-content-disposition = "MIT"
...
LICENSE_${PN}-express = "MIT"
LICENSE_${PN} = "MIT"

В примере следует отметить 3 важных аспекта:

  • SRC_URI применяет схему NPM, поэтому используется сборщик NPM;
  • recipetool собирает данные о всех лицензиях и при отсутствии лицензии для субмодуля перед его именем помещается символ комментария;
  • оператор inherit npm заставляет класс npm упаковывать все модули.

Для сборки пакета cute-files можно воспользоваться командой devtool build cute-files. Следует помнить, что nodejs нужно установить на целевой платформе до пакета. Предположим, что целевая система имеет адрес 192.168.7.2 и введем команду devtool deploy-target -s cute-files root@192.168.7.2 для установки пакета, после чего можно будет протестировать приложение.

Известные проблемы не позволяют просто запустить cute-files как при запуске npm install.

     $ cd /usr/lib/node_modules/cute-files
     $ node cute-files.js

Если в браузере ввести http://192.168.7.2:3000, будет показана приведенная на рисунке страница.


Задание можно найти в каталоге workspace/recipes/cute-files и использовать на любом уровне.

3.22.7.3. Код проекта NPM

Хотя полезно упаковывать модули уже в реестре NPM, добавление проектов node.js более распространено. Этот метод очень похож на использование реестра и команде devtool предоставляется URL исходных файлов. Используя прошлый пример с cute-files, вводим команду devtool add https://github.com/martinaglv/cute-files.git. Эта команда создает задание, очень похожее на задание из предыдущего параграфа, однако переменная SRC_URI имеет вид

     SRC_URI = "git://github.com/martinaglv/cute-files.git;protocol=https \
   npm://registry.npmjs.org;name=commander;version=2.9.0;subdir=node_modules/commander \
   npm://registry.npmjs.org;name=express;version=4.14.0;subdir=node_modules/express \
   npm://registry.npmjs.org;name=content-disposition;version=0.3.0;subdir=node_modules/content-disposition \
   "

Здесь основной модуль берется из репозитория Git, а зависимости — из реестра NPM. В остальном задания совпадают Можно собрать и развернуть пакет в соответствии с предыдущим параграфом.

3.23. Эффективная выборка файлов при сборке

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

3.23.1. Установка эффективных зеркал

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

     SOURCE_MIRROR_URL ?= "file:///home/you/your-download-dir/"
     INHERIT += "own-mirrors"
     BB_GENERATE_MIRROR_TARBALLS = "1"
     # BB_NO_NETWORK = "1"    

Здесь переменная BB_GENERATE_MIRROR_TARBALLS заставляет систему сборки OE создавать файлы репозиториев Git и сохранять их в каталоге DL_DIR. Из соображений производительности такое поведение системы сборки не задано по умолчанию. Можно также использовать переменную PREMIRRORS [3].

3.23.2. Подготовка исходных файлов без сборки

Другим вариантом является предварительная выборка исходных кодов без запуска сборки. Это позволяет избежать проблем с загрузкой и собрать весь исходный код в каталоге build/downloads внутри DL_DIR. Сделать это можно с помощью команды bitbake -c target runall=»fetch». Этот вариант гарантирует наличие всех исходных кодов и возможность сборки даже без доступа в Internet.

3.24. Выбор менеджера инициализации

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

3.24.1. Использование только systemd

В файле конфигурации дистрибутива следует указать

     DISTRO_FEATURES_append = " systemd"
     VIRTUAL-RUNTIME_init_manager = "systemd"    

В первой строке могут присутствовать и другие свойства. Можно также отключить SysVinit с помощью DISTRO_FEATURES_BACKFILL_CONSIDERED += «sysvinit». В результате этого будут удалены ненужные сценарии SysVinit. Для полного удаления сценариев инициализации следует указать VIRTUAL-RUNTIME_initscripts = «».

3.24.2. Systemd для основного образа и SysVinit для восстановления

В этом случае следует включить в файл конфигурации дистрибутива приведенные ниже переменные.

     DISTRO_FEATURES_append = " systemd"
     VIRTUAL-RUNTIME_init_manager = "systemd"    

В этом случае основной образ будет использовать задание packagegroup-core-boot.bb и systemd, а восстановительный (минимальный) не будет применять указанную группу пакетов. Однако можно установить SysVinit и пакеты, поддерживающие systemd и SysVinit.

3.25. Выбор менеджера устройств

YP обеспечивает несколько способов управления менеджером устройств (/dev).

  • Постоянный и заранее заполненный каталог /dev. В этом случае каталог /dev существует всегда и требуется создание узлов для устройств в процесс сборки.
  • Использование devtmpfs с менеджером устройств. В этом случае каталог /dev обеспечивается ядром как файловая система в памяти и автоматически заполняется ядром при работе. Дополнительная настройка узлов для устройств выполняется в пользовательском пространстве менеджером устройств, таким как udev или busybox-mdev.

3.25.1. Использование постоянного заполненного каталога /dev

Для использования статического метода заполнения устройств нужно задать USE_DEVFS = «0». Содержимое получаемого каталога /dev определяется файлом с таблицей устройств. Переменная IMAGE_DEVICE_TABLES задает используемую таблицу и должна быть установлена в файле конфигурации машины или дистрибутива, но можно задать ее и в файле local.conf. По умолчанию применяется IMAGE_DEVICE_TABLES = «device_table-mymachine.txt». Заполнение каталога обеспечивается утилитой makedevs в процессе сборки образа.

3.25.2. Использование devtmpfs и менеджера устройств

Для динамического заполнения устройств нужно использовать USE_DEVFS = «1». При установленной переменной каталог /dev заполняется ядром с помощью devtmpfs, для чего в конфигурации ядра должна быть установлена переменная CONFIG_DEVTMPFS. Созданные devtmpfs устройства принадлежат пользователю root и имеют права доступа 0600.

Для управления узлами устройств можно использовать такие менеджеры устройств, как udev или busybox-mdev. Выбор менеджера задается переменной VIRTUAL-RUNTIME_dev_manager в файле конфигурации машины или дистрибутива или в файле local.conf, как показано ниже.

     VIRTUAL-RUNTIME_dev_manager = "udev"

     # Some alternative values
     # VIRTUAL-RUNTIME_dev_manager = "busybox-mdev"
     # VIRTUAL-RUNTIME_dev_manager = "systemd"    

3.26. Использование внешних SCM

При работе с заданием из внешней системы SCM система сборки OE может уведомлять об изменении заданий в SCM и соберет в результате пакеты, зависящие от новых заданий, используя последнюю версию. Это работает лишь с SCM, где можно получить номер выпуска для изменений. В настоящее время это возможно для репозиториев Apache Subversion (SVN), Git и Bazaar (BZR). Для включения такого режима следует указать в переменной задания PV значение SRCPV, например, PV = «1.2.3+git${SRCPV}», а в файл local.conf нужно добавить строку SRCREV_pn-PN = «${AUTOREV}». PNэто имя задания, для которого нужно включить автоматическое обновление исходного кода. Можно не менять файл local.conf, а добавить в задание строку SRCREV = «${AUTOREV}».

YP включает дистрибутив poky-bleeding с файлом конфигурации, содержащим строку

     require conf/distro/include/poky-floating-revisions.inc

Эта строка добавляет включаемый файл с множеством строк вида

     #SRCREV_pn-opkg-native ?= "${AUTOREV}"
     #SRCREV_pn-opkg-sdk ?= "${AUTOREV}"
     #SRCREV_pn-opkg ?= "${AUTOREV}"
     #SRCREV_pn-opkg-utils-native ?= "${AUTOREV}"
     #SRCREV_pn-opkg-utils ?= "${AUTOREV}"
     SRCREV_pn-gconf-dbus ?= "${AUTOREV}"
     SRCREV_pn-matchbox-common ?= "${AUTOREV}"
     SRCREV_pn-matchbox-config-gtk ?= "${AUTOREV}"
     SRCREV_pn-matchbox-desktop ?= "${AUTOREV}"
     SRCREV_pn-matchbox-keyboard ?= "${AUTOREV}"
     SRCREV_pn-matchbox-panel-2 ?= "${AUTOREV}"
     SRCREV_pn-matchbox-themes-extra ?= "${AUTOREV}"
     SRCREV_pn-matchbox-terminal ?= "${AUTOREV}"
     SRCREV_pn-matchbox-wm ?= "${AUTOREV}"
     SRCREV_pn-settings-daemon ?= "${AUTOREV}"
     SRCREV_pn-screenshot ?= "${AUTOREV}"
          ...

Это позволяет создать дистрибутив с отслеживанием обновления исходного кода для многих пакетов. Однако дистрибутив poky-bleeding не тестируется как другие дистрибутивы и применять его следует с осторожностью.

3.27. Создание корневой файловой системы лишь для чтения

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

3.27.1. Создание корневой файловой системы

Для создания файловой системы без возможности записи к образу просто добавляется свойство read-only-rootfs. Для этого можно указать в задании для образа или в файле local.conf каталога сборки строку IMAGE_FEATURES = «read-only-rootfs» или EXTRA_IMAGE_FEATURES += «read-only-rootfs». Дополнительная информация об использовании этих переменных дана в параграфе 3.2.2. Настройка с помощью IMAGE_FEATURES и EXTRA_IMAGE_FEATURES и описаниях переменных IMAGE_FEATURES и EXTRA_IMAGE_FEATURES.

3.27.2. Сценарии пост-установки

Важно обеспечить выполнение сценариев пост-установки (pkg_postinst) для пакетов, включенных в образ, при создании корневой файловой системы при сборке на хосте, поскольку эти сценарии не смогут работать при первой загрузке на целевой системе. При включенном свойстве read-only-rootfs система сборки проверяет в процессе создания файловой системы выполнение всех сценариев пост-утсановки. Если какой-то из этих сценариев требует запуска после создания файловой системы, сборка завершается отказом. Проверка во время сборки гарантирует отказ сборки, а не первой загрузки на целевой системе.

Большинство сценариев пост-установки, создаваемых системой сборки из состава YP, созданы с возможностью выполнения в процессе создания файловой системы (например, сценарий пост-установки для кэширования шрифтов). Однако при создании своих сценариев нужно обеспечить возможность их работы при создании файловой системы.

Ниже указаны некоторые общие проблемы, возникающие при работе сценариев пост-установки.

  • Не используется $D в начале абсолютного пути. Система сборки определяет $D при создании корневой файловой системы, а при запуске на целевом устройстве значение $D пусто. Это предполагает двойное назначение $D — обеспечения корректности путей на хосте сборки и в целевой системе, а также определение используемой среды для выполнения соответствующих действий.
  • Попытка запуска процессов, относящихся к целевой архитектуре или зависимых от нее. Это можно обойти путем использования естественных инструментов, работающих на хосте сборки для решения тех же задач, или запуска процессов в QEMU с функцией qemu_run_binary.

3.27.3. Области с доступом для записи

При включенном свойстве read-only-rootfs любая попытка записи в корневую файловую систему будет давать отказ. Поэтому нужно обеспечить запись процессов и приложений в иную область, например, /tmp или /var/run.

3.28. Поддержка качества вывода сборки

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

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

3.28.1. Управление историей сборки

История сборки выключена по умолчанию и для включения нужно добавить оператор INHERIT и установить переменную BUILDHISTORY_COMMIT в конце файла conf/local.conf в каталоге сборки.

     INHERIT += "buildhistory"
     BUILDHISTORY_COMMIT = "1"    

Включение истории сборки заставляет систему сборки OE собирать выходную информацию и представлять ее в форме одной фиксации (commit) в локальный репозиторий Git. Включение истории сборки несколько увеличивает время сборки и занимаемое на диске пространство.

3.28.2. Содержимое истории сборки

История сборки хранится в каталоге ${TOPDIR}/buildhistory внутри каталога сборки, как определено в переменной BUILDHISTORY_DIR. На рисунке представлена сокращенная структура истории сборки.


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

3.28.2.1. История сборки пакета

История сборки для каждого пакета включает текстовый файл с парами «имя-значение». Например, файл buildhistory/packages/i586-poky-linux/busybox/busybox/latest содержит приведенные ниже данные.

     PV = 1.22.1
     PR = r32
     RPROVIDES =
     RDEPENDS = glibc (>= 2.20) update-alternatives-opkg
     RRECOMMENDS = busybox-syslog busybox-udhcpc update-rc.d
     PKGSIZE = 540168
     FILES = /usr/bin/* /usr/sbin/* /usr/lib/busybox/* /usr/lib/lib*.so.* \
        /etc /com /var /bin/* /sbin/* /lib/*.so.* /lib/udev/rules.d \
        /usr/lib/udev/rules.d /usr/share/busybox /usr/lib/busybox/* \
        /usr/share/pixmaps /usr/share/applications /usr/share/idl \
        /usr/share/omf /usr/share/sounds /usr/lib/bonobo/servers
     FILELIST = /bin/busybox /bin/busybox.nosuid /bin/busybox.suid /bin/sh \
        /etc/busybox.links.nosuid /etc/busybox.links.suid

Большинство пар соответствует переменным, использованным для создания пакета. Исключением является переменная FILELIST со списком реальных файлов из пакета и PKGSIZE с общим размером файлов пакета в байтах.

Имеется также файл, соответствующий заданию, из которого получен пакет (например, buildhistory/packages/i586-poky-linux/busybox/latest).

     PV = 1.22.1
     PR = r32
     DEPENDS = initscripts kern-tools-native update-rc.d-native \
        virtual/i586-poky-linux-compilerlibs virtual/i586-poky-linux-gcc \
        virtual/libc virtual/update-alternatives
     PACKAGES = busybox-ptest busybox-httpd busybox-udhcpd busybox-udhcpc \
        busybox-syslog busybox-mdev busybox-hwclock busybox-dbg \
        busybox-staticdev busybox-dev busybox-doc busybox-locale busybox

Для заданий, извлеченных из систем контроля версий (например, Git), имеется файл со списком выпусков исходного кода, указанных в задании, и списком реальных выпусков, использованных для сборки. Эти списки могут различаться при установке SRCREV = ${AUTOREV}. Ниже приведен пример из файла buildhistory/packages/qemux86-poky-linux/linux-yocto/latest_srcrev.

     # SRCREV_machine = "38cd560d5022ed2dbd1ab0dca9642e47c98a0aa1"
     SRCREV_machine = "38cd560d5022ed2dbd1ab0dca9642e47c98a0aa1"
     # SRCREV_meta = "a227f20eff056e511d504b2e490f3774ab260d6f"
     SRCREV_meta = "a227f20eff056e511d504b2e490f3774ab260d6f"

Можно использовать команду buildhistory-collect-srcrevs с опцией -a для получения сохраненных значений SRCREV из истории сборки в формате, пригодном для использования в глобальной конфигурации (например, local.conf или включаемый файл дистрибутива) с целью переопределения значений AUTOREV фиксированным набором выпусков. Пример вывода представлен ниже.

     $ buildhistory-collect-srcrevs -a
     # i586-poky-linux
     SRCREV_pn-glibc = "b8079dd0d360648e4e8de48656c5c38972621072"
     SRCREV_pn-glibc-initial = "b8079dd0d360648e4e8de48656c5c38972621072"
     SRCREV_pn-opkg-utils = "53274f087565fd45d8452c5367997ba6a682a37a"
     SRCREV_pn-kmod = "fd56638aed3fe147015bfa10ed4a5f7491303cb4"
     # x86_64-linux
     SRCREV_pn-gtk-doc-stub-native = "1dea266593edb766d6d898c79451ef193eb17cfa"
     SRCREV_pn-dtc-native = "65cc4d2748a2c2e6f27f1cf39e07a5dbabd80ebf"
     SRCREV_pn-update-rc.d-native = "eca680ddf28d024954895f59a241a622dd575c11"
     SRCREV_glibc_pn-cross-localedef-native = "b8079dd0d360648e4e8de48656c5c38972621072"
     SRCREV_localedef_pn-cross-localedef-native = "c833367348d39dad7ba018990bfdaffaec8e9ed3"
     SRCREV_pn-prelink-native = "faa069deec99bf61418d0bab831c83d7c1b797ca"
     SRCREV_pn-opkg-utils-native = "53274f087565fd45d8452c5367997ba6a682a37a"
     SRCREV_pn-kern-tools-native = "23345b8846fe4bd167efdf1bd8a1224b2ba9a5ff"
     SRCREV_pn-kmod-native = "fd56638aed3fe147015bfa10ed4a5f7491303cb4"
     # qemux86-poky-linux
     SRCREV_machine_pn-linux-yocto = "38cd560d5022ed2dbd1ab0dca9642e47c98a0aa1"
     SRCREV_meta_pn-linux-yocto = "a227f20eff056e511d504b2e490f3774ab260d6f"
     # all-poky-linux
     SRCREV_pn-update-rc.d = "eca680ddf28d024954895f59a241a622dd575c11"

Ниже приведены некоторые замечания по использованию команды buildhistory-collect-srcrevs.

  • По умолчанию выводятся только значения, где SRCREV не задана жестко (обычно при использовании AUTOREV). Опция -a задает вывод всех значений SRCREV.
  • Выходные операторы могут не давать эффекта, если где-то в конфигурации системы сборки применены переопределения. Опция -f добавляет форсированные переопределения в каждую строку, если нужно обойти это ограничение.
  • Сценарий не использует особой обработки при сборке для нескольких машин, однако помещает символ комментария перед каждым набором значений, задающим триплет, который уже был показан (например, i586-poky-linux).
3.28.2.2. История сборки образа

Для каждого образа создается набор описанных ниже файлов.

  • image-filesкаталог с выбранными файлами из корневой системы (заданы в BUILDHISTORY_IMAGE_FILES).
  • build-id.txtпонятные человеку сведения о конфигурации сборки и метаданные выпусков исходного кода, а также полный заголовок сборки, выводимый BitBake.
  • *.dotграфы зависимостей для образа, совместимые с graphviz.
  • files-in-image.txtсписок файлов в образе с правами доступа, владельцами, группами, размером и символьными ссылками.
  • image-info.txtтекстовый файл с информацией об образе в виде пар «имя-значение».
  • installed-package-names.txtсписок имен установленных пакетов.
  • installed-package-sizes.txtсписок имен установленных пакетов, упорядоченный по размерам.
  • installed-packages.txtсписок имен установленных пакетов с полными именами.

Информация об установленных пакетах может собираться даже при запрете включения менеджера пакетов в финальный образ. Ниже приведен пример файла image-info.txt.

     DISTRO = poky
     DISTRO_VERSION = 1.7
     USER_CLASSES = buildstats image-mklibs image-prelink
     IMAGE_CLASSES = image_types
     IMAGE_FEATURES = debug-tweaks
     IMAGE_LINGUAS =
     IMAGE_INSTALL = packagegroup-core-boot run-postinsts
     BAD_RECOMMENDATIONS =
     NO_RECOMMENDATIONS =
     PACKAGE_EXCLUDE =
     ROOTFS_POSTPROCESS_COMMAND = write_package_manifest; license_create_manifest; \
        write_image_manifest ; buildhistory_list_installed_image ; \
        buildhistory_get_image_installed ; ssh_allow_empty_password;  \
        postinst_enable_logging; rootfs_update_timestamp ; ssh_disable_dns_lookup ;
     IMAGE_POSTPROCESS_COMMAND =   buildhistory_get_imageinfo ;
     IMAGESIZE = 6900

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

3.28.2.3. Использование истории сборки для получения информации только об образе

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

     INHERIT += "buildhistory"
     BUILDHISTORY_COMMIT = "0"
     BUILDHISTORY_FEATURES = "image"
3.28.2.4. История сборки SDK

Похожая информация собирается в истории и для сборки SDK (например, bitbake -c populate_sdk imagename). Эта информация различается для стандартных и расширяемых SDK. Список файлов истории сборки приведен ниже.

  • files-in-sdk.txtсписок файлов в SDK с правами доступа, владельцами, группами, размером и символьными ссылками для хостовой и целевой части SDK.
  • sdk-info.txtтекстовый файл с информацией об SDK в виде пар «имя-значение».
  • sstate-task-sizes.txtтекстовый файл в виде пар «имя-значение» с данными о размерах групп задач (например, do_populate_sysroot), создаваемый только при сборке расширяемых SDK.
  • sstate-package-sizes.txtтекстовый файл в виде пар «имя-значение» с данными о пакетах с общим состоянием и размерах в SDK, создаваемый только при сборке расширяемых SDK.
  • sdk-filesкаталог с копиями файлов, указанных в BUILDHISTORY_SDK_FILES, если эти файлы имеются в выводе. По умолчанию BUILDHISTORY_SDK_FILES относится к расширяемым SDK, но его можно установить и для стандартных. Файлы conf/local.conf, conf/bblayers.conf, conf/auto.conf, conf/locked-sigs.inc и conf/devtool.conf копируются по умолчанию в этот каталог для расширяемых SDK.
  • В каталоги для хоста и цели включаются перечисленные ниже файлы частей SDK, работающих на хосте и цели. Большая часть этих файлов для расширяемого SDK будет пустой, поскольку расширяемые SDK не состоят из пакетов, как стандартные SDK.
    • depends.dot графы зависимостей для SDK, совместимые с graphviz.
    • installed-package-names.txtсписок имен установленных пакетов.
    • installed-package-sizes.txtсписок имен установленных пакетов, упорядоченный по размерам.
    • installed-packages.txtсписок имен установленных пакетов с полными именами.

Ниже представлен пример файла sdk-info.txt.

     DISTRO = poky
     DISTRO_VERSION = 1.3+snapshot-20130327
     SDK_NAME = poky-glibc-i686-arm
     SDK_VERSION = 1.3+snapshot
     SDKMACHINE =
     SDKIMAGE_FEATURES = dev-pkgs dbg-pkgs
     BAD_RECOMMENDATIONS =
     SDKSIZE = 352712

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

3.28.2.5. Просмотр данных истории сборки

Историю сборки можно посмотреть с помощью команды или через web-интерфейс. Для просмотра изменений (в предположении BUILDHISTORY_COMMIT = «1») можно использовать обычную команду Git, например, git log -p. Следует помнить, что этот метод показывает и несущественные изменений (например, размер пакета). Имеется команда buildhistory-diff, которая обращается к репозиторию Git и выводит существенные различия в удобной форме. Например,

     $ ~/poky/poky/scripts/buildhistory-diff . HEAD^
     Changes to images/qemux86_64/glibc/core-image-minimal (files-in-image.txt):
        /etc/anotherpkg.conf was added
        /sbin/anotherpkg was added
        * (installed-package-names.txt):
        *   anotherpkg was added
     Changes to images/qemux86_64/glibc/core-image-minimal (installed-package-names.txt):
        anotherpkg was added
     packages/qemux86_64-poky-linux/v86d: PACKAGES: added "v86d-extras"
        * PR changed from "r0" to "r1"
        * PV changed from "0.1.10" to "0.1.12"
     packages/qemux86_64-poky-linux/v86d/v86d: PKGSIZE changed from 110579 to 144381 (+30%)
        * PR changed from "r0" to "r1"
        * PV changed from "0.1.10" to "0.1.12"


Для buildhistory-diff нужен пакет GitPython, который можно установить с помощью команды pip3 install GitPython —user или менеджера пакетов (пакет python3-git). Просмотр изменений истории через web-интерфейс описан в файле README (http://git.yoctoproject.org/cgit/cgit.cgi/buildhistory-web/). Пример вывода показан на рисунке.

3.29. Автоматизированное тестирование при работе

Система сборки OE обеспечивает автоматизированные тесты для образов, позволяющие проверить функциональность при работе. Тесты можно запустить в QEMU или на реальном оборудовании. Тесты написаны на языке Python с применениям модуля unittest и большинство из них запускают команды на целевой системе через SSH. Сведения о тестах и инфраструктуре QA в составе YP приведены в разделе Testing and Quality Assurance [3].

3.29.1. Включение тестов

Управление тестами различается для случаев QEMU и реального оборудования, как описано ниже.

3.29.1.1. Включение тестов при выполнении в QEMU

Для запуска тестов нужно выполнить перечисленные ниже операции.

  • Настройка для работы через сеть без sudo.
    • Добавить NOPASSWD для нужного пользователя в файл /etc/sudoers для всех команд или runqemu-ifup. Нужно указать полный путь, поскольку он может меняться для разных копий репозитория источников.
    • В некоторых дистрибутивах нужно также «закомментировать» строку Defaults requiretty в /etc/sudoers.
    • Вручную настроить интерфейс tap в системе.
    • Запустить от имени root сценарий scripts/runqemu-gen-tapdevs, который должен создать список устройств tap. Обычно эта опция выбирается для сред Autobuilder.
      • Обеспечить использование абсолютного пути при вызове сценария с sudo.
      • Для работы сценария нужно собрать задание qemu-helper-native командой bitbake qemu-helper-native.
  • Установка переменной DISPLAY для работы с X-сервером (например, vncserver для машин без монитора).
  • Настройка на межсетевом экране входящих соединений из сети 192.168.7.0/24. Некоторые тесты (например, DNF) запускают сервер HTTP на случайном порту с большим номером, используемый для работы с файлами на целевой системе. Модуль DNF обслуживает ${WORKDIR}/oe-rootfs-repo, поэтому он может запускать команды DNF, требующие, чтобы межсетевой экран хоста пропускал входящие соединения из сети 192.168.7.0/24, которая по умолчанию используется runqemu для устройств tap.
  • Проверка наличия на хосте нужных пакетов:
    • Ubuntu и Debian — sysstat и iproute2;
    • OpenSUSE — sysstat и iproute2;
    • Fedora — sysstat и iproute;
    • CentOS — sysstat и iproute.

После запуска тестов выполняются перечисленные ниже действия.

  1. Копия корневой файловой системы записывается в ${WORKDIR}/testimage.
  2. Образ загружается в QEMU с помощью стандартного сценария runqemu.
  3. По умолчанию используется время ожидания 500 секунд для завершения процесса загрузки и вывода приглашения на вход в систему. Время задает переменная TEST_QEMUBOOT_TIMEOUT в файле local.conf.
  4. После появления приглашения на вход в систему запускается тест. Полный журнал загрузки будет доступен в каталоге ${WORKDIR}/testimage/qemu_boot_log.
  5. Загружаются модули тестов в порядке, заданном переменной TEST_SUITES. Вывод команд, выполняемых через SSH доступен в файле ${WORKDIR}/testimgage/ssh_target_log.
  6. При отсутствии отказов тестирование выполняется до завершения с записью вывода в файл ${WORKDIR}/temp/log.do_testimage.
3.29.1.2. Включение тестов при работе на аппаратной платформе

Система сборки OE может выполнять тесты на реальном оборудовании, а для некоторых устройств можно развернуть образ для предварительного тестирования на устройстве. Для автоматизированного развертывания на устройстве устанавливается первичный (master) образ. Затем при каждом запуске теста выполняются перечисленные операции.

  1. Загружается первичный образ, используемый для записи тестируемого образа во второй раздел.
  2. Устройство перезагружается с помощью внешнего сценария, который нужно создать.
  3. Загружается тестируемый образ.

При запуске тестов (независимо от способа разворачивания образа) устройство предполагается подключенным к сети с известным адресом IP, который может быть статическим или полученным от сервера DHCP. Для запуска тестов на устройстве нужно установить в переменной TEST_TARGET подходящее значение (для QEMU это не требовалось).

  • SimpleRemoteTarget для запуска тестов на целевой системе, в которой уже имеется тестируемый образ и доступна сеть. Этот вариант пригоден для реального устройства или образа, запущенного в QEMU или на иной виртуальной машине.
  • SystemdbootTarget для машин на основе EFI с загрузчиком systemd-boot и установленным core-image-testmaster (или аналогом). Устройство должно быть подключено к сети с поддержкой DHCP и сохранением IP-адреса при перезагрузке. Для этого режима имеются дополнительные требования, описанные в параграфе 3.29.1.3. Выбор SystemdbootTarget.
  • BeagleBoneTarget при разворачивании образов и запуске тестов на устройстве BeagleBone «Black» или оригинальном «White». Описание тестов дано в файле meta-yocto-bsp/lib/oeqa/controllers/beaglebonetarget.py.
  • EdgeRouterTarget при разворачивании образов и запуске тестов на устройстве Ubiquiti Networks EdgeRouter Lite. Описание тестов дано в файле meta-yocto-bsp/lib/oeqa/controllers/edgeroutertarget.py.
  • GrubTarget при разворачивании образов и запуске тестов на ПК с загрузчиком GRUB. Описание тестов дано в файле meta-yocto-bsp/lib/oeqa/controllers/grubtarget.py.
  • your-target при разворачивании образов и запуске тестов на машине с пользовательским уровнем BSP. Для этого нужно добавить модуль Python, определяющий класс цели, в каталог lib/oeqa/controllers/ на своем уровне, а также обеспечить пустой файл __init__.py. Примеры даны в meta-yocto-bsp/lib/oeqa/controllers/.
3.29.1.3. Выбор SystemdbootTarget

При выборе TEST_TARGET = «SystemdbootTarget» нужно выполнить однократную настройку первичного образа.

  1. Установка EFI_PROVIDER = «systemd-boot».
  2. Сборка первичного образа core-image-testmaster. Задание для образа приведено в качестве примера и может быть настроено в соответствии с задачей. Требования к образу приведены ниже.
    • Наследование core-image для установки модулей ядра.
    • Установка обычных утилит Linux, а не busybox (bash, coreutils, tar, gzip, kmod).
    • Применение образа initramfs с настроенным установщиком. Обычно образ создает один раздел rootfs, но здесь применяется образ, создающий определенный набор разделов. Установщик подходит не для всех BSP и может потребоваться создание разделов вручную по описанной ниже схеме.
      • Первый раздел с точкой монтирования /boot и меткой «boot».
      • Основной раздел rootfs для установки образа с точкой монтирования /.
      • раздел с меткой «testrootfs» для разворачивания тестируемого образа.
  3. Установка образа, созданного для целевой системы.

В заключение нужно установить тестируемый образ.

  1. Настройка файла local.conf путем включения приведенных ниже строк.
         IMAGE_FSTYPES += "tar.gz"
         INHERIT += "testimage"
         TEST_TARGET = "SystemdbootTarget"
         TEST_TARGET_IP = "192.168.2.3"    
  2. Сборка тестируемого образа с помощью команды bitbake core-image-sato.
3.29.1.4. Управление питанием

Для большинства аппаратных платформ (кроме SimpleRemoteTarget) возможно управление питанием.

  • Можно использовать TEST_POWERCONTROL_CMD вместе с TEST_POWERCONTROL_EXTRA_ARGS как команду, выполняемую на хосте для управления питанием. Код теста передает один аргумент — off, on или cycle (off, затем on). Например, в файле local.conf можно задать TEST_POWERCONTROL_CMD = «powercontrol.exp test 10.11.12.1 nuc1». В этом случае предполагается, что сценарий выполняет команду ssh test@10.11.12.1 «pyctl nuc1 arg«, затем выполняется сценарий Python для управления питанием с именем nuc1. Нужно настроить TEST_POWERCONTROL_CMD и TEST_POWERCONTROL_EXTRA_ARGS для своей ситуации. Единственным требованием является указание on, off или cycle в качестве последнего аргумента.
  • Когда команда не задана, происходит подключение к устройству через SSH и выполняется обычная команда reboot для перезагрузки устройства. Это хорошо в тех случаях, когда машина действительно перезагружается (тест SSH не дает отказа). Это полезно в простых ситуациях, обычно с одной платой, где время от времени возможно ручное воздействие.

Если оборудование не поддерживает управление питанием, но нужно провести эксперимент с автоматизированным тестированием устройства, можно использовать сценарий dialog-power-control, который выводит диалог, приглашающий выполнить нужную операцию управления питанием. Для этого сценария нужно установить KDialog или Zenity и задать TEST_POWERCONTROL_CMD = «${COREBASE}/scripts/contrib/dialog-power-control».

3.29.1.5. Подключение последовательной консоли

Если тест на целевой машине требует последовательную консоль для взаимодействия с загрузчиком (например, BeagleBoneTarget, EdgeRouterTarget, GrubTarget), нужно указать команду соединения с консолью на целевой машине в переменной TEST_SERIALCONTROL_CMD и возможно в TEST_SERIALCONTROL_EXTRA_ARGS.

Это может быть терминальная программа, если машина подключена к локальному последовательному порту, а также telnet или ssh при удаленном подключении к консоли. Независимо от способа программе нужно просто подключиться к последовательной консоли и перенаправить это соединение на стандартный ввод и вывод, как делает любая терминальная программа. Например, при использовании программы picocom на последовательном порту /dev/ttyUSB0 во скоростью 115200 бит/с можно задать TEST_SERIALCONTROL_CMD = «picocom /dev/ttyUSB0 -b 115200».

Для локальных устройств, где последовательное устройство исчезает при перезагрузке, предоставляется дополнительный сценарий serdevtry, который просто указывается в качестве префикса команды вызова терминала с указанием пути. Например, TEST_SERIALCONTROL_CMD = «${COREBASE}/scripts/contrib/serdevtry picocom -b 115200 /dev/ttyUSB0».

3.29.2. Запуск тестов

Тесты можно запускать автоматически или вручную.

  • Автоматический запуск. Для автоматического запуска теста после создания образа системой сборки OE нужно сначала установить в файле local.conf каталога сборки TESTIMAGE_AUTO = «1», а затем собрать образ. После успешной сборки вводится команда bitbake core-image-sato.
  • Запуск вручную. Для запуска вручную нужно сначала глобально унаследовать класс testimage, включив в файл local.conf строку INHERIT += «testimage», а затем запустить тесты командой bitbake -c testimage image.

Все файлы тестов хранятся в каталоге meta/lib/oeqa/runtime внутри дерева исходных кодов, имена тестов напрямую отображаются на модули Python. Каждый модуль может включать множество тестов, которые обычно группируются по функциональным областям (например, тесты для systemd собраны в модуле meta/lib/oeqa/runtime/systemd.py).

Тесты можно добавить на любой уровень, разместив их в подходящем месте (layer/lib/oeqa/runtime) и добавив его в переменную BBPATH файла local.conf file. Имена модулей не должны совпадать с именами из meta/lib/oeqa/runtime.

Можно изменить набор тестов путем добавления или переопределения переменной TEST_SUITES в local.conf, где каждое имя представляет требуемый для образа тест. Модули из TEST_SUITES не могут быть пропущены, даже когда тест не подходит для образа (например, запуск тестов RPM на образе без rpm). Добавление auto в TEST_SUITES заставляет систему сборки пытаться запустить все подходящие для образа тесты (т. е. каждый модуль может пропустить себя). Порядок тестов в TEST_SUITES важен и зависит от зависимостей между тестами, поэтому тест, зависящий от другого теста, нужно указывать после того, от которого он зависит. Например, поскольку тест ssh зависит от теста ping, следует помещать ssh в список после ping. Класс test не меняет порядок и не контролирует зависимости.

Каждый метод может иметь несколько классов с разными методами тестирования. Применяются правила Python unittest. Ниже указаны некоторые обстоятельства, которые нужно принимать во внимание при запуске тестов.

  • По умолчанию тесты для образа определяется в виде DEFAULT_TEST_SUITES_pn-image = «ping ssh df connman syslog xorg scp vnc date rpm dnf dmesg».
  • Добавление своих тестов в список имеет форму TEST_SUITES_append = » mytest».
  • Конкретный набор тестов запускается в виде TEST_SUITES = «test1 test2 test3».

3.29.3. Экспорт тестов

Можно экспортировать тесты для запуска независимо от системы сборки. Экспорт требуется, если нужно запускать тесты вручную без планировщика. Можно экспортировать лишь тесты, указанные в TEST_SUITES.

Если образ уже собран, нужно проверить наличие в local.conf приведенных ниже строк.

INHERIT +="testexport"
     TEST_TARGET_IP = "IP-address-for-the-test-target" TEST_SERVER_IP = "IP-address-for-the-test-server"

После этого тесты можно экспортировать командой bitbake image -c testexport. Экспортируемые тесты помещаются в каталог tmp/testexport/image области сборки, указываемый переменной TEST_EXPORT_DIR.

Экспортированные тесты можно запускать извне среды сборки, как показано ниже.

$ cd tmp/testexport/image $ ./runexported.py testdata.json  

Ниже приведен пример, показывающий адреса IP и использующий образ core-image-sato:

     INHERIT +="testexport"
     TEST_TARGET_IP = "192.168.7.2"
     TEST_SERVER_IP = "192.168.7.1"    

Тест экспортируется командой bitbake core-image-sato -c testexport и запускается извне, как показано ниже.

     $ cd tmp/testexport/core-image-sato
     $ ./runexported.py testdata.json

3.29.4. Создание новых тестов

Все новые тесты нужно размещать в корректном месте, чтобы система сборки могла найти их. Тесты функций, добавляемых тем или иным уровнем, следует размещать в каталоге layer/lib/oeqa/runtime (при условии обычного расширения переменной BBPATH в файле уровня layer.conf). Следует помнить отмеченные ниже детали.

  • Имена файлов должны напрямую отображаться на имена тестов (модулей).
  • Недопускается использование имен, совпадающих с именами имеющихся тестов.
  • Как минимум в каталоге запуска тестов должен быть пустой файл __init__.py.

Создание нового теста уместно начать с копирования имеющегося (например, syslog.py или gcc.py удобны в качестве образца). Модули тестов могут использовать код из вспомогательных классов meta/lib/oeqa/utils.

Команды оболочки следует структурировать так, чтобы на них можно было полагаться, а при успехе они бы возвращали один код. Следует учитывать необходимость анализа вывода в некоторых случаях. Примеры модулей можно найти в файлах df.py и date.py.

Все классы тестов наследуют oeRuntimeTest из файла meta/lib/oetest.py. Этот базовый класс предлагает некоторые атрибуты, описанные ниже.

3.29.4.1. Методы класса
  • hasPackage(pkg) возвращает True, если пакет pkg имеется в списке установленных в образ, основанном на файле манифеста, создаваемом задачей do_rootfs task.
  • hasFeature(feature) возвращает True если feature имеется в IMAGE_FEATURES или DISTRO_FEATURES.
3.29.4.2. Атрибуты класса
  • pscmd эквивалентна «ps -ef», если procps имеется в образе. В остальных случаях pscmd будет «ps» (busybox).
  • tcконтекст вызванного теста с доступом к перечисленным ниже атрибутам.
    • dхранилище данных BitBake, позволяющие использовать такие вызовы, как oeRuntimeTest.tc.d.getVar(«VIRTUAL-RUNTIME_init_manager»).
    • testslist и testsrequired служат для внутреннего использования и не нужны тестам.
    • filesdirабсолютный путь к meta/lib/oeqa/runtime/files, где содержатся вспомогательные файлы тестов для копирования в целевую систему (такие, как небольшие файлы C для компиляции).
    • targetобъект контроллера целевой системы, используемый для развертывания и запуска определенного образа (например, QemuTarget, SimpleRemote, SystemdbootTarget). Тесты обычно используют приведенные ниже элементы.
      • ip — IP-адрес целевой системы.
      • server_ip — IP-адрес хоста, который обычно используется тестами DNF.
      • run(cmd, timeout=None) единственный, наиболее используемый метод. Команда служит «оболочкой» для ssh root@host «cmd» и возвращает пару (status, output) — код возврата cmd и ее вывод. Необязательный аргумент timeout указывает число секунд, в течение которых тесту следует ожидать возврата cmd. Значение None задает принятый по умолчанию интервал 300 секунд, 0 задает неограниченное ожидание.
      • copy_to(localpath, remotepath) — scp localpath root@ip:remotepath.
      • copy_from(remotepath, localpath) — scp root@host:remotepath localpath.
3.29.4.3. Атрибуты экземпляра

Имеется один атрибут экземпляраtarget, который идентичен атрибуту класса с тем же именем, описанному выше. Этот атрибут существует для экземпляра и класса, поэтому тесты могут использовать в методах экземпляра self.target.run(cmd) вместо oeRuntimeTest.tc.target.run(cmd).

3.29.5. Установка пакетов на тестируемом устройстве без менеджера пакетов

Когда для теста нужен пакет, созданный BitBake, этот пакет можно установить для чего на тестируемом устройстве не требуется менеджер пакетов. Однако потребуется соединение SSH, а целевая система должна использовать класс sshcontrol. Этот метод использует команду scp для копирования файлов между хостом и целью, что ведет к потере прав доступа и специальных атрибутов.

Используется файл JSON для определения требуемых тесту пакетов. Этот файл должен размещаться там же, где находится определяющий тест файл. Кроме того, имя файла должно напрямую отображаться на имя тестового модуля и использовать расширение .json. Файл должен включать объект с именем теста в качестве ключа объекта или массива. Этот объект (массив объектов) использует указанные ниже данные.

  • «pkg» — обязательная строка, указывающая имя устанавливаемого пакета.
  • «rm» — необязательное логическое значение, управляющее удалением пакета после теста (по умолчанию false).
  • «extract» — необязательное логическое значение, управляющее распаковкой формата пакета (по умолчанию false). При значении true пакет не устанавливается автоматически на тестируемом устройстве.

Далее приведен пример файла JSON для теста foo, устанавливающего пакет bar, и теста foobar, устанавливающего пакеты foo и bar. По завершении теста пакеты на устройстве удаляются.

     {
         "foo": {
 "pkg": "bar"
         },
         "foobar": [
 {
     "pkg": "foo",
     "rm": true
 },
 {
     "pkg": "bar",
     "rm": true
 }
         ]
     }

3.30. Средства и методы отладки

Конкретный метод отладки зависит от природы проблемы и области, где возникает ошибка. Стандартные методы отладки на основе сравнение с последним работающим вариантом и проверки внесенных изменений и поэтапным их анализом для поиска источника проблемы применимы в YP как и других системах. Хоть и невозможно детализировать каждый отказ, в этом разделе даны некоторые базовые советы, которые помогут при устранении проблем.

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

3.30.1. Просмотр журналов отказов задач

Журнал задачи можно найти в файле ${WORKDIR}/temp/log.do_taskname. Например, журнал задачи do_compile минимального образа QEMU для машины x86 (qemux86) будет в файле tmp/work/qemux86-poky-linux/core-image-minimal/1.0-r0/temp/log.do_compile. Для просмотра команд BitBake, связанных с журналом, следует обратиться к соответствующему файлу run.do_taskname в том же каталоге. Файлы log.do_taskname и run.do_taskname на деле являются символьными ссылками на файлы log.do_taskname.pid и log.run_taskname.pid, где pid является идентификатором PID выполнявшейся задачи. Символьный ссылки всегда указывают на последние файлы.

3.30.2. Просмотр значений переменных

Иногда нужно узнать значение переменной на этапе анализа BitBake. Это может быть связано с неожиданным поведением проекта. Причиной может быть, например, неудачная попытка изменить переменную. Опция BitBake -e позволяет увидеть значения переменных после анализа файлов конфигурации (local.conf, bblayers.conf, bitbake.conf и т. д.). Команда bitbake -e recipename выведет значения переменных после анализа указанного задания.

Каждое задание имеет свой набор переменных (хранилище данных). После анализа конфигурации делается копия хранилища до начала анализа заданий. Такое копирование предполагает, что набор переменных одного задания не виден другим заданиям. В задании каждая задача имеет доступ к хранилищу данных задания и установленные задачей переменные доступны другим задачам в рамках этого задания.

В выводе команды bitbake -e каждой переменной предшествует информация о способе ее назначения, включая временные значения, которые были переопределены, и установленные флаги (varflags). Это удобно для отладки. Переменные, экспортируемые в среду, указываются с префиксом export в выводе bitbake -e. Например, export CC=»i586-poky-linux-gcc -m32 -march=i586 —sysroot=/home/ulf/poky/build/tmp/sysroots/qemux86″.

Кроме значений переменных по команде bitbake -e или bitbake -e recipe выводятся приведенные ниже данные.

  • Вывод начинается с дерева, где указаны все файлы конфигурации и классы, включенные глобально, с рекурсивным указанием включаемых и наследуемых файлов. Большая часть поведения системы сборки OE (включая поведение обычных задач сборки задания) реализована в классе base и наследуемых им классах, а не в самой программе BitBake.
  • После значений переменных выводятся все функции. Для функций оболочки включенные в них переменные преобразуются. Если функция изменяется путем переопределения или операторов со стилем переопределения, таких как _append и _prepend, выводится окончательная функция.

3.30.3. Просмотр данных пакетов с помощью oe-pkgdata-util

Утилита oe-pkgdata-util позволяет запрашивать PKGDATA_DIR и выводит связанную с пакетом информацию для пакетов, которые уже собраны. Ниже описаны некоторые субкоманды oe-pkgdata-util. В именах пакетов и путях допускается использование обычных шаблонов * и ?.

  • oe-pkgdata-util list-pkgs [pattern] выводит данные о всех или соответствующих шаблону pattern пакетах.
  • oe-pkgdata-util list-pkg-files package … выводит файлы и каталоги указанных пакетов. Другим вариантом просмотра содержимого пакетов является изучение каталога ${WORKDIR}/packages-split в задании для пакета. Этот каталог создается задачей do_package и включает один подкаталог для каждого создаваемого заданием пакета. Для просмотра каталогов ${WORKDIR}/packages-split нужно отключить rm_work при сборке задания.
  • oe-pkgdata-util find-path path … выводит имена всех пакетов, включающих указанные пути. Например, приведенная ниже команда говорит, что файл /usr/share/man/man1/make.1 включен в пакет make-doc.
         $ oe-pkgdata-util find-path /usr/share/man/man1/make.1
         make-doc: /usr/share/man/man1/make.1
  • oe-pkgdata-util lookup-recipe package … выводит имена заданий, создавших указанные пакеты.

Для получения дополнительной информации о командах oe-pkgdata-util можно использовать команды

$ oe-pkgdata-util ‐‐help
     $ oe-pkgdata-util subcommand --help 

3.30.4. Просмотр зависимостей между заданиями и задачами

Иногда бывает сложно понять, почему BitBake хочет собрать другие задания перед сборкой указанного. Информация о зависимостях помогает в этом. Для получения данных о зависимостях задания служит команда bitbake -g recipename, которая выводит в текущий каталог два файла, указанных ниже.

  • pn-buildlistсписок задач и целей, вовлеченных в сборку задания recipename. Вовлеченность означает, что по меньшей мере одна из задач задания нужна при сборке recipename с нуля. Цели, указанные в ASSUME_PROVIDED, не выводятся.
  • task-depends.dotграф зависимостей между задачами.

Граф выводится в формате DOT и может быть преобразован в изображение (например, с помощью dot из Graphviz).

  • Файлы DOT имеют текстовый формат. Граф создается с помощью команды bitbake -g и часто бывает достаточно большим для чтения без специальной очистки (например, опции Bitbake -I) и обработки. Тем не менее, файлы .dot могут быть полезны для получения информации. Например, строка «libxslt.do_configure» -> «libxml2.do_populate_sysroot» в файле task-depends.dot указывает, что задача do_configure в libxslt зависит от задачи do_populate_sysroot в libxml2, которая указана в DEPENDS.
  • Примером обработки файлов .dot является сценарий Python scripts/contrib/graph-tool, который находит и показывает пути между узлами графа.

Другим вариантом просмотра данных о зависимостях служит команда bitbake -g -u taskexp recipename, которая выводит окно графического интерфейса с зависимостями при сборке и работе для заданий, включенных в сборку recipename.

3.30.5. Просмотр зависимостей между переменными задач

Как отмечено в разделе Checksums (Signatures) [6], BitBake пытается автоматически определить, от каких переменных зависит задача, если значения переменных меняются. Это определение обычно надежно, однако в таких ситуациях, как создание имен переменных в процессе работы, может потребоваться вручную указывать зависимости от этих переменных с помощью vardeps, как описано в разделе Variable Flags [6]. Если нет уверенности в автоматическом определении зависимостей переменной для данной задачи, можно посмотреть зависимости, найденные BitBake.

  1. Сборка задания, содержащего задачу по команде bitbake recipename.
  2. Просмотр в каталоге STAMPS_DIR файла данных подписи (sigdata), соответствующего задаче. Файлы sigdata содержат базу данных Python со всеми метаданными, использованными при создании контрольной суммы для задачи. Например, для do_fetch в задании db файл sigdata можно найти в каталоге ${BUILDDIR}/tmp/stamps/i586-poky-linux/db/6.0.30-r1.do_fetch.sigdata.7c048c18222b16ff0bcee2000ef648b1. Для задач, ускоренных через кэш общего состояния (sstate), создается дополнительный файл siginfo в SSTATE_DIR вместе с кэшированным выводом задачи. Файлы siginfo содержат те же данные, что и sigdata.
  3. Ввод команды bitbake-dumpsig для файла sigdata или siginfo. Например, bitbake-dumpsig ${BUILDDIR}/tmp/stamps/i586-poky-linux/db/6.0.30-r1.do_fetch.sigdata.7c048c18222b16ff0bcee2000ef648b1. Вывод этой команды позволяет увидеть строки предполагаемых зависимостей переменных для задачи с учетом рекурсивных зависимостей. Например, Task dependencies: [‘PV’, ‘SRCREV’, ‘SRC_URI’, ‘SRC_URI[md5sum]’, ‘SRC_URI[sha256sum]’, ‘base_do_fetch’]. Функции (например, base_do_fetch) также учитываются в зависимостях переменных и сами зависят от указанных в них переменных. Вывод bitbake-dumpsig включает также значение каждой переменной, список ее зависимостей, и данные BB_HASHBASE_WHITELIST.

Имеется также команда bitbake-diffsigs для сравнения двух файлов siginfo или sigdata, которая может быть полезна при поиске различий между двумя версиями задачи. При вызове команды для одного файла она ведет себя как bitbake-dumpsig. Можно также использовать BitBake для вывода данных подписи без выполнения задачи с помощью опции BitBake ‐‐dump-signatures=SIGNATURE_HANDLER или -S SIGNATURE_HANDLER. Основными значениями SIGNATURE_HANDLER являются none и printdiff, обеспечивающие вывод лишь подписи или сравнение подписи с кэшированной. Использование BitBake с любой из этих опций заставляет BitBake вывести дамп файлов sigdata в каталоге stamps для каждой задачи, которая будет выполняться, без реальной сборки указанного пакета.

3.30.6. Просмотр метаданных, использованных для создания входной подписи

Просмотр метаданных, используемых для создания входной подписи sstate также может помочь при отладке. Эта информация доступна в файлах siginfo каталога SSTATE_DIR. Интерпретация данных описана в предыдущем параграфе. Концепции общего состояния рассмотрены в разделе Shared State [1].

3.30.7. Аннулирование общего состояния для повторного запуска задачи

Система сборки OE использует контрольные суммы и кэш общего состояния для предотвращения ненужного повтора сборки задач. Эту схему называют кодом общего состояния и как все схемы, она обладает некоторыми недостатками. Возможны случаи неявного внесения в код изменений, которые не будут учтены при расчете контрольной суммы. Эти изменения влияют на вывод задачи, но не вызывают код общего состояния в повторной сборке задания. Рассмотрим пример, где инструмент меняет вывод rpmdeps. Результатом изменения должна стать недействительность всех элементов кэша общего состояния для package и package_write_rpm. Однако изменение является внешним (неявным), поэтому записи кэша общего состояния остаются корректными и процесс сборки будет использовать их вместо перезапуска задачи, что может вызвать проблемы.

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

3.30.8. Запуск конкретных задач

Любое задание состоит из набора задач. Стандартный порядок выполнения задач в BitBake имеет вид — do_fetch, do_unpack, do_patch, do_configure, do_compile, do_install, do_package, do_package_write_*, do_build. По умолчанию выполняется задача do_build и все задачи, которые требуется выполнить до нее. Некоторые задачи (например, do_devshell) не входят по умолчанию в цепочку сборки. Для запуска таких задач можно использовать опцию -c в BitBake, например,

     $ bitbake matchbox-desktop -c devshell

Опция -c учитывает зависимости задач и будет заранее запускать все задачи, от которых зависит выполняемая задача (включая задачи из других заданий). Даже при указании задачи вручную с помощью опции -c программа будет запускать лишь те задачи, которые она сочтет нужными. Выбор актуальных задач описан в разделе Stamp Files and the Rerunning of Tasks [1].

Если нужно форсировать запуск устаревшей задачи (например, после внесения вручную изменений в каталог WORKDIR задания), можно воспользоваться опцией -f. Эта опция никогда не требуется при работе с задачей do_devshell, поскольку для этой задачи уже установлен флаг переменной [nostamp]. Ниже приведен пример использования опции -f.

     $ bitbake matchbox-desktop
   ...
     Внесение изменений в рабочий каталог
   ...
     $ bitbake matchbox-desktop -c compile -f
     $ bitbake matchbox-desktop    

Эта последовательность сначала собирает, а затем заново компилирует matchbox-desktop. Последняя команда перезапускает все задачи (в основном, упаковку) поле компиляции. BitBake понимает, что задача do_compile была запущена повторно и это требует перезапуска других задач.

Более короткий способ перезапуска задачи и всех обычных задач сборки задания, зависящих от нее, обеспечивает опция -C (не следует путать с -c). Опция аннулирует данную задачу и запускает задачу do_build, которая используется по умолчанию, и задачи от которых та зависит. Для этого две последних команды в приведенном выше примере следует заменить командой bitbake matchbox-desktop -C compile. Опции -f и -C работают за счет изменения входной контрольной суммы указанной задачи, что косвенно вызывает перезапуск задачи и зависимых от нее задач с использованием обычных механизмов зависимости.

BitBake явно отслеживает изменение задач таким способом и будет выдавать при следующей сборке, включающей такие задачи, предупреждение вида WARNING: /home/ulf/poky/meta/recipes-sato/matchbox-desktop/matchbox-desktop_2.1.bb.do_compile is tainted from a forced run. Цель этого предупреждения заключается в уведомлении пользователя о том, что рабочий каталог и вывод сборки могут не быть «чистыми» как при нормальной сборке. Чтобы избежать таких предупреждений, можно очистить рабочий каталог и заново собрать задание, как показано ниже.

     $ bitbake matchbox-desktop -c clean
     $ bitbake matchbox-desktop

Список задач данного пакета можно посмотреть, запустив задачу do_listtasks командой вида bitbake matchbox-desktop -c listtasks. Результат будет выведен на консоль и записан в файл ${WORKDIR}/temp/log.do_listtasks.

3.30.9. Отладочный вывод BitBake

Отладочный вывод BitBake обеспечивает опция -D, которую можно указывать до 3 раз (-DDD) для расширения подробностей. Команда bitbake -DDD -v targetname может показать, почему программа BitBake выбрала ту или иную версию пакета и провайдера, а также помогает в ситуациях, когда результат представляется неожиданным.

3.30.10. Сборка без зависимостей

Для сборки конкретного задания ( файл.bb) можно применить команду вида bitbake -b somepath/somerecipe.bb. Команда не проверяет зависимостей, поэтому нужно проверить их выполнение. Имя файла можно указать частично и BitBake будет искать уникальное совпадение.

3.30.11. Механизмы протоколирования заданий

YP обеспечивает несколько механизмов протоколирования для отладочного вывода и уведомлений об ошибках и предупреждениях. Ниже перечислены функции Python для протоколирования, обеспечивающие запись в файлы журналов ${T}/log.do_task и на стандартный вывод.

  • bb.plain(msg) записывает msg в журнальный файл и на стандартный вывод.
  • bb.note(msg) записывает «NOTE: msg» в журнальный файл, а также на стандартный вывод (с опцией -v).
  • bb.debug(level, msg) записывает «DEBUG: msg» в журнальный файл, а также на стандартный вывод, если уровень не меньше значения level (см. опцию -D [6]).
  • bb.warn(msg) записывает «WARNING: msg» в журнальный файл и на стандартный вывод.
  • bb.error(msg) записывает «ERROR: msg» в журнальный файл и на стандартный вывод. Вызов этой функции не ведет к отказу задачи.
  • bb.fatal(msg) похожа на bb.error(msg), но ведет к отказу задачи.bb.fatal() создает исключительную ситуацию, означающую, что не нужно помещать return после функции.

Такие же функции протоколирования доступны для функций оболочки bbplain, bbnote, bbdebug, bbwarn, bberror, bbfatal) и реализованы в классе logging (см. каталог meta/classes в дереве исходных кодов).

3.30.11.1. Журналы Python

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

Ниже приведен пример на языке Python для обработки журналов в плане определения числа задач, которые нужно запустить. Дополнительная информация приведена в разделе do_listtasks [3]).

     python do_listtasks() {
         bb.debug(2, "Starting to figure out the task list")
         if noteworthy_condition:
 bb.note("There are 47 tasks to run")
         bb.debug(2, "Got to point xyz")
         if warning_trigger:
 bb.warn("Detected warning_trigger, this might be a problem later.")
         if recoverable_error:
 bb.error("Hit recoverable_error, you really need to fix this!")
         if fatal_error:
 bb.fatal("fatal_error detected, unable to print the task list")
         bb.plain("The tasks present are abc")
         bb.debug(2, "Finished figuring out the tasklist")
     }
3.30.11.2. Журналы Bash

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

     do_my_function() {
         bbdebug 2 "Running do_my_function"
         if [ exceptional_condition ]; then
 bbnote "Hit exceptional_condition"
         fi
         bbdebug 2  "Got to point xyz"
         if [ warning_trigger ]; then
 bbwarn "Detected warning_trigger, this might cause a problem later."
         fi
         if [ recoverable_error ]; then
 bberror "Hit recoverable_error, correcting"
         fi
         if [ fatal_error ]; then
 bbfatal "fatal_error detected"
         fi
         bbdebug 2 "Completed do_my_function"
     }

3.30.12. Отладка конфликтов параллельной сборки

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

Если конфликт не удается исправить, можно попытаться сбросить PARALLEL_MAKE или PARALLEL_MAKEINST.

3.30.12.1. Отказы

Предположим, например, что собирается образ, который зависит от пакета neard, и при сборке BitBake сталкивается с проблемой, выводя показанные ниже сообщения (строки вывода дополнительно разбиты для удобства восприятия).

| DEBUG: SITE files ['endian-little', 'bit-32', 'ix86-common', 'common-linux', 'common-glibc', 'i586-linux', 'common']
| DEBUG: Executing shell function do_compile
| NOTE: make -j 16
| make --no-print-directory all-am
| /bin/mkdir -p include/near
| /bin/mkdir -p include/near
| /bin/mkdir -p include/near
| ln -s /home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/work/i586-poky-linux/neard/
  0.14-r0/neard-0.14/include/types.h include/near/types.h
| ln -s /home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/work/i586-poky-linux/neard/
  0.14-r0/neard-0.14/include/log.h include/near/log.h
| ln -s /home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/work/i586-poky-linux/neard/
  0.14-r0/neard-0.14/include/plugin.h include/near/plugin.h
| /bin/mkdir -p include/near
| /bin/mkdir -p include/near
| /bin/mkdir -p include/near
| ln -s /home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/work/i586-poky-linux/neard/
  0.14-r0/neard-0.14/include/tag.h include/near/tag.h
| /bin/mkdir -p include/near
| ln -s /home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/work/i586-poky-linux/neard/
  0.14-r0/neard-0.14/include/adapter.h include/near/adapter.h
| /bin/mkdir -p include/near
| ln -s /home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/work/i586-poky-linux/neard/
  0.14-r0/neard-0.14/include/ndef.h include/near/ndef.h
| ln -s /home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/work/i586-poky-linux/neard/
  0.14-r0/neard-0.14/include/tlv.h include/near/tlv.h
| /bin/mkdir -p include/near
| /bin/mkdir -p include/near
| ln -s /home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/work/i586-poky-linux/neard/
  0.14-r0/neard-0.14/include/setting.h include/near/setting.h
| /bin/mkdir -p include/near
| /bin/mkdir -p include/near
| /bin/mkdir -p include/near
| ln -s /home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/work/i586-poky-linux/neard/
  0.14-r0/neard-0.14/include/device.h include/near/device.h
| ln -s /home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/work/i586-poky-linux/neard/
  0.14-r0/neard-0.14/include/nfc_copy.h include/near/nfc_copy.h
| ln -s /home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/work/i586-poky-linux/neard/
  0.14-r0/neard-0.14/include/snep.h include/near/snep.h
| ln -s /home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/work/i586-poky-linux/neard/
  0.14-r0/neard-0.14/include/version.h include/near/version.h
| ln -s /home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/work/i586-poky-linux/neard/
  0.14-r0/neard-0.14/include/dbus.h include/near/dbus.h
| ./src/genbuiltin nfctype1 nfctype2 nfctype3 nfctype4 p2p > src/builtin.h
| i586-poky-linux-gcc  -m32 -march=i586 --sysroot=/home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/
  build/build/tmp/sysroots/qemux86 -DHAVE_CONFIG_H -I. -I./include -I./src -I./gdbus  -I/home/pokybuild/
  yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/sysroots/qemux86/usr/include/glib-2.0
  -I/home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/tmp/sysroots/qemux86/usr/
  lib/glib-2.0/include  -I/home/pokybuild/yocto-autobuilder/yocto-slave/nightly-x86/build/build/
  tmp/sysroots/qemux86/usr/include/dbus-1.0 -I/home/pokybuild/yocto-autobuilder/yocto-slave/
  nightly-x86/build/build/tmp/sysroots/qemux86/usr/lib/dbus-1.0/include  -I/home/pokybuild/yocto-autobuilder/
  yocto-slave/nightly-x86/build/build/tmp/sysroots/qemux86/usr/include/libnl3
  -DNEAR_PLUGIN_BUILTIN -DPLUGINDIR=\""/usr/lib/near/plugins"\"
  -DCONFIGDIR=\""/etc/neard\"" -O2 -pipe -g -feliminate-unused-debug-types -c
  -o tools/snep-send.o tools/snep-send.c
| In file included from tools/snep-send.c:16:0:
| tools/../src/near.h:41:23: fatal error: near/dbus.h: No such file or directory
|  #include <near/dbus.h>
|                        ^
| compilation terminated.
| make[1]: *** [tools/snep-send.o] Error 1
| make[1]: *** Waiting for unfinished jobs....
| make: *** [all] Error 2
| ERROR: oe_runmake failed
3.30.12.2. Воспроизведение ошибок

Конфликты при параллельной сборке могут не возникать каждый раз, поэтому нужен способ воспроизведения таких ошибок. В приведенном ниже примере компиляция пакета neard вызывает проблему. Поэтому сначала нужно собрать neard локально. Перед началом сборки в переменной PARALLEL_MAKE файла local.conf устанавливается большое значение (например, «-j 20»), что повысит вероятность возникновения ошибки. Далее выполняется сборка по команде bitbake neard, а по ее завершении запускается сборка командой bitbake neard -c devshell (см. раздел 3.8. Использование среды devshell). В среде devshell вводятся команды

     $ make clean
     $ make tools/snep-send.o

Это позволит четко увидеть отказ. В данном случае отсутствует зависимость neard для цели Makefile, как можно видеть из сокращенного вывода, представленного ниже.

     i586-poky-linux-gcc  -m32 -march=i586 --sysroot=/home/scott-lenovo/......
        ...
     tools/snep-send.c
     In file included from tools/snep-send.c:16:0:
     tools/../src/near.h:41:23: fatal error: near/dbus.h: No such file or directory
      #include <near/dbus.h>
           ^
     compilation terminated.
     make: *** [tools/snep-send.o] Error 1
     $
3.30.12.3. Подготовка исправлений

Поскольку отсутствует зависимость для цели Makefile, нужно исправить файл Makefile.am, создаваемый из Makefile.in. Можно использовать Quilt для создания patch-файла (см. раздел 3.7. Использование Quilt).

     $ quilt new parallelmake.patch
     Patch patches/parallelmake.patch is now on top
     $ quilt add Makefile.am
     File Makefile.am added to patch patches/parallelmake.patch

Здесь нужно отредактировать файл Makefile.am для добавления нужной зависимости. Например, это может быть строка вида

     tools/snep-send.$(OBJEXT): include/near/dbus.h

После редактирования файла нужно создать patch-файл с помощью команды

     $ quilt refresh
     Refreshed patch patches/parallelmake.patch

Полученный файл исправления нужно добавить в каталог задания командой вида

     $ cp patches/parallelmake.patch poky/meta/recipes-connectivity/neard/neard

В заключение нужно применить правки к сборке задания neard (neard-0.14.bb), чтобы оператор SRC_URI включал patch-файл. Переменная в результате будет иметь вид

     SRC_URI = "${KERNELORG_MIRROR}/linux/network/nfc/${BPN}-${PV}.tar.xz \
    file://neard.in \
    file://neard.service.in \
    file://parallelmake.patch \
   "

После этого можно завершить работу с devshell командой exit.

3.30.12.4. Тестирование сборки

После внесений всех исправления можно повторить локальную сборку командой bitbake neard и результат должен быть положительным. Затем можно снова открыть devshell и повторить очистку и сборку, как показано ниже.

     $ bitbake neard -c devshell
     $ make clean
     $ make tools/snep-send.o

Проблем возникать не должно. После внесения всех корректировок их следует зафиксировать для задания в OE-Core и восходящем репозитории, чтобы проблема не повторялась у других (см. параграф 3.31.2. Представление изменений в YP).

3.30.13. Удаленная отладка с помощью GDB

GDB2 позволяет проверять запущенные программы с целью поиска и исправления неполадок, а также выполнять анализ данных после отказа программ. GDB доступен в составе YP и по умолчанию устанавливается в образах SDK, описание которых приведено в разделе Images [3]. Описание GDB доступно на странице http://sourceware.org/gdb/. Для более эффективной работы следует установить отладочные (-dbg) пакеты для приложений, которые планируется отлаживать. Это сделает доступными отладочные символы и сделает вывод более информативным.

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

Поскольку хост GDB отвечает за загрузку и обработку отладочной информации, для отладки нужно убедиться, что этот хост имеет доступ к двоичным файлам с отладочными символами, а также обеспечить компиляцию для целевой платформы без оптимизации. Хост GDB также должен иметь локальный доступ ко всем библиотекам, используемым отладочной программой. Поскольку для gdbserver отладочная информация локально не нужна, ее можно исключить из двоичных файлов для целевой системы. Однако для соответствия с двоичными файлами на хосте отладки компиляция должна выполняться без оптимизации. В соответствии с документацией GDB будем называть двоичный файл на целевой системе «подчиненным» (inferior). Ниже описан процесс удаленной отладки с использованием GDB.

  1. Настройка системы сборки для создания отладочной файловой системы. В файле local.conf следует указать
         IMAGE_GEN_DEBUGFS = "1"
         IMAGE_FSTYPES_DEBUGFS = "tar.bz2"

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

  2. Настройка системы для включения gdbserver на удаленной файловой системе. В файл local.conf или задание для образа нужно включить строку IMAGE_INSTALL_append = “ gdbserver», которая обеспечит сервер.
  3. Сборка среды для создания образа и сопровождающей отладочной файловой системы командой bitbake image. Сборку кросс-компоненты GDB и ее подготовку для отладки лучше всего выполнить путем сборки SDK с помощью команды bitbake -c populate_sdk image. Другим вариантом является сборка минимального инструментария, соответствующего целевой системе. Этот вариант более компактный и реализуется командой bitbake meta-toolchain.Еще один метод заключается в автономной сборке GDB по команде bitbake gdb-cross-architecture. Это создает временную копию cross-gdb, которую можно использовать для отладки. Этот решение наиболее быстрое, но два предыдущих более эффективны при продолжительном использовании отладчика. При запуске gdb-cross, система сборки OE предложит реальный образ (например, gdb-cross-i586).
  4. Установка debugfs, как показано ниже.
    $ mkdir debugfs
         $ cd debugfs
         $ tar xvfj build-dir/tmp-glibc/deploy/images/machine/image.rootfs.tar.bz2 $ tar xvfj build-dir/tmp-glibc/deploy/images/machine/image-dbg.rootfs.tar.bz2
  5. Установка GDB. Установите SDK (в случае его использования) и выполните сценарий настройки среды. Если применялась система сборки, GDB будет в каталоге build-dir/tmp/sysroots/host/usr/bin/architecture/architecture-gdb
  6. Загрузка целевой системы. В случае использования QEMU следует прочесть документацию QEMU. Проверьте доступ хоста к целевой системе по протоколу TCP.
  7. Отладка программы включает запуск gdbserver на целевой системе и GDB на хосте отладки. В приведенном ниже примере отлаживается пакет gzip
         root@qemux86:~# gdbserver localhost:1234 /bin/gzip —help

    Опции gdbserver описаны в документации GDB Server. После запуска gdbserver нужно запустить GDB на хосте отладки и настроить для отладчика соединение с целевой системой, как показано ниже.

    $ cd directory-holding-the-debugfs-directory $ arch-gdb (gdb) set sysroot debugfs (gdb) set substitute-path /usr/src/debug debugfs/usr/src/debug (gdb) target remote IP-of-target:1234

    После этого все остальное должно загружаться автоматически (двоичные файлы, символы и заголовки). Команда GDB set в примере может быть включена в пользовательский файл ~/.gdbinit и при запуске GDB будут выполнены остальные команды из файла.

  8. Развертывание без пересборки образа. Во многих случаях при отладке может потребоваться быстрое развертывание нового двоичного файла в целевой системе без пересборки образа целиком. Одним из вариантов решения этой задачи является просто сборка нужной компоненты и копирование файлов непосредственно в debugfs целевой системы и хоста отладки. Например,
    $ bitbake bash
         $ bitbake -c devshell bash
         $ cd ..
         $ scp packages-split/bash/bin/bash target:/bin/bash $ cp -a packages-split/bash-dbg/* path/debugfs

3.30.14. Отладка на целевой платформе с помощью GDB

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

  1. Установить GDB на целевой платформе, путем добавления в конфигурацию строки IMAGE_INSTALL_append = » gdb» или IMAGE_FEATURES_append = » tools-debug».
  2. Обеспечить наличие отладочных символов, например, с помощью строки IMAGE_INSTALL_append = » packagename-dbg» или IMAGE_FEATURES_append = » dbg-pkgs».

Для повышения точности отладочной информации можно снизить уровень оптимизации, используемый компилятором. Например, можно добавить в файл local.conf строку DEBUG_BUILD = «1», что снизит уровень оптимизации с FULL_OPTIMIZATION = «-O2» до DEBUG_OPTIMIZATION = «-O -fno-omit-frame-pointer». Это одновременно снизит производительность приложений, поэтому по завершении отладки следует восстановить оптимизацию.

3.30.15. Рекомендации по отладке

При добавлении пакетов нужно отслеживать появление нежелательных элементов в командах компилятора. Например, это могут быть ссылки на локальные файловые системы, такие как /usr/lib/ или /usr/include/. Если нужно исключить при загрузке заставку psplash, следует добавить psplash=false в командную строку ядра. Это позволит видеть консольный вывод. Можно также переключить виртуальную консоль (например, Fn+-> или Fn+<- на Zaurus).

Удаление TMPDIR (обычно tmp/ в каталоге сборки) часто решает временные проблемы сборки. Это не влечет значительных издержек, поскольку вывод задач кэшируется в SSTATE_DIR (обычно sstate-cache/ в каталоге сборки). Однако это может быть лишь обходом, а не решением проблемы. Поэтому неплохо поискать решение до удаления каталога.

Понимание практического применения свойства (функции) в задании очень важно, поэтому рекомендуется настроить тот или иной метод поиска в файлах. Например, можно использовать приведенную ниже shell-функцию на основе GNU Grep, которая выполняет рекурсивный поиск теста в связанных с заданиями файлах, пропуская двоичные файлы, каталоги .git и каталог сборки (в предположении, что его имя начинается с build).

     g() {
         grep -Ir \
  --exclude-dir=.git \
  --exclude-dir='build*' \
  --include='*.bb*' \
  --include='*.inc*' \
  --include='*.conf*' \
  --include='*.py*' \
  "$@"
     }

Ниже приведено несколько примеров использования функции.

     $ g FOO    # рекурсивный поиск FOO
     $ g -i foo # рекурсивный поиск  foo без учета регистра
     $ g -w FOO # рекурсивный поиск FOO как слова с игнорированием FOOBAR

Если поиск информации о работе функции требует слишком много времени, это может говорить о необходимости расширить или улучшить документацию. В таких случаях уместно сообщить об ошибке с использованием YP Bugzilla. Работа с этим ресурсом описана на странице YP Bugzilla wiki и в параграфе 3.31.1. Фиксация ошибок в YP. В руководствах может не быть описания переменных, которые являются сугубо внутренними и имеют ограниченную область действия (например, переменные, используемые внутри одного файла .bbclass).

3.31. Внесение изменений в YP

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

3.31.1. Фиксация ошибок в YP

Для сообщений о дефектах (ошибках) YP служит ресурс YP Bugzilla, информацию о котором можно найти в разделе Yocto Project Bugzilla [3]. Описание работы с ресурсом имеется на странице YP Bugzilla wiki. Ниже кратко описаны этапы информирования об ошибках.

  1. Открыть страницу YP Bugzilla.
  2. Выбрать ссылку File a Bug для ввода информации об ошибке.
  3. Выбрать подходящие варианты Classification, Product и Component для информации об ошибке. Ошибки YP делятся на несколько категорий, включающих разную продукцию и компоненты. Например, для ошибки на уровне meta-intel следует выбрать Build System, Metadata & Runtime, BSPs и bsps-meta-intel.
  4. Выбрать Version для YP в соответствии с версией, где найдена ошибка (например, 2.7.1).
  5. Определить и выбрать важность (Severity) ошибки.
  6. Выбрать оборудование (Hardware), с которым связана ошибка.
  7. Выбрать архитектуру (Architecture), с которой связана ошибка.
  8. Выбрать пункт изменения документации (Documentation change) для ошибки. Если влияние ошибки на документацию не понятно, следует выбрать Don’t Know.
  9. Представить краткое описание (Summary) ошибки в одну или две строки.
  10. Представить подробное описание ошибки (Description), указав детали контекста, поведение, вывод и т. п. Здесь можно присоединить файлы с информацией, используя кнопку Add an attachment.
  11. Нажать кнопку Submit Bug для фиксации сообщения, которому будет присвоен номер Bugzilla, а информация будет сохранена в системе отслеживания ошибок.

Полученные сообщения обрабатывает команда YP Bug Triage Team, присваивая ему дополнительные атрибуты (например, приоритет). Вы будете считаться «подателем» (Submitter) сообщения при всех последующих контактах. Bugzilla автоматически будет уведомлять по электронной почте о всех событиях, связанных с обработкой сообщения.

3.31.2. Представление изменений в YP

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

YP использует списки рассылки и рабочий процесс на основе исправления (patch), похожие на процессы для ядра Linux, но с существенными отличиями. Имеются специальные списки рассылки для представления правок. Сообщения из этих списков просматриваются и обрабатываются сопровождающими и нужно выбрать список в соответствии с размещением кода, который вы хотите изменить. Каждая компонента (например, уровень) должна включать файл README, указывающий, куда направить изменения и как их следует обрабатывать.

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

Репозиторий poky, являющийся эталонной средой сборки YP, является гибридным и состоит из нескольких частей (BitBake, Metadata, документация и т. п.), созданных с помощью инструмента combo-layer. Отправка изменений зависит от компонент, как указано ниже.

  • Core Metadata. Отправляйте правки в список рассылки openembedded-core. Например, в этот список следует отправлять исправления для каталогов meta или scripts.
  • BitBake. Отправляйте правки в список рассылки bitbake-devel.
  • meta-*. Отправляйте правки в список рассылки poky.

Для изменений на других уровнях репозитория YP (yoctoproject.org), в инструментах и документации YP следует направлять правки в рассылку YP. Иногда конкретный список указан в документации уровня и следует применять его.

Для дополнительных заданий, не вписывающихся в основные метаданные, следует определить уровень, к которому относится задание, и представить правки в соответствии с документацией этого уровня (например, README). При наличии сомнений можно задать вопрос в общей рассылке Yocto или openembedded-devel.

Можно также отправить изменения в восходящий репозиторий и попросить сопровождающего внести их. Эти процедуры описаны в разделе Git Workflows and the Yocto Project [1].

В OpenEmbedded-Core имеется два тестовых репозитория:

  • ветвь «ross/mut» дерево mut (master-under-test) в репозитории poky-contrib источников YP;
  • ветвь «master-next» branch является частью основного репозитория poky в репозитории источников YP.

Сопровождающие используют эти ветви для тестирования предложений перед включением правок. Включение правки в одну из этих ветвей позволяет получить представление о состоянии предложенных правок.

Эта система несовершенна и изменения могут иногда теряться в общем потоке. Запрос о статусе исправления или изменения является вполне уместным, если на предложение не было отклика. В YP планируется использование Patchwork для отслеживания статуса правок и автоматического предварительного просмотра.

3.31.2.1. Использование сценариев для представления изменений

Описанная здесь процедура служит для внесения изменений в восходящий репозиторий Git «contrib». Базовая информация о работе с репозиториями представлена в Git Community Book.

  1. Внесите изменения локально в свой репозиторий Git. Изменения следует делать компактными, контролируемыми и изолированными. Компактность и изолированность изменений упрощает их просмотр, слияние и перебазирование, а также позволяет сохранять историю изменений.
  2. Добавьте свои изменения с помощью команды git add для каждого измененного файла.
  3. Зафиксируйте изменения с помощью команды git commit. Данные фиксации должны соответствовать стандартным соглашениям, приведенным ниже.Обязательно включите строку «Signed-off-by:», как это требуется для ядра Linux. Добавление строки означает, что податель согласен с Developer’s Certificate of Origin 1.1, текст которого приведен ниже.Сертификат происхождения для разработчика, версия 1.1Внося свой вклад в проект, я подтверждаю указанное ниже.
      1. Вклад полностью или частично создан мной и я имею право представить его в соответствии с лицензией для открытого кода, указанной в файле.
      2. Или вклад основан на предыдущей работе, которая, насколько мне известно, покрывается подходящей лицензией для открытого кода и я имею право в соответствии с этой лицензией представить эту работу с изменениями, независимо от того, созданы ли они полностью мной, на условиях той же лицензии (если мне не разрешено применять иную лицензию), которая указана в файле.
      3. Вклад был предоставлен мне напрямую другим лицом, которое подтвердило пп. (a), (b) или (c), и я не менял его.
      4. Я понимаю и согласен с тем, что этот проект и вклад являются общедоступными и запись вклада (включая все предоставленные мной персональные данные) хранится в течение неопределенного времени и может распространяться в соответствии с этим проектом и лицензиями для открытого кода.

Представьте краткое описание изменений в 1 строку (если требуется более полное описание, его следует включить в тело сообщения). Краткое описание обычно выводится в коротком списке изменений. Если изменения относятся к заданию, следует указать имя задания в качестве префикса краткого описания. В остальных случаях следует указывать в качестве префикса сокращенный путь к измененному файлу.

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

Если изменение связано с конкретной ошибкой, для которой уже имеется идентификатор отслеживания (bug-tracking ID), следует включить этот идентификатор в подробное описание. Например, в YP применяется соглашение для указания ошибок и фиксациям с устранением конкретной ошибки следует использовать в начале подробного описания строку Fixes [YOCTO #bug-id].

  1. Поместите свои фиксации в репозиторий Contrib, если у вас есть право записи в него.
    $ git push upstream_remote_repo local_branch_name

    Предположим, что у вас есть право добавления в восходящий репозиторий meta-intel-contrib и вы работаете с локальной ветвью your_name/README. Команда git push meta-intel-contrib your_name/README поместит выши локальные фиксации в в репозиторий meta-intel-contrib (ветвь your_name/README).

  2. Определить, кого следует уведомить. Это может быть сопровождающий или список рассылки, определенный одним из указанных ниже способов.
    1. Файл сопровождения maintainers.inc в каталоге meta/conf/distro/include дерева исходных кодов.
    2. Поиск по файлам с помощью команды git shortlog — filename, выводящей список фиксаций для указанного файла. Список не упорядочен, но включает всех, кто представлял фиксации.
    3. Просмотр списков рассылки YP и др., перечисленных в разделе Mailing lists [3].
  3. Сделайте запрос на извлечение. Сообщите сопровождающему или в список рассылки сообщение об отправке изменений, передав запрос на извлечение.YP включает два сценария для создания и отправки запросов — create-pull-request и send-pull-request. Эти сценарии хранятся в каталоге scripts дерева исходных кодов (например, ~/poky/scripts). Сценарии корректно формируют запросы без добавления пробелов и тегов HTML. Сопровождающему, который получит запрос напрямую или через список рассылки, сможет сохранить и применить изменения непосредственно из почтового сообщения. Такой метод отправки является предпочтительным.Сначала создается запрос на извлечение. Например, команда ~/poky/scripts/create-pull-request -u meta-intel-contrib -s «Updated Manual Section Reference in README» запускает сценарий, указывает каталог восходящего репозитория для записи изменений (contrib) и задает строку темы в создаваемых patch-файлах. Запуск сценария создает файлы правок *.patch в каталоге pull-PID внутри текущего каталога. Одним из файлов является сопроводительное письмо.Перед использованием сценария send-pull-request нужно отредактировать сопроводительное письмо, указав сведения об изменениях. Затем можно отправить запрос на извлечение. Например, команда ~/poky/scripts/send-pull-request -p ~/meta-intel/pull-10565 -t meta-intel@yoctoproject.org запускает сценарий и указывает каталог исправления и адрес электронной почты для отправки. Сценарий является интерактивным и нужно следовать выводимым на экран инструкциям.

    Справка об использовании сценариев выводится при указании опции -h.

         $ poky/scripts/create-pull-request -h
         $ poky/scripts/send-pull-request -h
3.31.2.2. Использование электронной почты для представления изменений

Можно представлять изменения с помощью электронной почты, отправляя их в соответствующий список рассылки (см. раздел Mailing Lists [3]), как описано ниже.

  1. Внесите изменения локально в свой репозиторий Git. Изменения следует делать компактными, контролируемыми и изолированными. Компактность и изолированность изменений упрощает их просмотр, слияние и перебазирование, а также позволяет сохранять историю изменений.
  2. Добавьте свои изменения с помощью команды git add для каждого измененного файла.
  3. Зафиксируйте изменения с помощью команды git commit —signoff. Опция —signoff указывает, что изменения внесены вами и подтверждает DCO3, как описано выше. Данные фиксации должны соответствовать стандартным соглашениям, описанным в п. 3 предыдущего параграфа.
  4. Формат представлениясообщение электронной почты, создаваемое с помощью команды git format-patch. При вызове команды нужно указать список выпусков или число правок (patch). Например, любая из команда git format-patch -1 и git format-patch HEAD~ берет последнюю одиночную фиксацию (commit) и форматирует ее как почтовое сообщение в текущем каталоге. После выполнения команды в текущем каталоге будут созданы нумерованные файлы .patch для представления. При наличии нескольких patch-файлов следует указывать в команде опцию —cover, которая создает сопроводительное письмо, как первый patch-файл серии. Это письмо затем можно отредактировать для описания серии правок. Информация о команде git format-patch выводится по команде man git-format-patch. Если предполагается частое представление правок для IYP или OE, можно запросить область contrib и связанные с этим права.
  5. Импорт файлов в почтовый клиент с помощью команды git send-email. Для этого на хосте должна быть установлен и должным образом настроен соответствующий пакет Git Ubuntu, Debian и Fedora это git-email). Команда git send-email передает сообщение с использованием локального или удаленного агента MTA4, такого как msmtp, sendmail, или через прямую настройку в конфигурационном файле Git ~/.gitconfig. Если правки представляются только по электронной почте, важно отправлять их без пробелов и тегов HTML. Сопровождающему, который получит сообщение нужно его сохранить и применить прямо из почты. Хорошим способом проверки корректности сообщения служит отправка его по своему адресу для тестового сохранения и применения. Команда git send-email является предпочтительным методом отправки patch-файлов по электронной почте, поскольку нет риска появления в сообщении ненужных пробелов, которые могут вносить почтовые клиенты. Команда имеет опции для указания получателей и дополнительного редактирования сообщения. Сведения об опциях можно получить с помощью команды man git-send-email.

3.32. Работа с лицензиями

Как отмечено в разделе Licensing [1], проекты с открытым кодом доступны для всех и могут использовать разные лицензии. Здесь описаны механизмы, используемые системой сборки OE для отслеживания изменений в текстах лицензий, и поддержка лицензирования открытого кода в течение жизненного цикла проекта. Рассмотрено также использование в заданиях коммерческих лицензий, которое по умолчанию отключено.

3.32.1. Отслеживание изменений в лицензиях

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

3.32.1.1. Указание переменной LIC_FILES_CHKSUM

Переменная LIC_FILES_CHKSUM содержит контрольные суммы текста лицензий в исходном коде задания.

     LIC_FILES_CHKSUM = "file://COPYING;md5=xxxx \
 file://licfile1.txt;beginline=5;endline=29;md5=yyyy \
 file://licfile2.txt;endline=50;md5=zzzz \
 ..."
  • При использовании beginline и endline следует учитывать, что нумерация строк начинается с 1, а не с 0. Начальная и конечная строка учитываются в контрольной сумме, т. е. в примере будут учитываться строки 1 — 29 в файле licfile1.txt и 1 — 50 в файле licfile2.txt.
  • При несоответствии контрольной суммы указанная часть текста лицензии включается в сообщение QA, что позволяет проверить начало и конец учитываемого текста.

Система сборки использует переменную S в качестве принятого по умолчанию каталога при поиске файлов из LIC_FILES_CHKSUM. В примере используются файлы текущего каталога. Рассмотрим еще один пример.

     LIC_FILES_CHKSUM = "file://src/ls.c;beginline=5;endline=16;\
     md5=bb14ed3c4cda583abc85401304b5cd4e"
     LIC_FILES_CHKSUM = "file://${WORKDIR}/license.html;md5=5c94767cedb5d6987c902ac850ded2c6"

Первая строка указывает файл ${S}/src/ls.c с учетом строк 5 — 16, вторая указывает файл в WORKDIR. Переменная LIC_FILES_CHKSUM обязательная для всех заданий, где не установлено LICENSE = «CLOSED».

3.32.1.2. Разъяснение синтаксиса

Как отмечено выше, в переменной LIC_FILES_CHKSUM указаны все важные файлы, содержащие текст лицензий для исходного кода. Можно задать контрольную сумму файла целиком или его части, указанной первой и последней учитываемой строкой (полезно для документов, включающих заголовок, файлов README и т. п.). Если параметр beginline или endline опущен, предполагается учет с первой или до последней строки, соответственно.

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

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

  • Если задан пустой или недействительный параметр md5, BitBake возвращает ошибку md5 mis-match и выводит корректное значение параметра в процессе сборки, записывая его также в журнал сборки.
  • Если файл содержит лишь текст лицензии, параметры beginline и endline не нужны.

3.32.2. Включение заданий с коммерческими лицензиями

По умолчанию система сборки OE исключает компоненты с коммерческими и иными специальными лицензиями. Это требование определяется на уровне заданий в переменной LICENSE_FLAGS. Например, задание poky/meta/recipes-multimedia/gstreamer/gst-plugins-ugly содержит LICENSE_FLAGS = «commercial». Имеется более сложный пример, содержащий явное имя и версию задания (после преобразования переменной).

     LICENSE_FLAGS = "license_${PN}_${PV}"

Для включения в образ компоненты, ограниченной определением LICENSE_FLAGS, нужно добавить соответствующую запись в переменную LICENSE_FLAGS_WHITELIST, которая обычно задается в файле local.conf. Например, для включения пакета poky/meta/recipes-multimedia/gstreamer/gst-plugins-ugly можно добавить строку commercial_gst-plugins-ugly или более общий вариант commercial в переменную LICENSE_FLAGS_WHITELIST. Полное описание работы переменной приведено в параграфе 3.32.2.1. Соответствие флагов лицензий.

Для дополнительного включения пакета, собранного из задания с LICENSE_FLAGS = «license_${PN}_${PV}», в предположении, что файл задания называется emgd_1.10.bb в следующем примере добавлено license_emgd_1.10.

     LICENSE_FLAGS_WHITELIST = "commercial_gst-plugins-ugly license_emgd_1.10"

Не требуется указывать полную строку лицензии в списке разрешений и можно применять сокращенную форму, которая состоит из первой части строки лицензии до первого символа _. Сокращенная строка будет соответствовать любой лицензии, содержащей эту подстроку. Например, LICENSE_FLAGS_WHITELIST = «commercial license» будет соответствовать обоим пакетам, упомянутым выше, а также все прочим пакетам с лицензией, начинающейся с commercial или license.

3.32.2.1. Соответствие флагов лицензий

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

Перед сравнением флага, определенного конкретным заданием, с содержимым разрешенного списка к этому флагу добавляется преобразованная переменная _${PN}. Преобразование делает каждое значение LICENSE_FLAGS зависящим от задания. Например, указание LICENSE_FLAGS = «commercial» в задании foo ведет к строке commercial_foo. Соответствующая строка сравнивается со списком разрешений.

Разумное применение строк LICENSE_FLAGS и содержимого LICENSE_FLAGS_WHITELIST обеспечивает гибкость включения и исключения заданий на основе лицензии. Например, можно расширить сопоставление использованием подстрок флагов лицензий. В этом случае нужно применять ту часть преобразованной строки, которая предшествует добавленному символу _ (например usethispart для usethispart_1.3, usethispart_1.4 и т. п.).

Например, простое указание строки commercial в списке разрешений, будет соответствовать любому преобразованному определению LICENSE_FLAGS, начинающемуся с commercial (commercial_foo, commercial_bar), которое автоматически создается системой сборки для гипотетических заданий foo и bar в предположении, что эти задания включают LICENSE_FLAGS = «commercial».

Таким образом можно задать исчерпывающий список флагов лицензий в списке разрешений и разрешить использование в образе только определенных заданий или использовать подстроки для расширения совпадений, чтобы разрешить включение более широкого спектра заданий. Эта схема работает даже в тех случаях, когда к строке LICENSE_FLAGS уже добавлен суффикс _${PN}. Например, система сборки преобразует флаг лицензии commercial_1.2_foo в commercial_1.2_foo_foo и задание будет соответствовать в списке разрешений строкам commercial и commercial_1.2_foo.

Ниже приведены несколько других вариантов.

  • Можно указать в задании foo строку с версией, такую как commercial_foo_1.2. Система сборки преобразует эту строку в commercial_foo_1.2_foo. Комбинация этого флага со списком разрешений, включающим commercial, обеспечит совпадение как и для любого другого флага, начинающегося со строки commercial.
  • В некоторый случаях можно использовать commercial_foo в списке разрешений совпадать будет не только commercial_foo_1.2, но и любой флаг, начинающийся с commercial_foo, независимо от версии.
  • Можно задать в списке разрешений пакет и версию (например, commercial_foo_1.2) для точного совпадения.
3.32.2.2. Другие варианты, связанные с коммерческими лицензиями

Другие полезные переменные для работы с коммерческими лицензиями определены в файле poky/meta/conf/distro/include/default-distrovars.inc.

     COMMERCIAL_AUDIO_PLUGINS ?= ""
     COMMERCIAL_VIDEO_PLUGINS ?= ""

Для включения этих компонент можно указать в файле local.conf строки вида

     COMMERCIAL_AUDIO_PLUGINS = "gst-plugins-ugly-mad \
        gst-plugins-ugly-mpegaudioparse"
     COMMERCIAL_VIDEO_PLUGINS = "gst-plugins-ugly-mpeg2dec \
        gst-plugins-ugly-mpegstream gst-plugins-bad-mpegvideoparse"
     LICENSE_FLAGS_WHITELIST = "commercial_gst-plugins-ugly commercial_gst-plugins-bad commercial_qmmp"

Можно конечно создать для этих компонент список разрешений LICENSE_FLAGS_WHITELIST = «commercial», но он включит и другие пакеты, где LICENSE_FLAGS содержит commercial, что может оказаться нежелательным. Указание подключаемых модулей в операторах COMMERCIAL_AUDIO_PLUGINS и COMMERCIAL_VIDEO_PLUGINS (вместе с разрешением LICENSE_FLAGS_WHITELIST) включает плагины или компоненты в сборку образа.

3.32.3. Поддержка соответствия лицензиям в жизненном цикле проекта

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

Среди сотен разных лицензий, отслеживаемых YP, сложно знать требования каждой из них. Однако требования основных лицензий FLOSS могут выполняться, если соблюдаются три главных условия:

  • предоставлен исходный код программы;
  • предоставлен текст лицензии для программы;
  • предоставлены сценарии компиляции и изменения исходного кода.

Имеются и другие требования, а также методы, описанные здесь (например, механизм распространения исходного кода). Поскольку в разных организациях применяются различные методы соблюдения лицензий, здесь не описывается универсальный способ выполнить требования, а рассматриваются методы обеспечения соответствия путем выполнения трех приведенных выше условий. После их соблюдения перед выпуском образа, исходных кодов или системы сборки следует проверить полноту всех компонент. В процессе сборки образа YP создает манифест лицензий, размещаемый в каталоге ${DEPLOY_DIR}/licenses/image_name-datestamp, который поможет при проверке.

3.32.3.1. Предоставление исходного кода

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

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

Прежде чем использовать DL_DIR или класс archiver, нужно решить вопрос о способе представления кода. Класс archiver может создавать архивы и SRPM с разными уровнями соответствия. Один из способов заключается просто в выпуске архива (tarball) исходного кода. Это можно сделать, добавив в файл local.conf каталога сборки строки вида

     INHERIT += "archiver"
     ARCHIVER_MODE[src] = "original"

В процессе создания образа исходный код всех включенных в образ заданий помещается в каталоги DEPLOY_DIR/sources на основе переменной LICENSE для каждого задания. Выпуск каталога целиком позволяет выполнить требования по предоставлению исходного кода без изменений. Важно отметить, что размер каталога может оказаться большим. Решением проблемы размера может быть выпуск лишь архивов, для которых лицензия требует предоставление кода. Предположим, что нужен лишь код GPL, определяемый приведенным ниже сценарием.

     # Сценарий для архивирования пакетов с определенными требованиями лицензий
     # Файлы исходного кода и лицензий копируются в каталоги пакетов
     # Сценарий нужно запускать из каталога сборки (build)
     #!/bin/bash
     src_release_dir="source-release"
     mkdir -p $src_release_dir
     for a in tmp/deploy/sources/*; do
        for d in $a/*; do
           # Get package name from path
           p=`basename $d`
           p=${p%-*}
           p=${p%-*}
           # Архивировать только пакеты GPL (измените *GPL* для других лицензий)
           numfiles=`ls tmp/deploy/licenses/$p/*GPL* 2> /dev/null | wc -l`
           if [ $numfiles -gt 1 ]; then
  		echo Archiving $p
  		mkdir -p $src_release_dir/$p/source
  		cp $d/* $src_release_dir/$p/source 2> /dev/null
  		mkdir -p $src_release_dir/$p/license
  		cp tmp/deploy/licenses/$p/* $src_release_dir/$p/license 2> /dev/null
           fi
        done
     done

На этом этапе можно создать архив из каталога gpl_source_release и предоставить его пользователям. Этот метод является этапом соблюдения разделов 3a в GPLv2 и 6 в GPLv3.

3.32.3.2. Предоставление текста лицензий

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

     COPY_LIC_MANIFEST = "1"
     COPY_LIC_DIRS = "1"
     LICENSE_CREATE_PACKAGE = "1"

В результате тексты лицензий в процессе сборки будут включены в образ. Установка значения 1 для всех трех переменных приводит к наличию двух копий файла лицензии (в /usr/share/common-licenses и /usr/share/license). Это обусловлено тем, что переменные COPY_LIC_DIRS и COPY_LIC_MANIFEST добавляют копию лицензии при сборке образа, но не предлагают путь добавления лицензий для недавно установленных в образ пакетов. Переменная LICENSE_CREATE_PACKAGE добавляет отдельный пакет и путь обновления при добавлении лицензий в образ.

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

3.32.3.3. Предоставление сценариев компиляции и изменений исходного кода

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

При наличии уровней BSP и дистрибутива эти уровни используются для правки, компиляции, упаковки или изменения (если оно имеется) всех программ с открытым кодом, включенных в образ, может потребоваться выпуск этих уровней в соответствии с разделом 3 лицензии GPLv2 или разделом 1 лицензии GPLv3. Одним из способов решения задачи является явный выбор версии YP и уровней, используемых при сборке. Например,

     # Сборка с использованием ветви warrior репозитория poky
     $ git clone -b warrior git://git.yoctoproject.org/poky
     $ cd poky
     # Сборка с использованием release_branch для уровней
     $ git clone -b release_branch git://git.mycompany.com/meta-my-bsp-layer
     $ git clone -b release_branch git://git.mycompany.com/meta-my-software-layer
     # Очистка репозиториев .git
     $ find . -name ".git" -type d -exec rm -rf {} \;

Для удобства конечных пользователей разработчики могут рассмотреть изменение файла meta-poky/conf/bblayers.conf.sample, чтобы обеспечить автоматическое включение созданных организацией уровнем уровней при использовании выпущенной системы сборки для создания образа, как показано ниже.

     # POKY_BBLAYERS_CONF_VERSION каждый раз увеличивается в build/conf/bblayers.conf
     # changes incompatibly
     POKY_BBLAYERS_CONF_VERSION = "2"

     BBPATH = "${TOPDIR}"
     BBFILES ?= ""

     BBLAYERS ?= " \
       ##OEROOT##/meta \
       ##OEROOT##/meta-poky \
       ##OEROOT##/meta-yocto-bsp \
       ##OEROOT##/meta-mylayer \
       "

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

3.32.4. Копирование отсутствующих лицензий

Некоторые пакеты (например, linux-firmware) могут иметь лицензии, которые мало распространены. Можно избежать применения множества лицензий общего назначения, применимых лишь к определенным пакетам, путем использования переменной NO_GENERIC_LICENSE. Это также позволяет избежать ошибок QA при использовании в задании необычной, но и не закрытой лицензии. Ниже приведен пример использования файла LICENSE.Abilis.txt в качестве лицензии для извлеченного исходного кода.

     NO_GENERIC_LICENSE[Firmware-Abilis] = "LICENSE.Abilis.txt"

3.33. Использование инструмента отчетов об ошибках

Инструмент отчетов об ошибках позволяет представлять ошибки, возникшие в процессе сборки, в центральную базу данных. Извне системы сборки можно использовать web-интерфейс базы для поиска и просмотра ошибок, а также статистики. Инструмент использует модель «клиент-сервер» с реализацией клиентской части в дереве исходных кодов YP (например, poky). Сервер получает данные от клиента и записывает их в базу.

Действующий сервер отчетов об ошибках доступен по ссылке http://errors.yoctoproject.org. Этот сервер организован для того, чтобы можно было получить помощь при возникновении ошибок и предоставить полную информацию об ошибке, а затем указать ссылку на нее (URL) и отправить сообщение в список рассылки. Отправленные на сервер отчеты доступны для всех.

3.33.1. Включение отчетов

По умолчанию инструмент отчетов об ошибках отключен и для его включения нужно наследовать класс report-error, добавив в конце файла local.conf в каталоге сборки строку INHERIT += «report-error». Данные отчетов по умолчанию записываются в файл ${LOG_DIR}/error-report, однако можно задать другое место хранения командой вида ERR_REPORT_DIR = «path».

Включение отчетов об ошибках заставляет систему сборки фиксировать все сообщения и записывать их в указанный файл. При возникновении ошибки система сборки включает в консольный вывод команду для отправки файла с информацией на сервер. Например, для передачи информации на восходящий сервер может служить команда $ send-error-report /home/brandusa/project/poky/build/tmp/log/error-report/error_report_201403141617.txt, которая отправит информацию в общедоступную базу данных на сервере http://errors.yoctoproject.org. При указании конкретного сервера сведения можно отправить в другую базу данных. Информация о работе с инструментом доступна по команде send-error-report —help.

При отправке файла выводится приглашение на просмотр передаваемых данных, а также указание имени и (необязательного) почтового адреса. После ввода информации команда возвращает идентификатор переданных сведений на сервере, например, http://errors.yoctoproject.org/Errors/Details/9522/, который можно использовать для последующей работы с этой ошибкой.

3.33.2. Отключение отчетов

Для отключения отчетов об ошибках следует указать в конце файла local.conf строку INHERIT += «report-error».

3.33.3. Установка своего сервера отчетов об ошибках

При желании можно установить свой сервер отчетов об ошибках, загрузив его код из репозитория Git http://git.yoctoproject.org/cgit/cgit.cgi/error-report-web/. Установка сервера описана в файле README.

3.34. Использование Wayland и Weston

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

YP включает библиотеки протокола Wayland и эталонный сборщик Weston, размещая их в дереве источников. В частности, задания для Wayland и Weston находятся в каталоге meta/recipes-graphics/wayland. Можно собрать пакеты Wayland и Weston для использования с платформами, принимающими инфраструктуру Mesa 3D и Direct Rendering (Mesa DRI). Это означает, что вы не сможете собрать и использовать пакеты, если ваша платформа поддерживает, например, Intel® Embedded Media и Graphics Driver (Intel® EMGD), которые переопределяют Mesa DRI.

По причине отсутствия поддержки EGL пакет Weston 1.0.3 не работает напрямую на эмулируемом в QEMU оборудовании. Однако эта версия Weston без проблем работает с X=эмуляцией.

3.34.1. Включение Wayland в образе

Для включения Wayland нужно добавить его в сборку и установить в образ.

3.34.1.1. Сборка

Чтобы заставить Mesa собрать платформу wayland-egl, а Weston — собрать Wayland с поддержкой KMS5, нужно добавить флаг wayland в оператор DISTRO_FEATURES в файле local.conf в форме DISTRO_FEATURES_append = » wayland». Если где-нибудь включена поддержка X11, Weston будет собирать Wayland с поддержкой X11.

3.34.1.2. Установка

Для установки Wayland в образ нужно включить в файл local.conf оператор CORE_IMAGE_EXTRA_INSTALL += «wayland weston».

3.34.2. Запуск Weston

Для запуска Weston в среде X11 нужно включить пакет, как описано выше и собрать образ Sato. В этом случае Weston Launcher помещается в категорию Utility.

Можно запустить Weston из командной строки, что зачастую удобней в среде разработки. Для этого следует выполнить указанные ниже действия.

  1. Ввести для экспорта XDG_RUNTIME_DIR команды
         mkdir -p /tmp/$USER-weston
         chmod 0700 /tmp/$USER-weston
         export XDG_RUNTIME_DIR=/tmp/$USER-weston
  2. Запустить Weston из оболочки командой weston.

Глава 4. Использование QEMU

YP использует открытую реализацию эмулятора QEMU6 как часть инструментария. В этой главе рассмотрена работа с эмулятором и его применение в разработке.

4.1. Обзор

В контексте YP эмулятор и машина виртуализации QEMU позволяет запускать полные образы, собранные в YP, как задачи системы сборки. Эмулятор QEMU полезен для запуска и тестирования образов и приложений для поддерживаемой YP архитектуры без реального оборудования. YP также использует QEMU для запуска автоматизированных тестов QA на финальных образах, включаемых в каждый выпуск. Реализация эмулятора несколько отличается от обычного QEMU и здесь приведен ее краткий обзор. Официальная информация доступна на сайте QEMU и в руководстве пользователя.

4.2. Запуск QEMU

Для использования QEMU нужно установить и инициализировать эмулятор, а также иметь нужные для работы элементы (образы и файловые системы). Ниже описаны этапы подготовки к работе с QEMU.

  1. Установка QEMU. Эмулятор можно сделать доступным в YP разными способами, одним из которых является установка SDK (см. раздел The QEMU Emulator [2]).
  2. Настройка среды.
    • При выборе репозитория poky с загрузкой и распаковкой архива YP можно организовать среду сборки приведенными ниже командами.
           $ cd ~/poky
           $ source oe-init-build-env    
    • При установке кросс-инструментов можно запустить сценарий их инициализации. Например, приведенная ниже команда запускает сценарий из принятого по умолчанию каталога poky_sdk.
           . ~/poky_sdk/environment-setup-core2-64-poky-linux
  3. Проверка наличия нужных элементов. Нужно убедиться в наличии собранного ядра, которое будет загружаться в QEMU, а также корневой файловой системы для целевой машины и архитектуры.
    • Если был собран образ для QEMU (qemux86, qemuarm и т. п.), его элементы будут находиться в каталоге сборки.
    • Если образа еще нет, нужно зайти на страницу machines/qemu и загрузить готовый образ для целевой машины и архитектуры.

    Извлечение корневой файловой системы описано в разделе Extracting the Root Filesystem [2].

  4. Запуск QEMU командой вида $ runqemu [option ] […]. В соответствии с введенной командой runqemu выполнит заданные действия. Например, по умолчанию QEMU ищет собранный последним образ по временной метке. В параметрах нужно указать по меньшей мере машину, образ виртуальной машины (*wic.vmdk) или образ ядра (*.bin). Ниже приведено несколько примеров запуска QEMU:
    • Запуск QEMU с MACHINE = «qemux86». В предположении стандартного каталога сборки runqemu автоматически найдет образ bzImage-qemux86.bin и файловую систему core-image-minimal-qemux86-20140707074611.rootfs.ext3 (для образа core-image-minimal). При наличии нескольких образов с одним именем, QEMU использует более свежий.
           $ runqemu qemux86
    • Похож на предыдущий пример, но явно указывается образ и тип корневой файловой системы.
           $ runqemu qemux86 core-image-minimal ext3
    • Загрузка образа initramfs для включения звука в QEMU. В этом случае runqemu устанавливает внутреннюю переменную FSTYPE = «cpio.gz». Для включения звука должен быть установлен подходящий драйвер.
           $ runqemu qemux86 ramfs audio
    • В этом примере не представлено информации, достаточной для запуска QEMU. Хотя корневая файловая система задана, нужно еще указать хотя бы MACHINE, KERNEL или VM.
           $ runqemu ext3
    • Этот пример задает загрузку образа виртуальной машины (файл .wic.vmdk). Из .wic.vmdk программа runqemu определяет архитектуру QEMU (MACHINE) qemux86 и корневую файловую систему vmdk.
           $ runqemu /home/scott-lenovo/vm/core-image-minimal-qemux86.wic.vmdk

4.3. Переключение консоли

При загрузке и работе QEMU можно переключаться между поддерживаемыми консолями с помощью клавиш Ctrl+Alt+цифра. Например, Ctrl+Alt+3 переключает на последовательную консоль, если она активна. Возможность переключения полезна, например, при нарушении по какой-либо причине работы основной консоли QEMU. Обычно 2 служит для переключения на основную консоль, 3 — на последовательную.

4.4. Удаление заставки

Можно удалить заставку при загрузке QEMU с помощью клавиш Alt+<-. Это позволяет увидеть фоновый вывод.

4.5. Запрет захвата курсора

Используемая по умолчанию интеграция QEMU захватывает курсор в главном окне. Это обусловлено тем, что стандартные мыши обеспечивают только относительные перемещения, а не абсолютные координаты. Можно отменит захват курсора с помощью клавиш Ctrl+Alt. Интеграция QEMU в YP поддерживает сенсорные панели wacom USB, которые обеспечивают абсолютные координаты, что позволяет курсору входит в главное окно и выходить из него без захвата, упрощая работу пользователя.

4.6. Запуск на сервере NFS

Одним из вариантов работы QEMU является запуск на сервере NFS. Это полезно в тех случаях, когда нужно обращаться к одной файловой системы с хоста сборки и эмулируемой системы. Следует отметить, что для запуска здесь не нужны полномочия root, поскольку применяется сервер NFS в пользовательском пространстве. Ниже описана процедура запуска QEMU с использованием сервера NFS.

  1. Извлечение корневой файловой системы. Когда все готово к запуску QEMU в среде, можно использовать сценарий runqemu-extract-sdk из каталога scripts. Сценарий runqemu-extract-sdk принимает архив корневой файловой системы и распаковывает его в указанное место. Например, команда runqemu-extract-sdk ./tmp/deploy/images/qemux86/core-image-sato-qemux86.tar.bz2 test-nfs распаковывает файловую систему в каталог test-nfs.
  2. Запуск QEMU. После извлечения корневой файловой системы можно запустить runqemu, указав расположение файловой системы. При этом изменения, внесенные в каталог ./test-nfs будут видны при работе. Например, для работы с образом qemux86 служит команда runqemu qemux86 ./test-nfs.

Для запуска, остановки или перезапуска общего ресурса NFS служат приведенные ниже команды.

  • Запуск общего раздела NFS — runqemu-export-rootfs start file-system-location.
  • Остановка общего раздела NFS — runqemu-export-rootfs stop file-system-location.
  • Перезапуск общего раздела NFS — runqemu-export-rootfs restart file-system-location.

4.7. Совместимость QEMU с CPU при работе с KVM

По умолчанию сборка QEMU компилируется для 64-битовых и x86 Intel® Core™2 Duo процессоров, а также 32-битовых x86 Intel® Pentium® II. QEMU собирается для этих CPU по причини их совместимости с широким спектром менее распространенных CPU.

Однако, несмотря на широкую совместимость, эти процессоры могут использовать функции, не поддерживаемые процессором вашего хоста. Это не вызывает проблем при использовании в QEMU программной эмуляции функций, но проблемы могут возникать при работе QEMU со включенным KVM. В частности, программы, скомпилированные для некоторых CPU, не могут работать на CPU под управлением KVM без поддержки функции. Для решения проблемы можно переопределить настройку CPU в QEMU путем установки переменной QB_CPU_KVM в файле qemuboot.conf в каталоге deploy/image. Эта установка задает опцию -cpu, передаваемую QEMU в сценарии runqemu. Для просмотра списка поддерживаемых типов служит команда qemu -cpu.

4.8. Производительность QEMU

При использовании QEMU для эмуляции оборудования могут возникать проблемы производительности в зависимости от комбинации целевой системы и архитектуры. Например, работа образа qemux86 на 32-битовом хосте Intel x86 достаточно производительна в результате соответствия архитектуры целевой системы и хоста. При использовании образа qemuarm на том же хосте Intel производительность может упасть. Но специфические аспекты ARM будут эмулироваться достаточно точно.

Для ускорения работы образы QEMU поддерживают использование distcc для вызова кросс-компилятора вне эмулируемой системы. Если для запуска QEMU применяется runqemu и на хосте имеется приложение distccd, любой инструмент кросс-компиляции BitBake, доступный системе сборки, может автоматически использоваться из QEMU просто путем вызова distcc. Это можно сделать, определив переменную кросс-компилятора (например, export CC=»distcc»). При использовании подходящего образа SDK или автономного инструментария можно также применять эти инструменты.

Имеется несколько механизмов для подключения к системе, работающей на эмуляторе QEMU.

  • QEMU предоставляет интерфейс framebuffer, делающий доступными стандартные консоли.
  • Обычно устройства без монитора имеют стандартный последовательный порт. В этом случае можно настроить операционную систему работающего образа для использования последовательной консоли. Соединение использует стандартную сеть IP.
  • Для некоторых образов QEMU имеются серверы SSH. В образе core-image-sato QEMU сервер Dropbear (SSH) работает без доступа пользователя root. Образы core-image-full-cmdline и core-image-lsb используют OpenSSH вместо Dropbear. Эти серверы поддерживают стандартные команды ssh и scp. Однако в core-image-minimal сервера SSH нет.
  • Можно использовать сервер NFS в пользовательском пространстве для загрузки сессии QEMU с использованием локальной копии корневой файловой системы на хосте. Для организации соединения нужно распаковать архив корневой файловой системы с помощью команды runqemu-extract-sdk, а после этого указать сценарию runqemu распакованный каталог вместо образа коревой файловой системы (см. раздел 4.6. Запуск на сервере NFS).

4.9. Синтаксис командной строки QEMU

Базовый синтаксис команды runqemu имеет форму runqemu [option ] […]. В соответствии с введенной командой runqemu выполнит заданные действия. Например, по умолчанию QEMU ищет собранный последним образ по временной метке. В параметрах нужно указать по меньшей мере машину, образ виртуальной машины (*wic.vmdk) или образ ядра (*.bin). Ниже приведен вывод команды с опцией —help, описывающий команды runqemu.

     $ runqemu --help

     Usage: you can run this script with any valid combination
     of the following environment variables (in any order):
       KERNEL - the kernel image file to use
       ROOTFS - the rootfs image file or nfsroot directory to use
       MACHINE - the machine name (optional, autodetected from KERNEL filename if unspecified)
       Simplified QEMU command-line options can be passed with:
         nographic - disable video console
         serial - enable a serial console on /dev/ttyS0
         slirp - enable user networking, no root privileges is required
         kvm - enable KVM when running x86/x86_64 (VT-capable CPU required)
         kvm-vhost - enable KVM with vhost when running x86/x86_64 (VT-capable CPU required)
         publicvnc - enable a VNC server open to all hosts
         audio - enable audio
         [*/]ovmf* - OVMF firmware file or base name for booting with UEFI
       tcpserial=<port> - specify tcp serial port number
       biosdir=<dir> - specify custom bios dir
       biosfilename=<filename> - specify bios filename
       qemuparams=<xyz> - specify custom parameters to QEMU
       bootparams=<xyz> - specify custom kernel parameters during boot
       help, -h, --help: print this text

     Examples:
       runqemu
       runqemu qemuarm
       runqemu tmp/deploy/images/qemuarm
       runqemu tmp/deploy/images/qemux86/<qemuboot.conf>
       runqemu qemux86-64 core-image-sato ext4
       runqemu qemux86-64 wic-image-minimal wic
       runqemu path/to/bzImage-qemux86.bin path/to/nfsrootdir/ serial
       runqemu qemux86 iso/hddimg/wic.vmdk/wic.qcow2/wic.vdi/ramfs/cpio.gz...
       runqemu qemux86 qemuparams="-m 256"
       runqemu qemux86 bootparams="psplash=false"
       runqemu path/to/<image>-<machine>.wic
       runqemu path/to/<image>-<machine>.wic.vmdk

4.10. Опции команды runqemu

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

  • QEMUARCH архитектура машины QEMU (qemuarm, qemuarm64, qemumips, qemumips64, qemuppc, qemux86, qemux86-64).
  • VMобраз виртуальной машины (.wic.vmdk) для загрузки. Имя файла должно включать qemux86-64, qemux86, qemuarm, qemumips64, qemumips, qemuppc или qemush4.
  • ROOTFS корневая файловая система ext2, ext3, ext4, jffs2, nfs или btrfs. Для nfs нужен полный путь к корню.
  • KERNELобраз ядра (.bin). При наличии файла .bin runqemu обнаруживает его и считает образом ядра.
  • MACHINEархитектура машины QEMU (qemux86, qemux86-64, qemuarm, qemuarm64, qemumips, qemumips64, qemuppc). Опции MACHINE и QEMUARCH в основном идентичны. Если опция MACHINE не задана, runqemu пытается определить машину из других опций.
  • ramfs указывает загрузку образа initramfs, означающего тип файловой системы (FSTYPE) cpio.gz.
  • iso указывает загрузку образа ISO, означающего тип файловой системы (FSTYPE) .iso.
  • nographic отключает графическую консоль, устанавливая консоль на ttys0. Опция полезна, когда вы подключены к серверу и не хотите отключать пересылку X11 на рабочую станцию.
  • serial включает последовательную консоль на порту /dev/ttyS0.
  • biosdir устанавливает пользовательский каталог для BIOS, VGA BIOS и keymap.
  • biosfilename устанавливает пользовательское имя BIOS.
  • qemuparams=\»xyz\» задает пользовательские параметры QEMU и служит для передачи опций, отличных от kvm и serial.
  • bootparams=\»xyz задает пользовательские параметры для загрузки ядра.
  • audio включает звук в QEMU. Опция MACHINE при этом должна иметь значение qemux86 или qemux86-64. Кроме того, нужен драйвер snd_intel8x0 или snd_ens1370 на гостевой системе linux.
  • slirp включает сеть slirp, для которой не требуется доступ root, но использование сложнее и менее функционально.
  • kvm включает KVM для архитектуры qemux86 или qemux86-64. Для работы KVM нужно выполнить 3 условия:
    • опция MACHINE должна иметь значение qemux86 или qemux86-64;
    • на хосте сборки должны быть установлены модули KVM (/dev/kvm);
    • каталог /dev/kvm на сборочном хосте должен быть открыт для чтения и записи.
  • kvm-vhost включает KVM с поддержкой VHOST для архитектуры qemux86 или qemux86-64. Для работы KVM с VHOST нужно выполнить 3 условия:
    • должны быть выполнены условия для опции kvm;
    • на хосте сборки должно быть устройство virtio net (/dev/vhost-net);
    • каталог /dev/vhost-net на сборочном хосте должен быть открыт для чтения и записи, а также требуется поддержка slirp;
  • publicvnc включает сервер VNC на всех хостах.

Литература

[1] Yocto Project Overview and Concepts Manual, https://www.yoctoproject.org/docs/2.7.1/overview-manual/overview-manual.html.

[2] Yocto Project Application Development and the Extensible Software Development Kit (eSDK), http://www.yoctoproject.org/docs/2.7.1/sdk-manual/sdk-manual.html.

[3] Yocto Project Reference Manual, http://www.yoctoproject.org/docs/2.7.1/ref-manual/ref-manual.html.

[4] Yocto Project Quick Build, http://www.yoctoproject.org/docs/2.7.1/brief-yoctoprojectqs/brief-yoctoprojectqs.html.

[5] Yocto Project Board Support Package (BSP) Developer’s Guide, https://www.yoctoproject.org/docs/2.7.1/bsp-guide/bsp-guide.html.

[6] BitBake User Manual, http://www.yoctoproject.org/docs/2.7.1/bitbake-user-manual/bitbake-user-manual.html.

[7] Yocto Project Linux Kernel Development Manual, https://www.yoctoproject.org/docs/2.7.1/kernel-dev/kernel-dev.html.

[8] Toaster User Manual, http://www.yoctoproject.org/docs/2.7.1/toaster-manual/toaster-manual.html.

Перевод на русский язык

Николай Малых

nmalykh@protokols.ru

1OpenEmbedded Image Creator — создатель образов OpenEmbedded.

2GNU Project Debugger — отладчик проекта GNU.

3Developer’s Certificate of Origin.

4Mail Transport Agent — агент доставки почты.

5Kernel Mode Setting — установка режима ядра.

6Quick EMUlator.

Запись опубликована в рубрике Linux. Добавьте в закладки постоянную ссылку.