故障现象
有些使用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
则是在加载内核模块之后,因而还是会影响到设备驱动的加载。