• <li id="00i08"><input id="00i08"></input></li>
  • <sup id="00i08"><tbody id="00i08"></tbody></sup>
    <abbr id="00i08"></abbr>
  • 博客專欄

    EEPW首頁 > 博客 > 嵌入式Linux下使用 Plymouth 實現開機畫面示例

    嵌入式Linux下使用 Plymouth 實現開機畫面示例

    發布人:toradex 時間:2024-01-26 來源:工程師 發布文章

    By Toradex秦海

    1). 簡介

    嵌入式 Linux 下傳統實現 Splash Screen 的方式是通過替換 kernel 默認的 TUX 小企鵝 logo 為定制的開機畫面圖片來實現嵌入式設備開機圖片,雖然比較成熟且可以保證開機畫面加載比較早,但是存在的問題首先是對嵌入式設備不同顯示接口的兼容性不好,另外每次修改適配都需要重新編譯內核,維護起來不是很方便,然后就是只能支持靜態圖片無法支持動畫。基于上述原因,使用專門的 Splash Screen 工具來實現開機畫面逐漸成為嵌入式設備的主流方向,本文就簡單演示使用 Plymouth 工具來實現動態開機畫面的示例。


    本文所演示的平臺來自于Toradex Verdin iMX8MM  嵌入式平臺,基于 NXP iMX8M Mini 系列 ARM 處理器,主要核心架構為 Cortex-A53 。



    2). 硬件準備

    a).  Verdin iMX8MM ARM 核心版配合 Dahlia 載板,并通過 DSI-LVDS Adapter 連接 10inch LVDS 液晶顯示屏以及調試串口以便測試。



    3). 關于 Plymouth

    a). Plymouth 是一個實現 Linux 啟動過程中開機畫面的工具軟件,其啟動的時間非常早,通過 initramfs 幫助可以在 Linux 內核加載同時啟動,甚至要早于 Linux rootfs 文件系統掛載。Plymouth 可以方便的實現開關機圖片或者動畫。


    b). 關于 Plymouth 更多詳細介紹以及源代碼請自行參考如下資料。

    ./ Plymouth 官方頁面

    Plymouth


    ./ Plymouth 源代碼

    https://gitlab.freedesktop.org/plymouth/plymouth


    ./ Plymouth 深入配置使用說明

    Plymouth - ArchWiki



    4). 通過 Ycoto 環境配置 Plymouth 并編譯 Ycoto Linux BSP Image

    a). 配置 Ycoto Project 編譯環境

    ./ 參考這里配置基本的 Ycoto Project 編譯環境

    Build a Reference Image with Yocto Project/OpenEmbedded | Toradex Developer Center


    ./ 參考如下文章配置定制化 layer

    通過Yocto Project定制嵌入式Yocto Linux鏡像


    b). 在定制化 layer meta-customer-demos 下面添加 layer 配置文件

    ---------------------------------------

    $ mkdir -p ../oe_core/layers/meta-customer-demos/conf

    $ cd .../oe_core/layers/meta-customer-demos/conf

    ### create layer.conf file ###

    # We have a conf and classes directory, append to BBPATH

    BBPATH .= ":${LAYERDIR}"


    # We have recipes-* directories, add to BBFILES

    BBFILES += "${LAYERDIR}/recipes-*/*/*.bb ${LAYERDIR}/recipes-*/*/*.bbappend"


    BBFILE_COLLECTIONS += "customer-demos"

    BBFILE_PATTERN_customer-demos = "^${LAYERDIR}/"

    BBFILE_PRIORITY_customer-demos = "24"


    # Let us add layer-specific bbappends which are only applied when that

    # layer is included in our configuration

    BBFILES += "${@' '.join('${LAYERDIR}/%s/recipes*/*/*.bbappend' % layer \

                   for layer in BBFILE_COLLECTIONS.split())}"

    # Add layer-specific bb files too

    BBFILES += "${@' '.join('${LAYERDIR}/%s/recipes*/*/*.bb' % layer \

                   for layer in BBFILE_COLLECTIONS.split())}"


    LAYERDEPENDS_customer-demos = " \

        core \

        yocto \

        openembedded-layer gnome-layer multimedia-layer networking-layer \

    "

    LAYERSERIES_COMPAT_customer-demos = "hardknott honister kirkstone"

    ---------------------------------------


    c). 在定制化 layer meta-customer-demos 下面添加 Plymouth 相關配置文件

    ./ 增加 Plymouth bb file

    ---------------------------------------

    $ cd .../oe_core/layers/meta-customer-demos/

    $ mkdir -p recipes-core/plymouth

    $ cd recipes-core/plymouth

    ### cteate plymouth_%.bbappend file ###

    FILESEXTRAPATHS:prepend := "${THISDIR}/files:"

    SRC_URI += " \
    file://toradexlogo-white.png \
    file://spinner.plymouth \
    "

    PACKAGECONFIG = "pango drm"

    EXTRA_OECONF += "--with-udev --with-runtimedir=/run"

    do_install:append () {
    install -m 0644 ${WORKDIR}/toradexlogo-white.png ${D}${datadir}/plymouth/themes/spinner/watermark.png
    install -m 0644 ${WORKDIR}/spinner.plymouth ${D}${datadir}/plymouth/themes/spinner/spinner.plymouth
    }

    ---------------------------------------


    ./ 添加 Plymouth 使用的 theme 文件 和 background logo 圖片文件,這里使用的是一個配合屏幕分辨率的白色背景圖片,因此 spinner 圖標會被遮蓋,實際使用可以根據需要修改圖片文件和 theme 配置。

    ---------------------------------------

    $ mkdir files

    $ cp .../toradexlogo-white.png files

    $ cd files

    ### cteate spinner theme file spinner.plymouth ###

    [Plymouth Theme]

    Name=Spinner

    Description=Adoption of official Spinner Theme for Toradex.

    ModuleName=two-step


    [two-step]

    Font=Cantarell 12

    TitleFont=Cantarell Light 30

    ImageDir=/usr/share/plymouth/themes/spinner

    DialogHorizontalAlignment=.5

    DialogVerticalAlignment=.382

    TitleHorizontalAlignment=.5

    TitleVerticalAlignment=.382

    HorizontalAlignment=.5

    VerticalAlignment=.7

    WatermarkHorizontalAlignment=.5

    WatermarkVerticalAlignment=.45

    Transition=none

    TransitionDuration=0.0

    BackgroundStartColor=0x000000

    BackgroundEndColor=0x000000

    ProgressBarBackgroundColor=0x606060

    ProgressBarForegroundColor=0xffffff

    MessageBelowAnimation=true

    ---------------------------------------


    d). 由于 Plymouth 是文件系統組件,通過 Linux kernel 加載完成后在使能systemd 來啟動,這樣就會導致比較大的延遲;為了盡可能使 Plymouth 在系統啟動過程中盡早啟動,可以添加包含 Plymouth 的 Initramfs 鏡像使得 Plymouth 在 Linux Kernel 加載過程中即同步啟動了。

    ./ 添加 Initramfs bb 定義以及相關文件,對應需要 files 目錄下的相關文件請參考這里

    ---------------------------------------

    $ cd .../oe_core/layers/meta-customer-demos/recipes-core

    $ mkdir -p initramfs-framework/files

    $ cd initramfs-framework

    ### cteate initramfs-framework_1.0.bbappend file ###

    FILESEXTRAPATHS:prepend := "${THISDIR}/files:"


    SRC_URI += "\

        file://plymouth \

        file://kmod \

        file://0001-Mount-run-with-tmpfs.patch \

        file://0002-only-scan-for-block-devices.patch \

    "


    PACKAGES:append = " \

        initramfs-module-plymouth \

        initramfs-module-kmod \

    "


    SUMMARY:initramfs-module-plymouth = "initramfs support for plymouth"

    RDEPENDS:initramfs-module-plymouth = "${PN}-base plymouth ${@bb.utils.contains('DISTRO_FEATURES', 'systemd', 'systemd-udev-rules', '', d)}"

    FILES:initramfs-module-plymouth = "/init.d/02-plymouth"


    SUMMARY:initramfs-module-kmod = "initramfs support for loading kernel modules"

    RDEPENDS:initramfs-module-kmod = "${PN}-base"

    FILES:initramfs-module-kmod = "\

        /init.d/01-kmod \

        /etc/modules-load.d/* \

    "


    do_install:append() {

        install -m 0755 ${WORKDIR}/plymouth ${D}/init.d/02-plymouth

        install -m 0755 ${WORKDIR}/kmod ${D}/init.d/01-kmod

    }


    # Adding modules so plymouth can show the splash screen during boot

    SRC_URI:append:mx8-nxp-bsp = " file://50-imx8-graphics.conf"

    RDEPENDS:initramfs-module-kmod:append:mx8-nxp-bsp = " \

        kernel-module-display-connector \

        kernel-module-lontium-lt8912b \

    "


    do_install:append:mx8-nxp-bsp() {

        install -d ${D}/etc/modules-load.d/

        install -m 0755 ${WORKDIR}/50-imx8-graphics.conf ${D}/etc/modules-load.d/50-imx8-graphics.conf

    }

    ---------------------------------------


    ./ 添加 initramfs image 定義文件

    ---------------------------------------

    $ cd .../oe_core/layers/meta-customer-demos/recipes-core

    $ mkdir images

    $ cd images

    ### cteate initramfs-plymouth-splash-image.bb file ###

    DESCRIPTION = "Toradex plymouth splash demo initramfs image"


    PACKAGE_INSTALL = "initramfs-framework-base initramfs-module-udev \

        initramfs-module-rootfs initramfs-module-debug \

        initramfs-module-plymouth ${VIRTUAL-RUNTIME_base-utils} base-passwd \

        initramfs-module-kmod"


    SYSTEMD_DEFAULT_TARGET = "initrd.target"


    # Do not pollute the initrd image with rootfs features

    IMAGE_FEATURES = "splash"


    export IMAGE_BASENAME = "initramfs-plymouth-splash-image"

    IMAGE_LINGUAS = ""


    LICENSE = "MIT"


    IMAGE_FSTYPES = "cpio.gz"

    IMAGE_FSTYPES:remove = "wic wic.gz wic.bmap wic.vmdk wic.vdi ext4 ext4.gz teziimg"


    IMAGE_CLASSES:remove = "image_type_torizon image_types_ostree image_types_ota image_repo_manifest license_image qemuboot"


    # avoid circular dependencies

    EXTRA_IMAGEDEPENDS = ""


    inherit core-image nopackages


    IMAGE_ROOTFS_SIZE = "8192"


    # Users will often ask for extra space in their rootfs by setting this

    # globally.  Since this is a initramfs, we don't want to make it bigger

    IMAGE_ROOTFS_EXTRA_SPACE = "0"

    IMAGE_OVERHEAD_FACTOR = "1.0"


    BAD_RECOMMENDATIONS += "busybox-syslog"

    ---------------------------------------


    e). 由于增加了 initramfs image,就需要修改 distroboot 啟動文件 boot.scr 來調整啟動進程,這里通過修改 u-boot-distro-boot 文件來適配,對應的 files 目錄下的文件完整內容請參考這里

    ---------------------------------------

    $ cd .../oe_core/layers/meta-customer-demos/

    $ mkdir -p recipes-bsp/u-boot/files

    $ cd recipes-bsp/u-boot

    ### cteate u-boot-distro-boot.bbappend file ###

    FILESEXTRAPATHS:prepend := "${THISDIR}/files:"


    SRC_URI:append = " \

      file://boot.cmd.in \

    "

    ---------------------------------------


    f). 另外,對于 Verdin iMX8M Mini,由于顯示部分是通過 DSI-LVDS Bridge 來實現的,為了使得在 initramfs 階段就可以加載相關驅動,需要修改 Linux Kernel 配置,而對于其他 iMX8/iMX8X/iMX8MP 如果是原生 LVDS/HDMI 接口則無需修改。

    ---------------------------------------

    $ cd .../oe_core/layers/meta-customer-demos/

    $ mkdir -p recipes-kernel/linux/files

    $ cd recipes-kernel/linux

    ### cteate linux-toradex%.bbappend file ###

    FILESEXTRAPATHS:prepend := "${THISDIR}/files:"


    # Prevent the use of in-tree defconfig

    unset KBUILD_DEFCONFIG


    SRC_URI += "\

        file://defconfig \

        "

    ---------------------------------------


    ./ files 目錄下的完整 defconfig 文件請見這里,主要修改了如下幾個驅動的配置

    ---------------------------------------

    -CONFIG_DRM_PANEL_LVDS=m

    +CONFIG_DRM_PANEL_LVDS=y


    -CONFIG_DRM_SEC_MIPI_DSIM=m

    +CONFIG_DRM_SEC_MIPI_DSIM=y


    -CONFIG_DRM_TI_SN65DSI83=m

    +CONFIG_DRM_TI_SN65DSI83=y


    -CONFIG_DRM_IMX_SEC_DSIM=m

    +CONFIG_DRM_IMX_SEC_DSIM=y

    ---------------------------------------


    g). 最后配置完成的 meta-customer-demos 文件結構如下

    ---------------------------------------

    $ tree meta-customer-demos/

    meta-customer-demos/

    ├── conf

    │   └── layer.conf

    ├── recipes-bsp

    │   └── u-boot

    │       ├── files

    │       │   └── boot.cmd.in

    │       └── u-boot-distro-boot.bbappend

    ├── recipes-core

    │   ├── images

    │   │   ├── initramfs-ostree-torizon-image.bb

    │   │   └── initramfs-plymouth-splash-image.bb

    │   ├── initramfs-framework

    │   │   ├── files

    │   │   │   ├── 0001-Mount-run-with-tmpfs.patch

    │   │   │   ├── 0002-only-scan-for-block-devices.patch

    │   │   │   ├── 50-imx8-graphics.conf

    │   │   │   ├── kmod

    │   │   │   ├── plymouth

    │   │   │   └── rootfs

    │   │   └── initramfs-framework_1.0.bbappend

    │   └── plymouth

    │       ├── files

    │       │   ├── spinner.plymouth

    │       │   └── toradexlogo-white.png

    │       └── plymouth_%.bbappend

    └── recipes-kernel

        └── linux

            ├── files

            │   └── defconfig

            └── linux-toradex%.bbappend


    13 directories, 17 files

    ---------------------------------------


    h). 為了將 initramfs 集成到編譯生成的 Image 壓縮包內,需要修改如下 image_type 配置文件


    ---------------------------------------

    --- a/layers/meta-toradex-bsp-common/classes/image_type_tezi.bbclass

    +++ b/layers/meta-toradex-bsp-common/classes/image_type_tezi.bbclass

    @@ -8,7 +8,7 @@

     WKS_FILE_DEPENDS:append = " tezi-metadata virtual/dtb"

     DEPENDS += "${WKS_FILE_DEPENDS}"

     IMAGE_BOOT_FILES_REMOVE = "${@make_dtb_boot_files(d) if d.getVar('KERNEL_IMAGETYPE') == 'fitImage' else ''}"

    -IMAGE_BOOT_FILES:append = " overlays.txt ${@'' if d.getVar('KERNEL_IMAGETYPE') == 'fitImage' else 'overlays/*;overlays/'}"

    +IMAGE_BOOT_FILES:append = " overlays.txt initramfs-plymouth-splash-image-${MACHINE}.cpio.gz;initramfs-plymouth-splash-image.img ${@'' if d.getVar('KERNEL_IMAGETYPE') == 'fitImage' else 'overlays/*;overlays/'}"

     IMAGE_BOOT_FILES:remove = "${IMAGE_BOOT_FILES_REMOVE}"


     RM_WORK_EXCLUDE += "${PN}"

    ---------------------------------------


    i). 修改 build/conf/bblayer.conf 文件添加相關 layer

    ---------------------------------------

    --- a/build/conf/bblayers.conf  2023-03-30 11:13:22.946533642 +0800

    +++ b/build/conf/bblayers.conf 2023-11-17 16:03:01.666129480 +0800

    @@ -35,6 +35,7 @@

       ${TOPDIR}/../layers/meta-freescale-distro \

       ${TOPDIR}/../layers/meta-toradex-demos \

       ${TOPDIR}/../layers/meta-qt5 \

    +  ${TOPDIR}/../layers/meta-customer-demos \

       \

       \

       ${TOPDIR}/../layers/meta-toradex-distro \

    ---------------------------------------


    j). 修改 build/conf/local.conf 文件,增加 Plymouth 和 initramfs 相關定義

    ---------------------------------------

    # add plymouth support

    CORE_IMAGE_EXTRA_INSTALL += "plymouth"

    INITRAMFS_IMAGE = "initramfs-plymouth-splash-image"

    INITRAMFS_FSTYPES = "cpio.gz"

    ---------------------------------------


    k). 重新編譯生成 Ycoto Linux BSP Image

    ---------------------------------------

    $ MACHINE="verdin-imx8mm" PARALLEL_MAKE="-j 4" BB_NUMBER_THREADS="4" bitbake tdx-reference-multimedia-image

    ---------------------------------------


    l). 參考這里的說明將上述修改下重新編譯生成的 Ycoto Linux Image 通過 Toradex Easy Installer 更新到 Verdin iMX8MM 模塊。



    5). Plymouth Splash 部署測試

    a). 安裝好上述編譯的 Image 后,參考這里說明配置合適的 Device-tree Overlay 文件來適配屏幕;然后配置如下 U-boot 環境變量來顯示 Splash,且縮短加載時間

    ---------------------------------------

    # setenv tdxargs ‘quiet logo.nologo vt.global_cursor_default=0 plymouth.ignore-serial-consoles splash fbcon=map:3’

    # setenv bootdelay 0

    # saveenv && reset

    ---------------------------------------


    b). 為了保證 Plymouth Splash和 Qt Demo App切換更自然,且中間不會被 Weston Desktop 中斷,需要修改一下一些 Systemd Service 文件

    ---------------------------------------

    --- a/lib/systemd/system/plymouth-quit.service

    +++ b/lib/systemd/system/plymouth-quit.service

    @@ -1,6 +1,6 @@

     [Unit]

     Description=Terminate Plymouth Boot Screen

    -After=rc-local.service plymouth-start.service systemd-user-sessions.service

    +After=rc-local.service plymouth-start.service systemd-user-sessions.service waylan

    d-app-launch.service


     [Service]

     ExecStart=-/bin/plymouth quit --retain-splash


    --- a/lib/systemd/system/serial-getty@.service

    +++ b/lib/systemd/system/serial-getty@.service

    @@ -12,7 +12,7 @@

     Documentation=man:agetty(8) man:systemd-getty-generator(8)

     Documentation=http://0pointer.de/blog/projects/serial-console.html

     BindsTo=dev-%i.device

    -After=dev-%i.device systemd-user-sessions.service plymouth-quit-wait.service getty

    -pre.target

    +After=dev-%i.device systemd-user-sessions.service getty-pre.target

     After=rc-local.service


     # If additional gettys are spawned during boot then we should make


    --- a/lib/systemd/system/weston.service

    +++ b/lib/systemd/system/weston.service

    @@ -13,7 +13,7 @@

     After=systemd-user-sessions.service


     # If Plymouth is used, we want to start when it is on its way out.

    -After=plymouth-quit-wait.service

    +#After=plymouth-quit-wait.service


     # D-Bus is necessary for contacting logind. Logind is required.

     Wants=dbus.socket


    --- a/etc/xdg/weston/weston.ini

    +++ b/etc/xdg/weston/weston.ini

    @@ -6,6 +6,7 @@

     repaint-window=16

     #enable-overlay-view=1

     modules=screen-share.so

    +shell=kiosk-shell.so


     #[shell]

     #size=1920x1080

    ---------------------------------------


    b). 最后部署完成的測試效果如下,實測從開機到出現 Splash 畫面大約5秒,另外 Plymouth splash 默認除了支持開機畫面,在 reboot 重啟和 poweroff 關機的時候也會同樣顯示 splash 畫面


    嵌入式Linux下使用 Plymouth 實現開機畫面示例15112.png


    動畫演示如下

    361_plymouth-splash_verdin-imx8mm.gif



    6). 總結

    本文基于嵌入式 Linux 簡單演示了 Plymouth splash 開機畫面的部署和測試。


    *博客內容為網友個人發布,僅代表博主個人觀點,如有侵權請聯系工作人員刪除。




    相關推薦

    技術專區

    關閉
    主站蜘蛛池模板: 翼城县| 普兰店市| 大竹县| 三都| 遵义市| 鄂州市| 保山市| 遂平县| 靖安县| 澄江县| 安远县| 高雄市| 孝昌县| 水城县| 周口市| 财经| 汉阴县| 吐鲁番市| 甘谷县| 四子王旗| 伊金霍洛旗| 南康市| 华阴市| 砚山县| 天峻县| 汪清县| 明光市| 江源县| 织金县| 卓尼县| 丽水市| 交口县| 张家口市| 广西| 平乡县| 新龙县| 潜江市| 府谷县| 盐边县| 科技| 峨眉山市|