在 systemd 启动前将 overlayfs 挂载到 “/” 上

在 systemd 启动前将 overlayfs 挂载到 “/” 上

我正在开发一款带有 arm cortex A9 的嵌入式设备。内核版本为 4.16.0,由 buildroot 2018.05 生成。存储内存是一个具有多个分区的 mmc。U-boot 读取一个分区中的 uImage 并启动内核。文件系统包含在内核映像中,并在启动时加载到 initramfs 中(配置:BR2_TARGET_ROOTFS_INITRAMFS)。

我想使用 overlayfs 将文件夹(在 mmc 中)用作“用户”文件系统,并挂载到/

我已成功尝试通过将这些行添加到以下目录来覆盖/etc名为的目录:/data/etc/etc/fstab

/dev/mmcblk0p1 /data auto defaults 0 1
overlay /etc overlay x-systemd.requires=/data,lowerdir=/etc,upperdir=/data/etc,workdir=/data/work/etc 0 1

这是可行的,但覆盖是在 systemd 启动其服务后安装的。因此,例如网络配置是 uImage 中的配置,而不是我的user文件系统中的配置。我想在启动 systemd 之前安装覆盖,就在/安装之后。

我的理解是,在启动时,系统会在 RAM 中创建第一个内存空间,然后在其中提取 cpio 映像。然后/将其安装在那里,系统启动第一个程序:systemd:/sbin/initPID 为 1。我的理解正确吗?

我读了很多文章和问答网站,但我仍然不明白在 systemd 启动之前,我必须在哪里进行更改才能在启动时执行覆盖。包含该mount /操作的文件是什么?

答案1

我的理解是,在启动时,系统会在 RAM 中创建第一个内存空间,然后在其中提取 cpio 映像。然后 / 会挂载在那里,系统会启动第一个程序:systemd:/sbin/init,PID 为 1。我的理解正确吗?

接近但不完全正确,你错过了中间的几个步骤。如果你使用 initramfs,实际顺序是:

  1. Linux 挂载内存空间(“tmpfs”文件系统)/并提取其中的 cpio 映像。

  2. Linux 运行/init现有的二进制文件在 cpio 图像中. 这将成为 PID 1。

  3. initramfs init 进程将您的主 rootfs 挂载到某个地方,例如/new/real。通常它不使用 fstab,而只使用内核命令行中提供的信息。

  4. initramfs init 进程使用 pivot_root() 和 chroot() 函数,以便将 rootfs 挂载在/。(原始内存中的 / 变得无法访问。)

  5. initramfs init 进程从 执行“真正的” init 系统(即 systemd)/sbin/init。由于它使用 exec() 来执行此操作,因此前后保持相同的 PID 1。

  6. Systemd 开始启动服务并挂载 /etc/fstab 条目。

因此,对于您的情况,您需要编辑 initramfs,以便它在步骤 3-4 中直接转到 overlayfs,而不是使用“原始”根分区。这应该不难,因为 initramfs /init 文件通常是一个基本的 shell 脚本。

相关内容