我在闪存设备(带有 UBIFS 的 MTD 设备)上运行我的 rootfs - 注意:它是一个 bitbake 系统,所以它不是成熟的 ubuntu 或任何东西。
我希望能够格式化该设备并向其写入一个新的 rootfs,所以我需要ubidetach
这个设备,我可以做到这一点,但为了做到这一点,我必须杀死每个进程/shell/应用程序等。 .. 曾经存在过的 - 即类似的列表,如果您这样做:
fuser -vm /dev
。
因此,到目前为止,我的尝试(在一定程度上确实有效)是使用pivot_root,我执行以下操作:
- 将 bin、sbin、lib 等复制到我的新 /tmp_root/ 文件夹中
- 挂载/绑定/proc、/sys、dev,运行到/tmp_root/
- 调用pivot_root
- 从 oldroot 卸载所有内容
- 杀死与 oldroot/dev 相关的所有进程
- 卸载旧根
这工作正常 - 此时我可以分离 UBIFS 和闪存 MTD 设备。然而,我不得不杀死所有正在运行的应用程序 - 这不是很有用!
所以,我想做的是(至少作为试验)而不是pivot_root
做一个switch_root
,或者类似的事情,然后我可以运行我的所有应用程序并(希望)刷新 MTD 设备。通常情况下是这样的initramtfs
(或者我已经读过),但就我而言,我只想在已经运行的 rootfs 上进行一些测试和切换文件系统。
使用我创建的同一/tmp_root
文件夹,我尝试过:
exec switch_root /tmp_root /sbin/init
exec -c /dev/console switch_root /tmp_root /sbin/init
但我总是得到同样的结果,例如:
旧的根文件系统不是 initramfs:参数无效
我有点卡住了,一旦系统启动并运行,是否可以完全切换rootfs?
笔记:运行Linux内核4.1.x
答案1
信息:
switch_root 将已安装的 /proc、/dev、/sys 和 /run 移动到 newroot 并使 newroot 成为新的根文件系统并启动在里面 过程。
程序init是进程ID为1的进程,它负责按要求的方式初始化系统。 init 由内核直接启动,并抵抗信号 9,该信号通常会杀死进程。所有其他程序都由 init 直接启动或通过其子进程之一。
之前启动的任何程序、守护进程、模块(?)switch_root
都是由 init 进程 1 启动的。 switch_root 将杀死该 init,因此所有在 init 被杀死后启动的都消失了。
新的 rootfs 必须具有模块(?)、程序、守护进程,以便新的 init 启动。新进程 1 将重新加载模块(?)、重新启动守护进程并生成用户程序。
“我希望能够格式化该设备并向其写入新的 rootfs”
假设您已经构建了新的 rootfs 并准备好“安装”。
格式化后如何启动?这就是你想要 switch_root 的原因吗,因为它已经启动了?
如果是,switch_root 可能不是您需要的工具。
其他可能允许您格式化和复制新 rootfs 的工具。
- 你的引导加载程序。
- 安装在可启动 USB 上的实时 Linux 发行版。
- 自定义 bitbaked 文件系统仅需要启动系统的最低限度,并且需要分区、格式化和复制工具(程序)。这将位于 MTD 上不同分区的另一个“驱动器”上,甚至位于 USB 或仅作为 bzImage 一部分的内存 initramfs 上。
- 您的新 rootfs 暂时位于另一个分区(例如 USB)上。必须调整您的引导加载程序以从它代替当前内核和 rootfs 进行引导。
- 网络启动以太 PXE 甚至 NFS。
这有帮助吗?