在Yocto Poky Kirkstone(4.0.2)中为只读根文件系统创建并挂载读写分区的问题求助
嗨,我刚好碰到过类似的场景,你遇到的问题核心原因确实是只读根文件系统的启动流程会跳过常规的/etc/fstab解析,转而依赖initrd里的init-install.sh脚本来处理挂载逻辑。下面给你两种适配hddimg格式的可行方案,一步步来操作:
方案一:给hddimg新增独立读写分区(持久化存储)
如果需要持久化保存应用数据,新增物理分区是最稳妥的方式,适配hddimg的步骤如下:
自定义hddimg的分区布局
在你的自定义layer里新建一个分区配置文件,比如conf/partitions/hddimg_with_rw_part.conf,内容如下:PARTITIONS = " \ 1 1024 ext4 ${IMAGE_ROOTFS} ; \ 2 2048 ext2 ; \ "这里第一行是原有的只读根分区(1GB,ext4格式),第二行是新增的读写分区(2GB,ext2格式,你可以根据需求调整大小和文件系统类型)。
让镜像使用这个分区配置
在你的local.conf里添加以下配置,告诉Yocto用我们自定义的分区规则生成hddimg:IMAGE_CLASSES += "image_partitioned" HDDIMG_PARTITIONS = "${TOPDIR}/conf/partitions/hddimg_with_rw_part.conf"修改initrd启动脚本,自动挂载新分区
因为只读根文件系统的挂载逻辑在initrd的init-install.sh里,我们需要通过bbappend来修改这个脚本:- 新建
recipes-core/initrdscripts/initrdscripts_%.bbappend文件,内容:FILESEXTRAPATHS:prepend := "${THISDIR}/files:" SRC_URI += "file://init-install.sh" - 在同目录下的
files/文件夹里复制原有的init-install.sh(可从Poky源码的recipes-core/initrdscripts/files/路径获取),找到根分区挂载的代码段(大概是mount -o ro ${ROOTFS} ${ROOTMOUNTPOINT}之后),添加挂载新分区的逻辑:
注意:这里的# 挂载读写分区到/usr/local mkdir -p ${ROOTMOUNTPOINT}/usr/local mount /dev/sda2 ${ROOTMOUNTPOINT}/usr/local -t ext2 -o rw,relatime/dev/sda2是新分区的设备名,如果你硬件里的存储设备名是mmcblk0p2这类,要对应修改。
- 新建
更新/etc/fstab(可选但推荐)
保留你之前用base-files_%.bbappend添加的fstab配置,再补充一行:/dev/sda2 /usr/local ext2 defaults,rw 0 0这样后续手动挂载或者系统重启时,fstab也能正常生效。
方案二:用OverlayFS实现/usr/local读写(无需新增分区)
如果不需要持久化存储,或者暂时不想修改分区布局,可以用OverlayFS把/usr/local变成读写层,读写内容临时存在内存或者volatile分区里:
修改initrd脚本配置OverlayFS
同样通过bbappend修改init-install.sh,在根分区挂载完成后添加以下代码:# 准备OverlayFS的分层目录 mkdir -p ${ROOTMOUNTPOINT}/usr/local_ro mkdir -p ${ROOTMOUNTPOINT}/usr/local_rw mkdir -p ${ROOTMOUNTPOINT}/usr/local_work # 将原/usr/local的内容迁移到只读底层 mv ${ROOTMOUNTPOINT}/usr/local/* ${ROOTMOUNTPOINT}/usr/local_ro/ # 挂载OverlayFS到/usr/local mount -t overlay overlay -o lowerdir=${ROOTMOUNTPOINT}/usr/local_ro,upperdir=${ROOTMOUNTPOINT}/usr/local_rw,workdir=${ROOTMOUNTPOINT}/usr/local_work ${ROOTMOUNTPOINT}/usr/local这样所有对/usr/local的写入都会存在
/usr/local_rw目录里,重启后会丢失(如果是存在内存里的话)。可选:绑定到持久化存储
如果需要保留数据,可以把/usr/local_rw绑定到你已有的存储分区,比如:mount /dev/sda2 ${ROOTMOUNTPOINT}/usr/local_rw -t ext2 -o rw,relatime
验证配置是否生效
编译镜像并烧写到设备后,执行mount -v命令,如果看到以下类似输出,就说明配置成功了:
- 方案一:
/dev/sda2 on /usr/local type ext2 (rw,relatime) - 方案二:
overlay on /usr/local type overlay (rw,relatime,lowerdir=/usr/local_ro,upperdir=/usr/local_rw,workdir=/usr/local_work)
内容的提问来源于stack exchange,提问作者durje




