IMX6ULL的开机动画和U盘自动加载

发布时间:2026/5/30 14:34:28

IMX6ULL的开机动画和U盘自动加载 上一篇博客中我们介绍了如何构建基于 BusyBox 的根文件系统。可能还有不少读者会疑惑构建这样一个根文件系统到底能用来做什么本篇文章将继续围绕 BusyBox 根文件系统展开介绍它在嵌入式 Linux 开发中的两个实际应用开机动画显示和U 盘自动挂载。建议先阅读本文最后的总结了解整体实现思路后再查看前面的具体操作步骤这样理解会更加清晰。目录一、开机动画显示1、编译psplash2、修改启动脚本 rcS3、制作 rootfs 根文件系统4、开机动画总结二、U盘的加载1、手动挂载 U 盘2、自动挂载 U 盘① eudev 的编译②把 eudev 拷进 rootfs③ 修改 fstab④ 修改 rcS 启动 udev⑤ 创建 udev 自动挂载规则3、U盘挂载总结一、开机动画显示开机动画一般由 Logo 图片和进度条组成可以让系统启动过程更加美观。这里我们使用psplash来实现该功能。psplash 是一个轻量级的开机动画程序常用于嵌入式 Linux 系统。编译源码后会生成psplash和psplash-write两个工具。其中psplash负责显示开机画面psplash-write负责更新进度条、显示文字或退出开机画面。1、编译psplashLinux 内核启动完成后会执行第一个用户态进程一般是/sbin/init。在 BusyBox 根文件系统中init会读取/etc/inittab并根据其中的配置执行启动脚本例如::sysinit:/etc/init.d/rcS因此真正适合启动 psplash 的位置是/etc/init.d/rcS而不是直接写在inittab中。因为 psplash 需要使用 framebuffer 设备例如/dev/fb0而该设备通常要等rcS中执行mdev -s后才会生成得更加可靠。下面是我编译 psplash 源码后生成的psplash和psplash-write并将相关文件复制到rootfs/usr/bin/目录中。这样根文件系统启动时就可以调用这些工具来显示开机动画。编译 PSplash ---------------- 进入源码目录 cd ~/100ask_imx6ull-sdk/DevelopmentEnvConf/psplash 如果源码是 Windows 换行需要先转换成 Linux 换行 dos2unix configure.ac Makefile.am make-image-header.sh *.c *.h README AUTHORS COPYING ChangeLog SECURITY.md psplash.doap .gitignore 如果没有 dos2unix sudo apt install dos2unix 生成 configure autoreconf -fi 设置交叉编译器路径 export PATH/home/book/100ask_imx6ull-sdk/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin:$PATH 配置 ./configure --hostarm-linux-gnueabihf --prefix/usr --without-systemd 编译 make 安装到临时目录 make DESTDIR$PWD/_install install 成功后检查 ls -l _install/usr/bin/psplash ls -l _install/usr/bin/psplash-write file _install/usr/bin/psplash file 命令应该能看到 ARM 相关信息。 回到工程目录 cd ~/100ask_imx6ull-sdk/DevelopmentEnvConf 创建目录 mkdir -p rootfs/usr/bin rootfs/etc/init.d 拷贝程序 cp psplash/_install/usr/bin/psplash rootfs/usr/bin/ cp psplash/_install/usr/bin/psplash-write rootfs/usr/bin/ 拷贝启动脚本 cp imx6ullModule/init.d/S00psplash rootfs/etc/init.d/ 添加执行权限 chmod x rootfs/usr/bin/psplash chmod x rootfs/usr/bin/psplash-write chmod x rootfs/etc/init.d/S00psplash 检查 ls -l rootfs/usr/bin/psplash ls -l rootfs/usr/bin/psplash-write ls -l rootfs/etc/init.d/S00psplash2、修改启动脚本 rcS接下来需要修改系统启动脚本rcS。不过该脚本并不是手动编写的而是由busybox_build_config.sh自动生成的。因此不建议直接修改生成后的rcS文件而应该修改busybox_build_config.sh中生成rcS的相关内容。执行下面命令后sudo ./busybox_build_config.sh该脚本会将已经编译好的 BusyBox 命令、动态库、配置文件、设备节点等内容组合成一个完整的根文件系统。因此我们需要在该脚本中加入 psplash 相关的启动逻辑主要修改位置如下图所示。S00psplash脚本主要用于启动、控制和关闭 psplash 开机动画。系统启动时脚本会通过$PSPLASH 在后台启动 psplash 程序用于显示开机 Logo 和进度条。随后通过$PSPLASH_WRITE PROGRESS 5 $PSPLASH_WRITE MSG Starting system向 psplash 发送控制命令设置启动进度并显示提示信息。当系统启动完成后再通过$PSPLASH_WRITE QUIT关闭开机动画界面。#!/bin/sh PSPLASH/usr/bin/psplash PSPLASH_WRITE/usr/bin/psplash-write PSPLASH_FIFO/tmp/psplash_fifo wait_psplash_fifo() { count0 while [ $count -lt 20 ] do [ -p $PSPLASH_FIFO ] return 0 sleep 0.1 count$((count 1)) done return 1 } start() { [ -x $PSPLASH ] || exit 0 $PSPLASH if [ -x $PSPLASH_WRITE ] wait_psplash_fifo; then $PSPLASH_WRITE PROGRESS 5 /dev/null 21 $PSPLASH_WRITE MSG Starting system /dev/null 21 fi } stop() { if [ -x $PSPLASH_WRITE ]; then $PSPLASH_WRITE QUIT /dev/null 21 fi } case $1 in start) start ;; stop) stop ;; restart) stop start ;; *) echo Usage: $0 {start|stop|restart} exit 1 esac exit $?3、制作 rootfs 根文件系统sudo tar -xjf ~/100ask_imx6ull-sdk/DevelopmentEnvConf/rootfs/rootfs.tar.bz2 \ -C /home/book/nfs_rootfs //放到板子和ubutun共享的目录中 sudo mkdir -p /home/book/tftpboot sudo cp ~/100ask_imx6ull-sdk/Linux-4.9.88/arch/arm/boot/zImage \ /home/book/tftpboot/ sudo cp ~/100ask_imx6ull-sdk/Linux-4.9.88/arch/arm/boot/imx6ull-14x14-angus.dtb \ /home/book/tftpboot/ ls -lh /home/book/tftpboot/zImage \ /home/book/tftpboot/imx6ull-14x14-angus.dtb setenv ip_dyn no setenv ipaddr 192.168.1.88 setenv serverip 192.168.1.66 setenv netmask 255.255.255.0 setenv nfsroot /home/book/nfs_rootfs //Net传输根文件系统 setenv image zImage setenv fdt_file imx6ull-14x14-angus.dtb setenv netargs setenv bootargs consolettymxc0,115200 root/dev/nfs rw nfsroot${serverip}:${nfsroot},v3,tcp ip${ipaddr}:${serverip}::${netmask}::eth0:off run netargs printenv bootargs tftpboot 0x83000000 imx6ull-14x14-angus.dtb setenv tftpblocksize 512 setenv tftptimeout 5000 setenv tftptimeoutcountmax 20 tftpboot 0x80800000 zImage bootz 0x80800000 - 0x830000004、开机动画总结总的来说开机动画的实现就是将 psplash 集成到rootfs根文件系统中并在busybox_build_config.sh生成的rcS启动脚本中调用 psplash。系统启动时rcS脚本会启动 psplash并通过psplash-write更新启动进度和提示信息从而实现开机 Logo 和进度条显示的效果。二、U盘的加载当 U 盘插入开发板后Linux 内核中的 USB 驱动会自动识别该设备并在串口中打印类似如下信息usb-storage 1-1.4:1.0: USB Mass Storage device detected scsi 0:0:0:0: Direct-Access Samsung Flash Drive sd 0:0:0:0: [sda] Attached SCSI removable disk sda: sda1其中/dev/sda表示整个 U 盘设备/dev/sda1表示 U 盘上的第一个分区。后续我们通常挂载的是/dev/sda1。1、手动挂载 U 盘挂载 U 盘前需要先确认当前内核是否支持对应的文件系统。可以执行cat /proc/filesystems查看内核已支持的文件系统类型常见的 U 盘格式有vfat、ext4、exfat等其中vfat通常对应 FAT/FAT32 格式。插入 U 盘后执行blkid /dev/sda1查看 U 盘分区格式。如果输出中显示TYPEvfat说明该 U 盘为 FAT/FAT32 格式如果显示TYPEexfat则说明该 U 盘为 exFAT 格式。确认当前内核支持该文件系统后即可创建挂载目录并将U 盘挂载到/mnt/usb目录下。mkdir -p /mnt/usb mount -t vfat /dev/sda1 /mnt/usb ls /mnt/usb2、自动挂载 U 盘如果希望系统在插入 U 盘后自动完成挂载就需要有一个用户空间程序持续监听内核上报的设备事件。这里可以使用eudev它是一个独立的用户空间设备管理软件包。eudev主要提供以下组件/sbin/udevd /bin/udevadm /etc/udev/其中udevd负责在后台监听内核设备事件udevadm用于调试和管理 udev 规则/etc/udev/目录则用于存放设备匹配规则。通过编写对应的 udev 规则可以在检测到 U 盘插入时自动执行挂载脚本从而实现 U 盘自动挂载。①eudev的编译进入源码目录 cd ~/100ask_imx6ull-sdk/DevelopmentEnvConf/eudev-3.2.14 设置交叉编译器 export PATH/home/book/100ask_imx6ull-sdk/ToolChain/gcc-linaro-6.2.1-2016.11-x86_64_arm-linux-gnueabihf/bin:$PATH 配置 ./configure \ --hostarm-linux-gnueabihf \ --prefix/usr \ --exec-prefix \ --bindir/bin \ --sbindir/sbin \ --libdir/lib \ --libexecdir/lib/udev \ --sysconfdir/etc \ --with-rootprefix \ --with-rootlibdir/lib \ --with-rootlibexecdir/lib/udev \ --with-rootrundir/run \ --disable-manpages \ --disable-selinux \ --disable-kmod \ --disable-blkid \ --disable-hwdb 编译 make 安装到临时目录 make DESTDIR$PWD/_install install 检查 ls _install/sbin/udevd ls _install/bin/udevadm ls _install/etc/udev②把 eudev 拷进 rootfs回到工程目录 cd ~/100ask_imx6ull-sdk/DevelopmentEnvConf 创建目录 sudo mkdir -p rootfs/sbin rootfs/bin rootfs/lib rootfs/etc 拷贝 sudo cp -av eudev-3.2.14/_install/sbin/udevd rootfs/sbin/ sudo cp -av eudev-3.2.14/_install/bin/udevadm rootfs/bin/ sudo ln -sf ../bin/udevadm rootfs/sbin/udevadm sudo cp -av eudev-3.2.14/_install/lib/* rootfs/lib/ sudo cp -av eudev-3.2.14/_install/etc/udev rootfs/etc/ 检查 ls -l rootfs/sbin/udevd ls -l rootfs/bin/udevadm ls -l rootfs/sbin/udevadm ls -l rootfs/etc/udev 检查动态库依赖 arm-linux-gnueabihf-readelf -d rootfs/sbin/udevd | grep NEEDED arm-linux-gnueabihf-readelf -d rootfs/bin/udevadm | grep NEEDED 如果只看到 libc.so.6 说明依赖比较简单rootfs 里已有 glibc 时一般没问题。③ 修改 fstab在fstab中增加devtmpfs和devpts主要是为了完善系统启动后的设备文件环境并不是直接实现 U 盘自动挂载。其中devtmpfs用于挂载/dev目录让系统能够自动生成/dev/sda1这类设备节点。插入 U 盘后后续的udevd和挂载脚本才能根据这些设备节点进行处理。devpts用于挂载/dev/pts主要提供终端、ssh、telnet 等伪终端设备和 U 盘自动挂载没有直接关系但也是 rootfs 中常见的基础挂载项。因此devtmpfs是自动挂载 U 盘的基础条件之一真正实现自动挂载还需要启动udevd并配合 udev 规则和挂载脚本。文件 rootfs/etc/fstab 推荐内容 # device mount-point type options dump fsck order proc /proc proc defaults 0 0 sysfs /sys sysfs defaults 0 0 devtmpfs /dev devtmpfs defaults 0 0 devpts /dev/pts devpts defaults 0 0 tmpfs /tmp tmpfs defaults 0 0 tmpfs /run tmpfs defaults 0 0 各项作用 /proc 内核和进程信息 /sys 设备信息udev 很依赖它 /dev 设备节点建议用 devtmpfs /dev/pts 伪终端 /tmp 临时目录 /run 运行时目录udev 会用到 /run/udev④ 修改 rcS 启动 udev修改启动脚本在系统启动时执行/sbin/udevd --daemon /bin/udevadm trigger /bin/udevadm settle其中udevd作为后台守护进程运行用于监听内核上报的 uevent 设备事件udevadm trigger用于主动触发已有设备的事件udevadm settle用于等待事件处理完成。当插入 U 盘后内核会产生 uevent 事件udevd接收到事件后会匹配/etc/udev/rules.d/10-usb-mount.rules规则。如果匹配到 U 盘分区设备例如sda1就会调用/etc/udev/scripts/usb-mount.sh sda1完成自动挂载。文件 rootfs/etc/init.d/rcS 如果用 udev原来的 mdev echo /sbin/mdev /proc/sys/kernel/hotplug mdev -s 要换成 mkdir -p /dev /dev/pts /run mount -a /sbin/udevd --daemon /bin/udevadm trigger /bin/udevadm settle 含义 /sbin/udevd --daemon 启动 udev 后台进程 /bin/udevadm trigger 主动扫描当前已有设备 /bin/udevadm settle 等待设备事件处理完成 注意 rcS 只负责启动 udevd。 真正插 U 盘后是后台运行的 udevd 自动处理事件。⑤ 创建 udev 自动挂载规则创建目录 sudo mkdir -p rootfs/mnt/usb sudo mkdir -p rootfs/etc/udev/rules.d sudo mkdir -p rootfs/etc/udev/scripts 创建规则文件 sudo vi rootfs/etc/udev/rules.d/10-usb-mount.rules 内容 KERNELsd[a-z][0-9]*, SUBSYSTEMblock, ACTIONadd, RUN/etc/udev/scripts/usb-mount.sh %k KERNELsd[a-z][0-9]*, SUBSYSTEMblock, ACTIONremove, RUN/etc/udev/scripts/usb-umount.sh %k 解释 KERNELsd[a-z][0-9]* 匹配 sda1、sdb1 这类 U 盘分区 SUBSYSTEMblock 匹配块设备 ACTIONadd 插入或新增设备 ACTIONremove 移除设备 %k 当前内核设备名例如 sda1 如果设备是 /dev/sda1udev 实际执行 /etc/udev/scripts/usb-mount.sh sda13、U盘挂载总结U 盘插入后内核会先识别出块设备例如/dev/sda1。但此时还不能直接访问 U 盘文件需要执行挂载命令将设备挂载到目录中mount -t vfat /dev/sda1 /mnt/usb因此自动挂载的核心就是在 U 盘插入并生成/dev/sda1后自动执行上述mount命令。本方案通过udev实现自动挂载。在启动脚本中执行/sbin/udevd --daemon /bin/udevadm trigger /bin/udevadm settleudevd会监听内核产生的 uevent 设备事件并匹配/etc/udev/rules.d/下的规则。匹配成功后再调用/etc/udev/scripts/中的脚本执行挂载命令从而完成 U 盘自动挂载。

相关新闻