Ok.
Methods:
- systemd service
In this case systemd servicesetssdroot.service
runing beforelocal-fs-pre.target
is used ( aftersystemd-remount-fs.service
from initrd, if initrd with systemd is used) . So it’s one of the first runing units when system starts up. But, there are parallel targetsswap.target
,cryptsetup-pre.target
, various low-level services. (systemd bootup ) . This service executes script, which switches rootfs with systemctl call/bin/systemctl --no-block switch-root ${CHROOT_PATH}
.
Pros:
-
No initrd or extlinux.conf required. So, work with JetPack 4.2, where kernel is located in special partition.
-
After building new kernel, default
initrd
update workflow is required, no manual modification of initrd (i.e.flash.sh ...
).If system doesn’t use initrd, we need only install modules on SSD and eMMC. -
If /dev/nvme0n1p1 is absent, default rootfs is used, because
setssdroot.service
will not be executed.
Cons:
-
It’s still hack
:)
. -
There are units, executing in parallel with
setssdroot.service
, including udevd, thus, for some devices modules will be loaded from rootfs on eMMC while others from NVMe. That’s why we need to install same modules on both. -
I don’t understand why, but we need copy of
setssdroot.service
andsetssdroot.sh
on NVMe, otherwise service completes with error (but still switches rootfs).
- extlinux.conf APPEND
In this case APPEND line with new “root=…” parameter is added toextlinux.conf
. At kernel loading stagecboot
appends this line to kernel cmdline. So cmdline have 2 “root=…” parameters: first - “root=/dev/mmcblk0p1” from device tree for cboot, second - custom, appended with extlinux.conf directive.
Pros:
-
Normal system bootup sequence. Main and backup kernel could be different.
-
All modules are loaded from initrd or rootfs on NVMe only. One needs only to copy new kernel image and it’s initrd to
/boot/
directory on eMMC and configure/boot/extlinux/extlinux.conf
there. No modules installation for new kernel on eMMC required. (Except when the same kernel image is used as backup). -
Backup kernel is set by extlinux.conf :
LABEL backup
MENU LABEL backup kernel
LINUX /boot/Image
INITRD /boot/initrd
APPEND ${cbootargs} quiet
It can have it’s own initrd and only it’s modules are installed on eMMC.
Cons:
-
Only JetPack 4.4 now is supported, because
cboot
with extlinux.conf parsing is required. -
After building new kernel and updating
initrd
,init
script should be patched manualy in case of default JetPackinitrd
. According @gtj, Dracut generated initrd works without modification -
If NVMe is absent, linux is stuck in initrd. To boot from backup kernel and rootfs on eMMC command from debug terminal should be used.