Rootfs backup on EMMC

Good afternoon, dear Nvidia! I’m trying now to create system.img that can flash not only 1 copy of the rootfs but 2 in a row.
Now after flashing 1 have 1 rootfs that takes 14 GB of memory. I want to create 2 same rootfs in the size of 6 GB and final 2 GB use for the data that I cannot loose if my rootfs was dead.
The main idea that if I somehow killed my rootfs - I can copy it again from U-BOOT and use it further without reflashing board again.
I tried to multiply system.img in 1 img but there is a problem - gparted cannot understand how it was created and its markup is unknown to it, so, I cannot do this with my bare hands. How can I provide such a functionality?

This is the Nano category, but it seems you have an eMMC model. That’s ok, but it also means you are using a third party carrier board, which in turn means that unless the manufacturer says to use the NVIDIA flash software, then you can’t flash with the purely NVIDIA flash software. Being able to simply flash backups can depend on that detail.

Also, the eMMC models have other partitions and QSPI memory. That content is used for boot (and the equivalent function of a BIOS since Jetsons don’t have a BIOS). That other content has to be compatible, so one release of that content won’t be guaranteed to work with a given rootfs if their versions are different (in some cases it might work, but it is a gamble). However, keep in mind that because a Jetson does not have a BIOS, it cannot self-flash. The concept of copy from U-Boot generally is not going to work. It is a much bigger story about this, but simply copying from U-Boot will generally fail.

Also, recognize that later boot content releases stopped using U-Boot. The R32.x L4T releases transitioned to using only CBoot, but gradually migrated U-Boot functionality (equivalence) into the CBoot software (CBoot was always there, but gradually added more functionality over time). CBoot essentially has a subset of U-Boot function.

If you want backup content, there are things you can do. Simply using the bootloader stages to restore isn’t one of them. You might want to give more detail on what you are most interested in.

We are using 32.7.4 and u-boot is still there. Perhaps I expressed myself incorrectly - I do not need flash everything, I only need to replace one partition with another completely and for this I need to create system.img in such a way that it contains 2 rootfs in a row.
You can replace this without problems from u-boot using regular raw reading and writing from emmc, but for this I need to understand. how to create system.img with 2 identical rootfs.

Are you sure it is U-Boot? CBoot absorbed the functionality and looks just like U-Boot. Someone from NVIDIA would have to comment, but I think R32.7.4 does not have actual U-Boot, just an API compliant CBoot.

I suspect that you would have to edit and modify CBoot to be able to do that, but I don’t know for certain. Maybe someone from NVIDIA can comment if there is a way to copy one partition to another in bootloader command line.

(Incidentally, I like the idea, but I don’t think it will work without extensive modification)

No, I think that it is still u-boot because nvidia still didn’t opened CBoot for Jetson Nano then if they depricated u-boot it appears that I cannot modify bootloader for my board at all that is very bad. It is still u-boot and it is not problem to write such script for u-boot - it is problem to understand how to create such system.img because nvidia has proprietary sd card markup and I cannot understand how to add more partitions in it.
Thus, the final question is: how to add more sections to the emmc? I need 2 more partitions for backup of rootfs and for backup of important information from the system.

system.img is not part of boot, this is strictly the root filesystem. The SD card typically contains only the rootfs on SD card models (there are differences if you buy a third party carrier module and add an eMMC module to it).

I don’t know the specific file, but there is an XML file on the host PC with the partitions listed in it, and their sizes. Someone from NVIDIA will have to answer since I have not experimented with custom partitions. Beware though that you have to be specific regarding SD card models versus eMMC models (eMMC models on third party carrier boards that have an SD card slot also quite different than the first two listed).

Yes, I know about the difference btw SD card and EMMC versions)
I tried to combine 2 same system.img into the 1 with cat but it hadn’t worked. The I thought that the problem is that it has some proprietary markup and it is not working if I doubling this, so I tried to ask nvidia - how can I add 2 more partitions after rootfs on EMMC)

system.img.raw is a partition as binary data. It has structure based on the ext4 filesystem type. There is no merging the way there is with markup data. However, you can access the content of a raw image (not a sparse image) simply by loopback mounting. You can mount (via loopback) two different raw images in two different locations, and then perform copies or rsync from one to the other. The moment you alter one directly, without ext4 tools, then the filesystem is probably destroyed.

I know you are interested in a second partition, which would mean creating a second empty partition, and then filling it with one of the raw images (sparse images expand to be an exact copy of the raw image; both work to install in most cases, but a raw image works in all cases). You can have two partitions. Or you can create a large enough single partition, and use a tool like mkfs.ext4 and rsync combination to put the loopback mounted images in there is some sort of combined way (which is useless if they are both the same partition…it’s like writing words on paper twice that are the same exact words in the same exact place with the same exact look and feel).

If you’ve defined an extra partition, or left space to create an extra partition, then you will have a partition that the running system won’t touch unless you’ve personally set it up for mount. What I don’t know, and what would require experimentation, is whether or not that partition is erased during a subsequent flash. If you’ve only specified the space, and not tried to create a partition during the flash, then it might survive flash. Defining the boundaries of partitions during flash is via the XML file.

Basically, the XML file defines details like the size of partitions and their order and their labels. Binary data is copied into those partitions during flash. If you define partitions that are the same as the default flash, except that the rootfs is some specific size, perhaps smaller than the default, then there would be space left over after flash. If that space has no definition of content in the XML file, then presumably (and I don’t know for certain) that empty space would be left untouched during flash. Should you happen to have previously created content there which is ext4 formatted, and contains files or data, it might be left intact after that flash (you’d have to try it and find out).

The key ingredient here is learning how the XML file sets up partition placement and size. The only partition you can make smaller would be the rootfs since the rest of the partitions have predefined binary images.

Someone else might be able to tell you the details of editing the XML file to reduce the size of the rootfs by 2 GB, making it easy to manually add another partition to the up and running system which can contain your data. Then you could flash again after putting test data on that partition and see if it is preserved.

Okay, thank you! Next time I will be in office I will try to modify xml file.
Maybe someone from Nvidia can comment this solution or add something?

Good afternoon! I discovered that it is impossible to flash 2 exact rootfs because system.img that contais 3 gb rootfs is 14 GB. I cannot understand why but when I opened this with hexdump it appears that there is no 0s in the end so all 14 gb contains smth. It’s strange how possible to obtain 14 gb image from 3 gb rootfs and when system.img is flashed rootfs is still 3 gb.
I have to truncate it somehow or generate new system.img but I cannot understand how to force it to be 6 gb, not 14…

Partitions are just binary data. What you’re looking at is the filesystem as soon as you consider files and directories…this is an organized set of tree data. You can in fact specify a non-default rootfs size, at least on command line flash. What I don’t know is how to combine that with custom partition schemes.

Note that when you clone a Jetson you get two clones…a raw clone, and a sparse clone. The raw clone is a bit-for-bit exact copy of the full partition. A sparse clone is “sort of” like compressing because it includes the specification of the full partition, but actual data only includes files and directories in the partition; as a filesystem fills up the sparse size approaches the raw size. When you flash with a sparse partition the “empty” content is filled and the partition matches the original partition size, but the actual filesystem content is much less if you have not filled up the filesystem. It sounds like you are flashing a sparse filesystem created from a 14 GB partition which has 3 GB of content.

When you generate a filesystem during a normal command line flash you can use the “-S <size>” option with flash.sh to set a size which is a multiple of 1024. Examples:
-S 14GiB
(size 14*1024*1024*1024 bytes, = 15032385536 bytes)

-S 14000 MiB
(size 14000*1024*1024 bytes, = 14680064000 bytes)

I don’t know how to work this though with multiple partition schemes. The ability is there though if someone can comment on creating two custom size matching APP partitions.

I got mixed up - this 14 gb was already preprepeared 2 rootfses that I compiled together with parted - my mistake. For the future experiments I returned to use simple system.img with the only 1 rootfs.
Now I tried to add in xml:

        <partition name="APP" type="data">
            <allocation_policy> sequential </allocation_policy>
            <filesystem_type> basic </filesystem_type>
            <size> APPSIZE </size>
            <allocation_attribute> 8 </allocation_attribute>
            <unique_guid> APPUUID </unique_guid>
            <filename> APPFILE </filename>
            <description> **Required.** Contains the rootfs. This partition must be defined after
              `primary_GPT` so it can be accessed as the fixed known special device
              `/dev/mmcblk0p1`. </description>
        </partition>

        <partition name="APP-1" type="data">
            <allocation_policy> sequential </allocation_policy>
            <filesystem_type> basic </filesystem_type>
            <size> 6442450944 </size>
            <allocation_attribute> 8 </allocation_attribute>
            <unique_guid> APPUUID </unique_guid>
            <filename> APPFILE </filename>
            <description> Contains the backup of the rootfs. This partition must be defined after
              `primary_GPT` so it can be accessed as the fixed known special device
              `/dev/mmcblk0p2`. </description>
        </partition>

And I trying to understand how to explain to flash.sh script that I want it to be flashed in mmcblk0p2 so then I should create 1 more EMMC partition and move every other partition on EMMC by 1.
In the flash.sh I added this but now flashing is totally freezes after APP (main rootfs) partition was flashed and it should flash the next APP-1 partition:

        APP-1)
                if [ ${disk_enc_enable} -eq 0 ]; then
                        target_partfile="${localsysfile}";
                else
                        target_partfile="${localsysbootfile}";
                fi;
               ;;

I don’t know if it is possible to shift all partitions over and create a custom mmcblk0p2. Someone from NVIDIA would have to answer.

Some information though, related to this, but not an answer: If you go to your “Linux_for_Tegra/” directory, and run the command “ls -l *.conf”, then you will see the human readable files which either have flash specifications or refer to another file for a subset of flash specifications. There will always be one file for the carrier board, and another file for the module (one can reuse module specifications on different carrier boards). Notice that the .conf files starting with “jetson-” are symbolic links pointing at files which are based on model numbers for modules and carrier boards…the jetson- versions of .conf files are aliases for easier human reading, but fully equivalent to what they point at. The flash targets are just the file name without the .conf suffix.

If you have a custom carrier board, then you could create a custom .conf file which includes the module specification files, plus an edited version of the carrier board content. You would name that as the flash parameter if using command line, and whatever your edits are, e.g., partitions or device tree, would be used upon flashing that target.

If you look at the chain of files resulting from that single parent file you will eventually find the XML file you are looking at. In other words, you could create a custom .conf file which eventually points at an alternate XML file which is an edit of the original (you wouldn’t need to remove the original file, you’d simply name your new flash target and the original flash target would remain available and unmodified).

Partitions tend to be referred to by their label, e.g., APP, but there are very likely other restrictions. Simply renaming a partition or moving it might result in unexpected consequences. I suggest that two partitions with the same label of APP is probably a violation on any Linux system, but adding another partition of an alternate label might not allow it to be used as you might expect since Jetsons do not have a BIOS in their boot chain. There is a mix of MB1, MB2, and CBoot software (with parts of UBoot migrated into CBoot; it used to be actual UBoot). Those partitions you see, such as mmcblk0p2, are part of the equivalent of the BIOS and the boot chain, so simply moving them or editing labels would work for Linux, but is likely to cause a failure during boot (what is coded into boot and bring-up stages can be hard wired or in software that does not care about labels).

Failover did not exist until R32.x, and early R32.x did not have failover. I have not experimented with failover, so I can’t give you any practical advise. However, is there a reason why the failover option is not workable for you? There is a different flash method for this, e.g., an initrd flash (sorry, I’ve never actually used the failover so I can’t tell you how to do this).

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