Я уже рассказывал, как можно собрать минимальный Linux под различные архитектуры. Также я описывал свой эмулятор известной игры «Ну, Погоди!». В этой статье я хочу рассказать, как создать дистрибутив Linux с моим эмулятором, который будет работать в режиме киоска.

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

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

Можно было попробовать создать киоск с нуля, но я решил использовать Yocto. Хотя контроля за происходящим меньше, и дистрибутив будет больше, Yocto является промышленным стандартом для встраиваемых систем, и знание, как работать с Yocto, не помешает.

При использовании Yocto обычно собирают дистрибутив в Linux. Также предъявляются требования к железу. Процесс сборки занимает значительное время. Всё это плата за универсальность. Вероятно, у меня будет желание создать киоск без использования Yocto, если эта тема интересна, напишите об этом в комментариях.

Для первой сборки потребуется значительное время. На моём ноутбуке это заняло около полутора часов. Сколько это займёт времени у вас, зависит от производительности ноутбука и канала интернет.

У меня был Raspberry Pi Zero 2 W, его мощности хватало для эмулятора, поэтому я использовал его для создания киоска.

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

Yocto Project и OpenEmbedded

OpenEmbedded — это фреймворк для сборки Linux-дистрибутивов для встраиваемых систем. Он содержит в себе систему сборки BitBake и набор рецептов по сборке Linux-дистрибутива, сгруппированных в слои.

Yocto Project использует в качестве основы OpenEmbeded, расширяя его документацией, reference-реализацией дистрибутива Poky, несколькими своими слоями, инструментами, стандартами и инфраструктурой тестирования.

Слои и рецепты

Основу Yocto составляют рецепты и слои.

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

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

Создание своего дистрибутива на основе Yocto Project

Создание своего дистрибутива начинается с клонирования Poky и необходимых слоёв.

  1. В нашем случае нужно склонировать Poky, meta-openembedded и meta-raspberrypi:

    git clone -b scarthgap https://github.com/yoctoproject/poky.git
    
    git clone -b scarthgap https://git.openembedded.org/meta-openembedded
    
    git clone -b scarthgap https://git.yoctoproject.org/meta-raspberrypi
    
  2. Создаём окружение для сборки в директории build-rpi:

    source poky/oe-init-build-env build-rpi
    
  3. Добавляем слои в наш дистрибутив:

    bitbake-layers add-layer ../meta-openembedded/meta-oe
    
    bitbake-layers add-layer ../meta-raspberrypi
    
  4. Удостоверяемся, что слои были добавлены:

    bitbake-layers show-layers
    
  5. Редактируем файл conf/local.conf:

    vi conf/local.conf
    
  6. Вставляем в начало файла conf/local.conf строку:

    MACHINE = "raspberrypi0-2w-64"
    
    • MACHINE — целевая аппаратная платформа,

    • raspberrypi0-2w-64 — конфигурация для Raspberry Pi Zero 2 W с 64-битной архитектурой. Эта строка делает многое. После её добавления Yocto подберёт соответствующие:

    • загрузчик,

    • настройки ядра Linux,

    • device tree,

    • параметры архитектуры CPU,

    • настройки GPU/драйверов,

    • различные machine-specific пакеты и конфигурации.

  7. Собираем один из вариантов дистрибутива core-image-sato:

    bitbake core-image-sato
    
  8. Ждём, пока всё соберётся, и при помощи balenaEtcher записываем образ core-image-sato-raspberrypi0-2w-64.rootfs-*.wic.bz2 из директории tmp/deploy/images/raspberrypi0-2w-64 на SD-карту.

  9. Вставляем SD-карту в Raspberry Pi, подключаем клавиатуру, мышь, монитор, питание.

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

Кастомизация дистрибутива

  1. Создадим свой слой, в который будем добавлять рецепты:

    bitbake-layers create-layer ../meta-rpi-kiosk
    
    bitbake-layers add-layer ../meta-rpi-kiosk
    
    
  2. В слое будет создан рецепт с именем по умолчанию, дадим рецепту осмысленное имя:

    mv ../meta-rpi-kiosk/recipes-example/ ../meta-rpi-kiosk/recipes-games
    
    mv ../meta-rpi-kiosk/recipes-games/example ../meta-rpi-kiosk/recipes-games/nu-pogodi
    
    mv ../meta-rpi-kiosk/recipes-games/nu-pogodi/example_0.1.bb ../meta-rpi-kiosk/recipes-games/nu-pogodi/nu-pogodi.bb
    
    
  3. Создаём файл ../meta-rpi-kiosk/recipes-bsp/bootfiles/rpi-cmdline.bbappend с содержимым:

    CMDLINE:append = " quiet loglevel=0 vt.global_cursor_default=0"
    

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

  4. Создаём файл ..meta-rpi-kiosk/conf/distro/rpi-kiosk.conf с содержимым:

    require conf/distro/poky.conf
    
    DISTRO = "rpi-kiosk"
    DISTRO_NAME = "Raspberry Pi Zero 2 W Kiosk"
    
    LICENSE_FLAGS_ACCEPTED += "synaptics-killswitch"
    IMAGE_INSTALL:append = " nu-pogodi kernel-modules"
    

    LICENSE_FLAGS_ACCEPTED нужен для принятия лицензий, IMAGE_INSTALL:append добавляет приложение «Ну, Погоди!» в собираемый образ.

  5. Файл meta-rpi-kiosk/recipes-games/nu-pogodi/nu-pogodi.bb:

    SUMMARY = "Nu, Pogodi!"
    DESCRIPTION = "SDL2-based Nu Pogodi"
    LICENSE = "MIT"
    
    SRC_URI = "git://github.com/artyomsoft/nupogodi-sdl.git;branch=yocto;protocol=https"
    SRCREV = "65c26bdd3e27ba68d16f38ef6f526c821b52b762"
    LIC_FILES_CHKSUM = "file://LICENSE;md5=1643afdae60f67513b07ff7184ecc366"
    PV = "1.0+git"
    
    S = "${WORKDIR}/git"
    
    DEPENDS = "libsdl2 libsdl2-image pkgconfig"
    RDEPENDS:${PN} += "libsdl2 libsdl2-image"
    
    inherit pkgconfig
    
    EXTRA_OEMAKE += "\
        CC='${CC}' \
        CFLAGS='${CFLAGS} -I${S} -I${S}/cpu -I${S}/device -I${S}/data' \
        LDFLAGS="${LDFLAGS} -lSDL2 -lSDL2_image -lm" \
        LIBS='-lSDL2 -lSDL2_image -lm' \
    "
    do_compile() {
        oe_runmake
    }
    
    do_install() {
        install -d ${D}${bindir}
        install -m 0755 nupogodi-sdl ${D}${bindir}/nupogodi
        install -d ${D}${bindir}/resources/nupogodi
        install -m 0644 resources/nupogodi/fg.png ${D}${bindir}/resources/nupogodi/fg.png
        install -m 0644 resources/nupogodi/im-02.bin ${D}${bindir}/resources/nupogodi/im-02.bin
        install -m 0644 resources/nupogodi/nupogodi.svg ${D}${bindir}/resources/nupogodi/nupogodi.svg
    }
    
  6. Чтобы получился киоск, нам нужно выполнить конфигурацию оконного менеджера, для этого добавляем в наш слой файлы session и matchbox-session-sato_%.bbappend. В первом файле прописываем действия при загрузке оконного менеджера, во втором — модифицируем существующий рецепт matchbox-session-sato

    Файл session:

    #!/bin/sh
    matchbox-window-manager -use_titlebar no -use_cursor no &
    cd /usr/bin
    exec /usr/bin/nupogodi
    

    Файл matchbox-session-sato_%.bbappend

    FILESEXTRAPATHS:prepend := "${THISDIR}/files:"
    
    SRC_URI += "file://session"
    
    LIC_FILES_CHKSUM = "file://session;endline=3;md5=9d8115f65e5fb57260b875d4130c5555"
    
    do_install:append() {
    install -m 0755 ${WORKDIR}/session ${D}/etc/matchbox/session
    }
    
  7. В итоге наш слой выглядит следующим образом:

    meta-rpi-kiosk/
    ├── conf/
    │   ├── distro/
    │   │   └── rpi-kiosk.conf
    │   └── layer.conf
    │
    ├── recipes-bsp/
    │   └── bootfiles/
    │       └── rpi-cmdline.bbappend
    │
    ├── recipes-games/
    │   └── nu-pogodi/
    │       └── nu-pogodi.bb
    │
    └── recipes-sato/
        └── matchbox-sato/
            ├── files/
            │   └── session
            └── matchbox-session-sato_%.bbappend
    
  8. Собираем один core-image-sato:

    bitbake core-image-sato
    

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

  9. Собраный образ записываем на SD-карту и загружаемся.

Созданный нами слой находится в GitHub-репозиотрии meta-rpi-kiosk.

Процесс загрузки киоска на Raspberry Pi Zero 2 W

Полезные ссылки

  1. Yocto Project — официальный сайт проекта Yocto, промышленного стандарта для создания встраиваемых Linux-дистрибутивов.

  2. OpenEmbedded — фреймворк для сборки Linux-дистрибутивов для встраиваемых систем, основа Yocto Project (содержит BitBake и набор рецептов).

  3. balenaEtcher — кроссплатформенная утилита для записи образов дисков (в том числе .wic.bz2) на SD-карты.

  4. meta-rpi-kiosk — GitHub-репозиторий созданного в статье слоя Yocto с рецептами эмулятора «Ну, Погоди!» и настройками киоска для Raspberry Pi Zero 2 W.

  5. poky — официальный репозиторий reference-дистрибутива Poky, используемый как основа для сборки.

  6. meta-openembedded — основной слой OpenEmbedded с дополнительными рецептами и пакетами.

  7. meta-raspberrypi — официальный слой Yocto для поддержки плат Raspberry Pi.

  8. nupogodi-sdl — репозиторий SDL2-эмулятора игры «Ну, Погоди!» (ветка yocto), который добавляется в образ киоска.

Заключение

С помощью Yocto мы собрали образ для Raspberry Pi Zero 2 W, добавили необходимые библиотеки и эмулятор «Ну, погоди!», а затем настроили запуск приложения в режиме киоска.

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

При этом за простым интерфейсом остаётся полноценный Linux: ядро, драйверы, файловая система, сеть и необходимые системные компоненты. Yocto позволяет собрать из этих компонентов именно тот образ, который нужен для конкретного устройства.

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

© 2026 ООО «МТ ФИНАНС»