故障现象
有些使用LSDK编译生成的系统镜像在安装至SD卡或eMMC并放入目标板卡启动后,不会自动挂载/boot分区;然而根据LSDK的设计,/lib/modules实际上是指向/boot/modules的软链接,因此boot分区挂载失败会内核驱动加载失败。
故障分析
1. 目标系统分析
在目标板卡上观察到,systemd报错的首个服务为/etc/systemd/system/boot.mount,通过journalctl可看到其日志中包含一条:
1 | |
这条消息提示自动挂载的参数配置有问题。/etc/systemd/system/boot.mount服务文件的内容如下:
1 | |
可见,其UUID并未被正确修改,导致挂载失败。
通过grep等工具对自启动的脚本及服务简要排查后,可以确定该参数不是在目标板卡上进行配置的。
2. 宿主系统分析
由于故障涉及目标系统的运行,而导致故障的参数具有动态的特性,初步推断问题出在烧录工具flex-installer上面。通过vim `which flex-installer`,并在文件中搜索UUID=字符串,可在350行左右发现boot分区UUID的更新机制:
1 | |
理想状态下这行代码在一部分操作系统中可以返回正确的UUID(如我的主机,使用openSUSE):
1 | |
但在本次编译、安装系统使用的Docker容器中(flex-build docker),lsblk -f命令本应正常返回的很多参数均为空,其中包括我们所关心的UUID:
1 | |
根据flex-installer的逻辑,也就不难理解为何没有正确配置boot分区的UUID了。
解决方案
经试验,blkid工具可以更可靠地获得分区的UUID。将flex-installer的第350行改为使用blkid即可:
1 | |
备注
原始故障的现象是不挂载/boot导致找不到内核模块,但并不能(仅)通过/etc/fstab来解决,因为boot.mount的自启动是在自动加载内核模块之前,而/etc/fstab则是在加载内核模块之后,因而还是会影响到设备驱动的加载。