Repository navigation
nand-migrate: move a NAND camera off the kernel-volume layout without UART - #243
Conversation
… UART
The first FIT NAND layout kept the kernel in a UBI volume of its own;
the current one keeps it as /boot/fitImage in the UBIFS rootfs, and
firmware's sysupgrade refuses the old one, asking for a reinstall from
U-Boot -- which needs a serial console.
Every U-Boot that saved that layout's stock bootcmd is a FIT NAND build
with ubifsload, so it already boots the new layout. nand-migrate writes
a rootfs that carries /boot (the -nand- package's rootfs.ubifs) into the
rootfs volume, switches bootcmd to the current stock one, and removes
the kernel volume -- in that order, so a run stopped after the write
still boots. It runs as PID 1 from a RAM root, handed over through the
::restart:/sbin/init action firmware's inittab carries, since UBI will
not update the volume the system runs from. U-Boot is not written.
Before anything is touched it refuses, saying why: an edited bootcmd, a
kernel volume without a FIT, bootargs without ${rootargs}, an image that
is not UBIFS for this LEB size or has no kernel in /boot, too little
RAM, a dynamic build, an inittab without the restart action. A camera
stopped after the bootcmd switch is finished live. The log is left in
/root/nand-migrate.log.
The U-Boot env is located, edited (exact key match) and CRC'd by
nand_layout.c, and written with every erase block it spans erased first.
|
/review |
Code Review by Qodo
1.
|
- A failed rootfs write is not survivable: once UBI begins the update the
old rootfs is gone, and the kernel volume kept for step 2 boots nothing
without it. A write-then-swap needs the image's size free, which this
layout never has (rootfs_data is autoresize). Retry from the copy in
RAM instead -- a new update starts the volume over -- and say plainly
what a run that cannot write it leaves behind.
- realpath() into a fixed buffer could overflow it; let it allocate, and
refuse a path the one-line hand-off conf cannot carry.
- ${rootargs} must be an argument of its own in bootargs.
- /boot and the kernel are looked up as the filesystem has them now: the
newest directory entry per name wins, so a later deletion counts.
- A UBIFS node is bounded by its LEB, not by the rest of the image.
- An env entry that does not end inside the env is rejected, not read
past.
Why
The first FIT NAND layout (u-boot-xmedia e19b798a, firmware #2526) kept the kernel in a UBI volume of its own:
kernel(FIT),rootfs(UBIFS),rootfs_data. The current one (u-boot-xmedia a138a692, firmware #2537) has no kernel volume. The kernel is/boot/fitImageinside the UBIFS rootfs. Firmware's sysupgrade refuses the old layout and asks for a reinstall from U-Boot, which needs a serial console.No UART is needed. A camera that saved the old layout's stock bootcmd has a FIT NAND build of u-boot-xmedia, and every NAND build has
CMD_UBIFS. So its U-Boot already boots the new layout, and only the flash contents andbootcmdhave to change.What
ipctool nand-migrate [--dry-run] [--wipe-settings] <rootfs.ubifs>, where the image isrootfs.ubifs.<soc>from the-nand-package to install.It runs these steps in order, so a run stopped at any point after step 1 still boots:
rootfsvolume, and compare it read back (SHA-1);bootcmdto the current stock one (ubifsload /boot/fitImage, then/boot/uImage);kernelvolume, then reboot.A stop after step 1 boots the old kernel volume with the new rootfs. A stop after step 2 boots
/boot. A camera left with the new bootcmd and a kernel volume is finished live, with no reboot. U-Boot is never written.Step 1 rewrites the volume the system runs from, so the work runs as PID 1 from a RAM root. ipctool pivots into a tmpfs (moving
/tmpalong when the image is there, so it isn't copied) and sends busybox initSIGQUIT. Firmware's inittab::restart:/sbin/initthen execs the static ipctool. The log is left in/root/nand-migrate.log.Before anything changes it refuses, saying why, when:
bootcmdisn't the stock one (an edited one is left to its owner);bootargslacks${rootargs};/boot(found from its directory-entry nodes);The env is located, edited (exact key match) and CRC'd in
nand_layout.c, whichnand_layout_testcovers. It is written with every erase block it spans erased first. The existingmtd_write()erases one block, which is too little for an env larger than a NAND block.Tested
nand_layout_testcovers synthetic env and UBIFS buffers, plus (viaNM_ENV/NM_IMAGE) this camera's real env dump and the builder image. It's added to pr-build-check.QEMU (qemu-hisilicon
gk7205v510, with the NAND erase fix 090aaec), on a replica of the camera's flash (its own U-Boot, env and three UBI volumes):Loading file '/boot/fitImage',Verifying Hash Integrity ... crc32+ sha1+ OK, login;IPCTOOL_MIGRATE_STOP=write, then a cold boot: boots via the kernel volume with the new rootfs; a re-run is accepted;IPCTOOL_MIGRATE_STOP=env, then a cold boot: boots/boot/fitImage; the next run removes the kernel volume live;/boot, a non-UBIFS file, an edited bootcmd.Hardware: Zenointel SD-2N-4G, gk7205v510, Oct-04 xm720xxx U-Boot. The image is
rootfs.ubifs.gk7205v500from buildergk7205v510_ultimate_zenointel-sd-2n-4g-nand.tgz.Back on SSH 1m46s later:
majestic came back up with the mis2008 sensor and its VENC channels.