嵌入式Linux下使用 Plymouth 實(shí)現(xiàn)開機(jī)畫面示例
By Toradex秦海
1). 簡介
嵌入式 Linux 下傳統(tǒng)實(shí)現(xiàn) Splash Screen 的方式是通過替換 kernel 默認(rèn)的 TUX 小企鵝 logo 為定制的開機(jī)畫面圖片來實(shí)現(xiàn)嵌入式設(shè)備開機(jī)圖片,雖然比較成熟且可以保證開機(jī)畫面加載比較早,但是存在的問題首先是對嵌入式設(shè)備不同顯示接口的兼容性不好,另外每次修改適配都需要重新編譯內(nèi)核,維護(hù)起來不是很方便,然后就是只能支持靜態(tài)圖片無法支持動畫。基于上述原因,使用專門的 Splash Screen 工具來實(shí)現(xiàn)開機(jī)畫面逐漸成為嵌入式設(shè)備的主流方向,本文就簡單演示使用 Plymouth 工具來實(shí)現(xiàn)動態(tài)開機(jī)畫面的示例。
本文所演示的平臺來自于Toradex Verdin iMX8MM 嵌入式平臺,基于 NXP iMX8M Mini 系列 ARM 處理器,主要核心架構(gòu)為 Cortex-A53 。
2). 硬件準(zhǔn)備
a).
核心版配合 載板,并通過 DSI-LVDS Adapter 連接 以及調(diào)試串口以便測試。3). 關(guān)于 Plymouth
a). Plymouth 是一個實(shí)現(xiàn) Linux 啟動過程中開機(jī)畫面的工具軟件,其啟動的時間非常早,通過 initramfs 幫助可以在 Linux 內(nèi)核加載同時啟動,甚至要早于 Linux rootfs 文件系統(tǒng)掛載。Plymouth 可以方便的實(shí)現(xiàn)開關(guān)機(jī)圖片或者動畫。
b). 關(guān)于 Plymouth 更多詳細(xì)介紹以及源代碼請自行參考如下資料。
./ Plymouth 官方頁面
./ Plymouth 源代碼
./ Plymouth 深入配置使用說明
4). 通過 Ycoto 環(huán)境配置 Plymouth 并編譯 Ycoto Linux BSP Image
a). 配置 Ycoto Project 編譯環(huán)境
./ 參考這里配置基本的 Ycoto Project 編譯環(huán)境
./ 參考如下文章配置定制化 layer
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 相關(guān)配置文件
./ 增加 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 圖標(biāo)會被遮蓋,實(shí)際使用可以根據(jù)需要修改圖片文件和 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 是文件系統(tǒng)組件,通過 Linux kernel 加載完成后在使能systemd 來啟動,這樣就會導(dǎo)致比較大的延遲;為了盡可能使 Plymouth 在系統(tǒng)啟動過程中盡早啟動,可以添加包含 Plymouth 的 Initramfs 鏡像使得 Plymouth 在 Linux Kernel 加載過程中即同步啟動了。
./ 添加 Initramfs bb 定義以及相關(guān)文件,對應(yīng)需要 files 目錄下的相關(guān)文件請參考
---------------------------------------
$ 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 來調(diào)整啟動進(jìn)程,這里通過修改 u-boot-distro-boot 文件來適配,對應(yīng)的 files 目錄下的文件完整內(nèi)容請參考
---------------------------------------
$ 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 來實(shí)現(xiàn)的,為了使得在 initramfs 階段就可以加載相關(guān)驅(qū)動,需要修改 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 文件請見
,主要修改了如下幾個驅(qū)動的配置---------------------------------------
-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 文件結(jié)構(gòu)如下
---------------------------------------
$ 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 壓縮包內(nèi),需要修改如下 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 文件添加相關(guān) 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 相關(guān)定義
---------------------------------------
# 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 環(huán)境變量來顯示 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). 最后部署完成的測試效果如下,實(shí)測從開機(jī)到出現(xiàn) Splash 畫面大約5秒,另外 Plymouth splash 默認(rèn)除了支持開機(jī)畫面,在 reboot 重啟和 poweroff 關(guān)機(jī)的時候也會同樣顯示 splash 畫面
動畫演示如下
6). 總結(jié)
本文基于嵌入式 Linux 簡單演示了 Plymouth splash 開機(jī)畫面的部署和測試。
*博客內(nèi)容為網(wǎng)友個人發(fā)布,僅代表博主個人觀點(diǎn),如有侵權(quán)請聯(lián)系工作人員刪除。