How to flash second OS on devkit to eMMC after flashing to nvme with initrd?

How to flash second OS to eMMC
without formatting the existing OS flashed to nvme with initrd ?
Is it possible?

I’ve never attempted it, but in theory, you could use extlinux.conf of one to name the rootfs of the other. That shouldn’t be too difficult if they share the same kernel and device tree. In theory (not necessarily easy in practical terms) an initrd could also use interactive boot menus the way the serial console does (or the way GRUB does on a PC). Never tried though. initrd edit would be more powerful, but also more difficult than extlinux.conf targets (extlinux.conf runs in bootloader stages, initrd is running in Linux).

Not that it is an answer, but you might find this useful information on an initrd

The most common use of an initrd is to load a kernel and a subset of required modules from a known “simplest possible” filesystem (the cpio unpack is just a directory tree in RAM with no particular traits other than “being in RAM like a tree”). All Linux bootloaders and kernel understand this “simplest case” filesystem. The actual content is a gzip cpio archive. It contains several files from “/lib/modules/$(uname -r)/”, e.g., let’s say the kernel understands ext4, but it needs to understand XFS…one would add the proper XFS module into the initrd at the proper location. Then you’d have a very minimal operating system with the XFS module available. This minimal operating system would then know how to use an XFS root filesystem despite the support being in a module. Once that module is in RAM it won’t matter what filesystem is in use, and one can then pivot_root (or some equivalent) to use the new filesystem.

You’re not using this for a new filesystem, but coincidentally, since an initrd is a “mini operating system”, it means that it contains a bash interpreter which functions as the init process. Every kernel is PID 0, and a kernel starts running only one process. That process is PID 1, and is known as init. In older systems this was always just a bash script (though logically divided into other scripts so it could be flexibly edited). In newer systems it is systemd (which has a symbolic link “init”; check out “ls -l /sbin/init”).

If that initrd contains an ability to output to the text console (and it should be able to, it is now Linux and the bootloader has overwritten itself with the Linux kernel), then that bash script which serves as init can be edited. Should support be present for interactive bash prompt interaction (you might have to add that), then you could pick a way to drop into the console and ask which rootfs to pivot to right before the original pivot_root (or chroot or switch_root or whatever is used in that particular initrd).

Note that the above uses the original kernel which is responsible for running the initrd. The rootfs is normally picked in part by the kernel argument “root=” (e.g., “root=/dev/mmcblk0p1”), but the pivot_root is also important. You might need to edit the kernel command line, but I’m not sure about that since pivot_root (or switch_root and family) might do that as well. The point is that the code for boot prior to the Linux kernel being loaded points at a certain start location, but once the Linux kernel is loaded, you are free to chain load or pivot to an alternate location.

If you have an initrd file, you can generally unpack and pack like this (assumption is you are in an empty directory when you start; I’ll call that directory name tmp, and the file itself has name initrd.cpio):

  • Short version:
# unpack to the current directory (you might need to pipe this through `gunzip` first):
sudo cpio -vid < initrd.cpio
# reverse to pack...make sure `initrd.cpio` itself is not there:
find . -print | cpio -ov > ../initrd.cpio
cd ..
gzip initrd.cpio
mv initrd.cpio initrd
  • Detailed version:
sudo -s
cd /tmp
# Need a clean directory you can later delete:
mkdir test
cd test
gunzip < /where/ever/it/is/initrd > initrd.cpio
# This does the actual unpack in current directory:
cpio -vid < initrd.cpio
# You can save or delete initrd.cpio here, I just
# delete (otherwise it gets put in any cpio you
# repackage which is not what you want):
mv initrd.cpio ..
# Explore, edit, modify if desired...then repackage
# with new name:
find . -print | cpio -ov > ../initrd-modified.cpio
cd ..
gzip initrd-modified.cpio
mv initrd-modified.cpio initrd-modified
# This is the old unmodified cpio file:
rm initrd.cpio
# Renamed with "-modified" just to keep it from getting mixed up,
# this is now usable as an INITRD entry.
rm -Rf test
  • An alternate representation for creating from a tree of files:
find . | cpio --quiet -H newc -o | gzip -9 -n > ../initrd_new

There are some options for flashing just the initrd, but have not used those.

The problem is that from prior experience it appears that flashing Jetson could erase existing filesystems by default.
Is it still the case? If I flash with sdkmanager or flash sh to eMMc will it wipe nvme ultimately? Or the nvme disk filesystem will be left intact with just eMMC being flashed?

I have not tried. I’ll suggest cloning is a good idea for backup even if you are not going to flash. There are often obscure flash options, and I do not know if the initrd can be individually cloned or flashed.

On the other hand, if you look in “/boot”, you will find some initrd content. It is possible there is an INITRD parameter. However, on at least some systems, passing this as a kernel argument would do the job (either the APPEND key/value of extlinux.conf, or the device tree’s “chosen->bootargs” (which is inherited).

Do you have an initrd currently being used? If so, then what do you see from:

  • cat /proc/cmdline (the actual arguments the Linux kernel sees, but not necessarily boot stages).
  • cat /proc/device-tree/chosen/bootargs.

Is there anything like “initrd=initrd.img”?

Note that if this is in the device tree, then the initrd content might be visible to early boot stages. If it is part of extlinux.conf, then possibly boot stages might import this at a later time, although still before Linux loads. If this is part of the device tree, then you are in luck in a number of ways. For example, you can test different boot entries via serial console picking boot arguments you’ve added to extlinux.conf whereby the DTB or the APPEND are edited without losing your previous known working boot entry. If you have a serial console boot log, does it mention where the initrd is retrieved from (it could be either a partition or a file)?

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.

any ideas why reverse approach - flashing nvme after having eMMC won’t result in unit to get to normal mode from recovery mode after flashing? it remains in recovery mode

flash_1-2_0_20230321-092957.log (45.1 KB)

I don’t have external devices to test with (and I’m running out of host PC space too), so I have no experience with external device versus internal device during failure. In theory though, any time flash succeeds, then the Jetson should automatically reboot to normal operation mode. Perhaps it is doing so, but the boot is failing? If that is the case, and if failed boot is testing correct for valid boot media, then there might be some sort of environment setup whereby it could test if the NVMe is present and valid before going on to eMMC. I think all of the pieces should be there already for doing this, but I have no way to experiment with external devices (even my host PC disk space is becoming scarce, so that too is a concern for me).