I want to start by verifying that your flash.sh command was run with “sudo” (root authority). Is this correct? I will assume it is correct because loopback can have issues otherwise. There is a bug in the flash.sh script as well, I’ll mention that at the end since indications are this is not an issue in your case.
I also want to verify that your host does not enable 64-bit extensions in mkfs.ext4. To do that look at file “/etc/mke2fs.conf”. You’ll see a block for “ext4”. Make sure that options “64bit” and “metadata_csum” are not in this. If those options are present they’ll need to be temporarily disabled. Normally this only shows at the Jetson side as U-Boot hands off to Linux and not as an issue during flash, but I could see the possibility that manipulating the raw image on loopback having problems with this.
The interesting thing in this case is that the flash is not failing…it never gets to attempt to flash because your host is choking while attempting to convert the 15GB rootfs image from uncompressed/raw to a compressed/sparse image.
The size of the file the original data source is from is correct. What remains is the data actually contained within the image and the location the data is being sent to.
We know the host’s disk has plenty of free space, and we know the file being created at least started to open or be created (but for sanity’s sake check to make sure there is a file of any size by the name “bootloader/system.img”…the system.img.raw is the larger file system.img is being created from…any existence verifies the host didn’t deny writing it).
This strongly suggests either the creation of the ext4 file system onto the loopback version of system.img.raw was somehow corrupt or wrong, or the data within that loopback mounted system is so odd that the software converting from raw to sparse couldn’t handle it. This latter possibility is so trivial everything else needs to be verified first. We need to know if the ext4 imposed on system.img.raw is valid.
Go to the “bootloader/” subdirectory where “system.img.raw” is. Make sure you have a place you can test mount this…the “/mnt” directory should already exist and is usually used for this (but make sure nothing else is there already). You can make a directory anywhere you like if “/mnt” is not available (mounting over some pre-existing content hides that content but does not harm it…the content will reappear after umount). I will use “/mnt” as the example.
See if you can mount the image read-only:
sudo mount -o loop,ro ./system.img.raw /mnt
cd /mnt
ls
cd -
sudo umount /mnt
What you should see is essentially a copy of the “rootfs/” subdirectory. If this failed or if there were mount errors listed, then we know where the problem is.
Assuming this does work file system check the image:
sudo -s
losetup --find --show ./system.img.raw
# Note which loop device it names! Perhaps since you used loop once (loop0) it will name "/dev/loop1".
# The next example shows loop1 but you may need to adjust.
fsck.ext4 /dev/loop1
losetup -d /dev/loop1
exit
Did the fsck.ext4 work without error?
Bug in flash.sh:
Each time you flash and create system.img.raw it uses loopback. This means a dynamically created “/dev/loop0” on the first flash. If the loop device is released, then flashing again will once again use “/dev/loop0”. However, if something has held on to the loop0 device, then each time you flash a new loop device will be needed…the number will increment. The second use will use “/dev/loop1”, the third use will use “/dev/loop2”, so on. For the case of using loopback more than once and not releasing it, or for the case of any other application on the system using loopback for any reason, flash.sh does not handle the name of the loop device correctly and the mkfs stage cannot succeed.
To adjust flash.sh on R21.6 so that it will always handle the loop# scheme correctly open the flash.sh file with an editor. Look for function “build_fsimg ()” (this starts at line 448). Here is the original content without edits (line numbers added):
448 build_fsimg ()
449 {
450 local loop_dev="/dev/loop0"
451 echo "Making $1... ";
452 # On some linux distributions, loop device is not created by default
453 # In such cases, create one manually
454 if [ ! -b ${loop_dev} ]; then
455 loop_dev=`losetup --find`
456 if [ "$?" != "0" ]; then
457 echo "Cannot find loop device. Terminating..";
458 exit 1;
459 fi
460 fi
Change this slightly. It should instead be:
448 build_fsimg ()
449 {
450 <b>#</b> local loop_dev="/dev/loop0"
<b>local loop_dev="$(losetup --find)"</b>
451 echo "Making $1... ";
452 # On some linux distributions, loop device is not created by default
453 # In such cases, create one manually
454 if [ ! -b ${loop_dev} ]; then
455 <b>#</b> loop_dev=`losetup --find`
456 <b>#</b> if [ "$?" != "0" ]; then
457 echo "Cannot find loop device. Terminating..";
458 exit 1;
459 <b>#</b> fi
460 fi
The “#” are just comments…those lines are made invisible but can be reactivated by uncommenting. Instead of starting with loop0 this will go directly to finding the first unused loop device. There are cases where someone already has loop0 in use and this will attempt to work with a loop device which should be left alone (e.g., an encrypted loopback mount might be on loop0…detaching this or altering it is a “bad thing”).
If you were to repeatedly try to flash without rebooting your host it would be best to have this edit (or if something else uses loopback), but for most people there won’t be an issue.
Note: “losetup --find” will echo the first unused loop device. Anyone can run this command. If this command is run as root, and if the device does not already exist, it will be created…non-root users cannot create missing loop devices, and thus flash.sh can only be run correctly as root (with sudo). Not using sudo would be similar to naming a non-existent loop device.