QSPI Flash update

We now need to update all content on the QSPI flash.
The current update method is to create a CAP package and then use the command fwupdtool install-blob <cap-file> to trigger the update after a system reboot.

Is it possible to perform the update directly via commands after the normal system running, instead of doing it in UEFI?

(Reason for avoiding updates in UEFI during boot: The QSPI flash update takes an excessively long time, and there is no any prompt information during the process. This makes accidental operations (such as power-off) highly likely to occur.)

Don’t think you can avoid a reboot or two as described here:

cat Linux_for_Tegra/tools/README_nv_bootloader_capsule_updater.txt
Obviously, replace IGX with Thor/ the actual file name.

4. Update the QSPI flash.
   a. Copy the generated QSPI flash payload to the target filesystem.
      $ scp ${Your_host_user_name}@${Your_host_IP}:${Your_path}/Linux_for_Tegra/Tegra_IGX_BL.Cap /opt
   b. Execute the bootloader_updater utility to update the IGX bootloader on QSPI flash.
      $ sudo nv_bootloader_capsule_updater.sh -q /opt/Tegra_IGX_BL.Cap
   c. Reboot the tareget to update the QSPI flash image on non-current slot bootloader.
   d. To check the Capsule update status, run the nvbootctrl command after boot to system:
      $ sudo nvbootctrl dump-slots-info
      Note: Capsule update status value "1" means update successfully. About the Capsule update status,
            please refer to developer guide for more information.
   e. To sync bootloader A/B slots, do the step b to d again.
   f. Then the bootloader partitions on QSPI flash(both A/B slots) are updated.

Thank you for your reply. If we do not use the CAP method, can we directly write to the QSPI partition via the mtd_debug write command, while system running?

If my understanding of this is close: On Jetson AGX Thor you cannot write QSPI with mtd_debug at runtime because QSPI is not bound to the Linux MTD subsystem in normal boot. The following infers that the 6.8.12-tegra kernel does not expose QSPI NOR as an MTD device.

ls /sys/class/mtd/   → (empty)
cat /proc/mtd        → header only, no devices

If it were possible it would be high risk since boot firmware lives there. If you clobber the wrong region/partition (UEFI, MB1/MB2, BPMP firmware), you could render the board unbootable / bricked, without an external recovery flash path.

Have you reviewed edk2-nvidia to see if it could serve your use case and create a specialized uefi to potentially avoid needing to modify it at runtime?

Your reply is really helpful.

Our board currently outputs the following:

mi@tegra-ubuntu-mos:~$ ls /sys/class/mtd/
mtd0 mtd0ro
mi@tegra-ubuntu-mos:~$ cat /proc/mtd
dev: size erasesize name
mtd0: 04000000 00001000 “spi5.0”
mi@tegra-ubuntu-mos:~$

And, When our system is running, we did write to the QSPI flash according to FileToFlash.txt using mtd_erase and mtd_write 4K align when erase.
but we found that the data can only be read correctly via mtd_read in recovery mode.
Does this make sense logically?

Leaving aside the risks, would this approach still be feasible?

As far as I can see FileToFlash.txt only exists on DriveOS. I found this Nvidia DriveOS webpage.

and in it there are Bootburn Scripts and Files. I looked at the filenames and recalled that they exist as python scripts in Linux_for_Tegra/unified_flash/tools/flashtools/bootburn_t264_py/

So perhaps the equivalent python scripts might help achieve your use case? I’ll look at the *.py to see if I see anything relevant.

That’s right.

The content in FileToFlash.txt is parsed by the *.py scripts and used to flash the QSPI (flash). The FileToFlash.txt file specifies the unused partitions (by offset and size) on the SPI flash, and which different files to flash to those partitions.

Based on the information I provided above,

mi@tegra-ubuntu-mos:~$ ls /sys/class/mtd/
mtd0 mtd0ro
mi@tegra-ubuntu-mos:~$ cat /proc/mtd
dev: size erasesize name
mtd0: 04000000 00001000 “spi5.0”
mi@tegra-ubuntu-mos:~$

can we determine whether the mtd_debug erase/write commands can be used when the system is running normally?

To inspect

mtdinfo /dev/mtd0
mtd_debug read /dev/mtd0 0 0x1000 dump.bin

Given your stated understanding of the risk, this may be another way to write.

flashcp --verbose image.bin /dev/mtd0
Handles erase/write sequencing correctly.
Said to be less error-prone than raw mtd_debug.
But again this is still inferior to capsule or initrd flashing for firmware.

flashcp --help

usage: flashcp [ -v | --verbose | -A | --erase-all ] <filename> <device>
       flashcp -h | --help
       flashcp -V | --version

   -h | --help           Show this help message
   -v | --verbose        Show progress reports
   -p | --partition      Only copy different block from file to device
   -A | --erase-all      Erases the whole device regardless of the image size
   -l | --wr-last=bytes  Write the first [bytes] last
   -V | --version        Show version information and exit
   <filename>            File which you want to copy to flash
   <device>              Flash device node or 'mtd:<name>' to write to (e.g. /dev/mtd0, /dev/mtd1, mtd:data, etc.)

Got it, i’ll try it.

mi@tegra-ubuntu-mos:~$ mtdinfo /dev/mtd0
mtd0
Name:                           spi5.0
Type:                           nor
Eraseblock size:                4096 bytes, 4.0 KiB
Amount of eraseblocks:          16384 (67108864 bytes, 64.0 MiB)
Minimum input/output unit size: 1 byte
Sub-page size:                  1 byte
Character device major/minor:   90:0
Bad blocks are allowed:         false
Device is writable:             true

mi@tegra-ubuntu-mos:~$ 


mi@tegra-ubuntu-mos:~$ sudo mtd_debug read /dev/mtd0 0 0x1000 dump.bin                
Copied 4096 bytes from address 0x00000000 in flash to dump.bin
mi@tegra-ubuntu-mos:~$ 
mi@tegra-ubuntu-mos:~$ sudo mtd_debug read /dev/mtd0 0 0x1000 dump1.bin
Copied 4096 bytes from address 0x00000000 in flash to dump1.bin                       
mi@tegra-ubuntu-mos:~$                                                                
mi@tegra-ubuntu-mos:~$ diff dump.bin dump1.bin                                        
Binary files dump.bin and dump1.bin differ

Two reads with mtd_debug read give different data.

Thanks

Hello, whitesscott:
I noticed that on Orin, we can update the payloader via the nv_update_engine command. Is this updating the QSPI flash while the system is running?
However, on Thor, this command is also present in the system, but I haven’t seen it being used.

Can this command (nv_update_engine)meet our requirement of updating the bootloader (QSPI flash) while the system is running?

The following is the OTA code for Orin. Does Thor support this operation as well?

T186REF_UPDATER="/usr/sbin/nv_update_engine"
bl_only_payload="bl_only_payload"

force_install_payload () {
        ...
        cp "${payload_name}" "${OTA_PACKAGE_DIR}"/bl_update_payload
        "${T186REF_UPDATER}" --forced-install &> "${OTA_PACKAGE_DIR}/${payload_name}.log"
       ...
}

For Drive-os Thor these may be helpful.

Bootloader Programming

Persistence Across Bootburn Flashing Using Persistent Partition

Managing Mass Storage Partitions in Virtualization

Virtualization enables managing independent partitions. It supports independent flashing, loading, and restarting of individual VM partitions.

You can enable this feature for individual partitions using the Partition Configuration Table (PCT) by setting a load_using_pl flag in your partition configuration.

If this flag is not enabled for a partition, then during the binding step all partition images are combined into a single bootable image with Hypervisor and other Foundation components. This image gets loaded into memory at once during system boot and reloading or rebooting such a partition at runtime is not possible.

Enabling the load_using_pl flag for a partition specifies that the system:

    Stores partition images independently (boot loader, OS kernel, file system)
    Enables independent flashing of partition images
    Requires the Partition Loader to load and execute partition boot images
    Enables partition restarting

whitesscott:
We sincerely apologize that we can only write to the QSPI flash at present, but cannot read from it. What could be the reason for this?

Sorry that it is not supported currently.

We’ve gotten your ticket with the custom requirements and will support you there.

KevinFFF:
I used mtd_debug to write data to /dev/mtd0 in the OS (app.img). The data can be read out normally in recovery mode.

Could you please confirm whether the write function has been verified to work properly on your side with the devkit?

I am concerned that due to the current functional restrictions, the write operation may also have issues.

If it’s convenient for you, let’s hop on a quick call to discuss this. 18511761654

Hi pengyang1,

Officially, we don’t support this use case(access QSPI in linux) on Jetson device as there may be the security related issue.
As you’ve filed a bug, we prefer to support you there for your customized requirement.