Completely Erasing Module

Is there any way to completely remove an image once it has been flashed to a module? I tried to search for a way to wipe the eMMC but couldn’t find anything. We are trying to test the install process and would like to completely reset the module after each attempt/test.

Thanks!

Every normal/full flash adds each partition back in again. The content is based on images on the host PC. Should the image be the same on the PC (such as from flashing twice using the same release), then content will be 100% replaced, but the content will be from a match of what was already there. Are you worried that bad content is remaining? Or are you thinking of security? Are you worried only about the rootfs, or are you worried about all partitions?

You could put images of the correct size which are entirely NULL bytes in the correct place and then flash, but I doubt this is really what you want. Also, keep in mind eMMC does not last forever. Wear leveling is important to the life of the eMMC, and so if you go to too much effort to fully wipe a system it may not last as long.

@linuxdev - Thanks for the quick response. The concern is that while testing the factory flashing process, some old/outdated/bad content remains on the module, and leads us to believe we have a complete/working process when in fact the process is incomplete and only works because of images there were previously flashed to the module. I think this leads me to believe I should be worried about about all of the partitions not just the rootfs.

Once the flashing process has been fine-tuned and perfected, the modules won’t be erased in this manner. Your concern for the wear leveling and life of the eMMC is greatly appreciated and noted. I think creating images composed entirely of NULL bytes will work to get us through this testing process.

I really appreciate your help and welcome any other thoughts or insights you my have.

-Cory

Sorry for the long post, much of this is about rootfs which you may already know, but probably someone will find it useful. Other partitions are a much simpler case.

For reference (I’ll say more later), a pure command line flash without using SDKM/JetPack uses the “driver package” of L4T (unpacked as non-root, producing the “Linux_for_Tegra/” content), and the “sample rootfs” (unpacked as root with sudo into “Linux_for_Tegra/rootfs/”). Then the “Linux_for_Tegra/apply_binaries.sh” script is run to place NVIDIA-specific drivers into “rootfs/”. If you flash on command line with the “-r” option, then no new image is created and the image left over from a previous flash is used…the “Linux_for_Tegra/bootloader/system.img.raw” and the “Linux_for_Tegra/bootloader/system.img” will remain unchanged for a “-r” option to flash.sh.

If you flash once with no content in the “rootfs/” subdirectory (such as not unpacking the sample rootfs, and not running “sudo ./apply_binaries.sh”), then the resulting rootfs in “bootloader/system.img.raw” and “bootloader/system.img” will also be empty, but they will be formatted as ext4.

The “system.img.raw” is an exact bit-for-bit match of the rootfs partition. “system.img” is normally (if you allow the default image to be created) just a “sparse” version of this. Flash occurs based on “system.img”, but regardless of whether this file is “raw” or “sparse” the result will be the same. Should the larger raw file be used, flash takes longer, but is otherwise the same thing (sparse is converted by the Jetson into the equivalent of raw during eMMC write).

You can manually convert a raw file into a sparse file with the “bootloader/mksparse” utility. This is dependent upon the software understanding the ext4 filesystem, and so a file with NULL bytes (versus ext4) probably cannot be used with mksparse (I haven’t tried), and the full sized raw image would need to be created. If you choose to use ext4, but with no content, then this much larger/slower file can be greatly reduced in size and time to flash goes down.

However, a sparse image will very likely simply mark areas which have no content as such and will probably not actually write the empty space. This is not really a problem in most cases, but if you really want the rootfs to overwrite with NULL bytes, then a sparse file is not suitable for your use (areas will be marked as free, but content will not be overwritten with other content unless something ends up filling up the filesystem). You would have to use the full sized raw file with name “bootloader/system.img” regardless of whether you put ext4 on it or not. I would be tempted to use ext4 with no content, but you can try a NULL-byte system.img (more info on doing this with dd later).

As a twist on the story you could also create an ext4 filesystem file for system.img which is a full filesystem…the empty ext4 loopback mountable image could be created, and then dd could be used to create a single file within the loopback device filled with NULL, or "1"s, or any pattern you want. This is the most time consuming way to do it, but is most likely to work in all cases to overwrite eMMC in that partition (a full partition won’t mark areas as unused, and will guarantee content throughout the entire filesystem). More on dd later.


Some URLs for what follows (you may need to go there, log in, and then go there a second time since redirect does not work):


If you flash on command line (which is best for production anyway, I’d ignore JetPack/SDK Manager), then you can log a flash and then observe which images (usually a “.bin” suffix prior to signing) need to be set as NULL bytes (or any byte pattern you want).

You can find the logged name and location of each file or partition image as it is copied in or flashed (some content is copied from a reference location into a working directory, then flash is from the working directory…logs should make this clear). If you unpack the driver package into an alternate location (so you don’t have to mess with your default flash area or content), then you could log a flash like this (the gawk part is just an attempt to remove some of the progress bar spam…you could skip that or adjust since it doesn’t really cut out much in some of the newer releases):

sudo ./flash.sh -S <SizeSpecification> jetson-tx2 mmcblk0p1 2>&1 \
   | gawk '{gsub("[0-9][0-9]+[/][0-9[0-9]+ bytes sent..",".");print}' \
   | tee log.txt

Normally the system.img.raw (raw rootfs) is an exact multiple of 1024 either twice (MiB) or three times (GiB). If you create your own file for as a substitute for actual rootfs, then it must match the default image size of system.img.raw, or else you must use the "-S " for non-default sizes (it doesn’t hurt to use “-S” for all cases if the value is correct). For example, a file which is 28GiB needs an exact file size of 28*1024*1024*1024 bytes (30064771072 bytes). After a test flash you can examine “bootloader/system.img.raw” to know the correct size (see how many times the exact byte size is divisible by 1024, and then use the MiB or GiB value). If you let the system generate a new system.img.raw (which you do not want), or if you manually create a purely NULL content rootfs file or an empty ext4 file, and if that file matches that default size, then you do not need to specify the “-S” option. If the file is any other size, then you must use “-S” and name the correct size.


Regarding generating files on the host, this would generate a 28GiB file (30064771072 bytes) filled with NULL bytes:

dd if=/dev/zero of=my_null_file.img bs=512 count=58720256

This is because 512*58720256 is 28GiB. The block size can be increased to do this faster:

dd if=/dev/zero of=my_null_image.img bs=58720256 count=512

…512 blocks of 58720256 bytes is equivalent to 58720256 blocks of size 512 bytes. The larger block size will create the file in less time. Block sizes are all a multiple of 512, e.g., 1024 works. Both result in 30064771072 bytes, which is evenly divisible by 1024 three times, and has size specification “-S 28GiB”.


Loopback manipulation of a file (such as the previously created my_null_file.img, a raw file) so it can be formatted as ext4 is how you will set up the empty file as ext4. If you run any losetup which requires root authority, but in which you do not use sudo or root, then you can examine some information without actually creating a loopback device. The same command which is run sudo will actually create the loopback device. To see what the next unused loopback device is:
losetup --find
…there are only so many loop devices available, so be careful you don’t create a lot of loop devices with sudo unless you really want that many.

If this shows as “loop0”, then this will cover the file with loop0:
sudo losetup --show --find ./my_null_image.img

If your loop device was “/dev/loop0”, then this will format the file as ext4:
mkfs.ext4 /dev/loop0
…notice that because your regular user owns the underlying my_null_image.img that sudo is not needed…don’t use sudo unless you have to, it can be painful to mkfs.ext4 by accident on the wrong thing.

Now mount the loopback device somewhere temporary. I use “/mnt” due to tradition. “sudo” is required:

sudo mount /dev/loop0 /mnt
# Verify:
df -H -T /mnt
# Fill this up with a single file of NULL bytes:
cd /mnt
# Verify again that you are really there, it's a bad idea to fill up the wrong partition:
df -H -T .
sudo dd if=/dev/zero of=empty_file.img bs=512
# Verify the loopback file is now full:
df -H -T .
# Exit that location and umount:
cd
sudo umount /dev/loop0
# ...your image is now ready for use as flash.

Copy this file to the “Linux_for_Tegra/bootloader/system.img” location and name. Assuming 28GiB, this flash should fully fill the rootfs with NULL bytes (you can use a pattern or non-NULL if you want to verify):
sudo ./flash.sh -S 28GiB -r jetson-tx2 mmcblk0p1

If you have logged previously and have replaced the other partition images with NULL or patterned files, then all such partitions have been overwritten.

Note that ext4 partitions are a special case because although written as binary data some parts of the Jetson have an understanding of ext4 for sparse and raw image conversion. Files written to other partitions should not have any issue of “not really writing all of the NULL bytes”; the way raw/sparse ext4-aware software might understand empty space is a special case.


Those other non-rootfs partitions are not normally generated and if you replace the original copy in the correct location with a NULL or pattern filled substitute, then each time a signed version is generated it should do so without overwriting any of your original work. The first time you run flash.sh without “-r” the “bootloader/system.img” will be overwritten and things won’t happen as you expect after that unless you place system.img back there. You could even modify the flash.sh from this “special reset driver package” to make sure system.img always has the same checksum (such as crc32, which is fast even on large files) and there is no way to run without “-r”.


Note that wear leveling may mean there are still bits present, but this will not have any effect on the current data retrieved from any partition. This should pretty much guarantee you’ve wiped the TX2 clean prior to a normal flash. I would not advise doing this a lot, and if you suspect some change did not take place which should have, then finding out why the change did not take place would be wise (you could use this eMMC wipe to verify some aspects, but I would not advise doing this prior to every real flash).

1 Like

Actually, you could use the tool in Linux_for_Tegra to do the erase. But you may need to change the corresoponding binary in below commands according to your module. Also this could apply to tx2 series only.

sudo ./tegraflash.py --chip 0x18 --applet mb1_recovery_prod.bin --bl nvtboot_recovery_cpu.bin --bins “mb2_bootloader nvtboot_recovery.bin; bpmp_fw bpmp.bin; bpmp_fw_dtb tegra186-a02-bpmp-quill-p3310-1000-c01-00-te770d-ucm2.dtb; tlk tos.img” --cmd “erase /sdmmc_boot/3/; erase/sdmmc_user/3/”

@WayneWWW - Would this be the equivalent of a “factory reset”, as in this would put the module into the same state as when it left NVIDIA’s factory?

@linuxdev - Thank you very much for such a detailed response. This has really helped me understand what the flashing script is doing behind the scenes as well as how to use it in a production environment. I know this will be useful to others as well.

Many thanks!

Hi Cory,

It puts the module into the same state as when it left NVIDIA’s factory?

It is totally erasing the emmc to empty and cannot boot. Anyone wants to use this module again must flash with jetpack first.

flash with jetpack first
This means flash.sh command will not suffice?
Would it be possible to use command line sdkmanager?

What does the “/3/” at the end of the erase “/sdmmc_boot/3/” and “/sdmmc_user/3/” do?

What does the “/3/” at the end of the erase “/sdmmc_boot/3/” and “/sdmmc_user/3/” do?

You could check the flash.xml. There is an instance “3” in both sdmmc_boot and sdmmc_user device.

This means flash.sh command will not suffice?
Would it be possible to use command line sdkmanager ?

Actually, flash.sh/jetpack/sdkmanager are same, so using flash.sh is also sufficient.

If you really want to tell the difference then…

flash.sh -> It is a tool to provide the minimal BSP and rootfs to flash your board. This tool has been used for long time and you could see this exist even in rel-21 for tk1. Also, jetpack and sdkm is using this tool to flash board too.

jetpack: Besideds installing the BSP/rootfs, it also help install the sdk.

sdkmanager: It is just a new version of GUI tool that to replace jetpack after rel-32.

I see that now. However, there is no 0, 1, or 2 instances. What is the purpose of having an instance of 3?

I think the instance means the sdmmc4 interface of tegra SoC.

“flash.sh”, and most of the “Linux_for_Tegra/” directory content is from the “driver package” (the “Linux_for_Tegra/rootfs/” content is from the “sample rootfs” and with NVIDIA drivers copied into this). JetPack and SDK Manager do not flash, they only act as a graphical front end to the driver package. JetPack/SDKM are a convenience for automatic downloading. JetPack/SDKM is installed to the host PC, and never to the Jetson…running JetPack/SDKM implies flashing L4T through the driver package even though the GUI looks like a separate program.

If you have the “Linux_for_Tegra/” content, then it won’t matter if it is from a manual download of the L4T driver package, nor if the download is from JetPack/SDKM. The result is the same.

The part which the driver package provides (other than convenience) is that if your Jetson is fully booted, then the host PC JetPack/SDKM can also copy optional packages over to the Jetson via ssh and then install those packages (e.g., CUDA). JetPack/SDKM can also install packages to the host PC (e.g., CUDA).

Different JetPack/SDKM releases are tied to a specific release of L4T. The optional packages have dependencies on the L4T release, and so using JetPack/SDKM to install packages implies the packages will be compatible with that release of L4T.