Here are the commands I used for burning the fuses. The most import part is the “-r 0x28” option to odmfuse.sh since that includes the enable_watchdog bit.
I first had to edit the odmfuse.sh script as there was a bug in it and it wasn’t generating the proper fuse values in the XML in offline / --noburn mode. On line 1071, there is a line that states
bootauth="None" and I had to replace that with
I then ran the following commands to get odmfuse_pkc.xml:
BOARDID=2888 BOARDSKU=0004 FAB=400 BOARDREV=M.0 ./odmfuse.sh --noburn -i 0x19 --auth SBKPKC -p -k pkc_priv.pem --KEK0 kek0 --KEK1 kek1 --KEK2 kek2 -S sbk --disable-jtag -r 0x28 jetson-agx-xavier-devkit
tar jxOf fuseblob.tbz2 bootloader/odmfuse_pkc.xml > odmfuse_pkc.xml
I noticed that odmfuse_pkc.xml was missing any programming for the FUSE_BOOT_DEVICE_INFO fuse as well, and the “Jetson AGX Xavier Series Fuse Specification” states “These fuses should be burned to 0x3”, so I added those in by adding this line to the XML:
<fuse name="BootDevInfo" size="4" value="0x3" />
Finally, I used the
burnfuses.sh script in OE4T to actually burn the fuses. That essentially executes the OE4T helper script
./tegra194-flash-helper.sh -c "burnfuses odmfuse_pkc.xml" which in turn calls tegraflash.py with
--cmd "burnfuses odmfuse_pkc.xml".
Fusing went just fine – I had no issues there. But you have my commands now if you wanted to reproduce what I did.
I subsequently flashed the board with the OE4T doflash.sh wrapper script. That just calls tegraflash.py with pre-signed/encrypted images and the cmd argument is “secureflash;reboot”. This is where I started to run into issues due to this BPMP watchdog. The flashing would fail while writing the APP partition always 15 seconds into boot, with this being the last that printed to the console:
[0058.658] I> Entering 3p server
[0058.658] I> USB configuration success
[0058.813] I> Populate storage info
[0058.870] I> Erasing device 0: 3
[0060.092] I> Writing device 0: 3.
[0060.200] I> Found 17 partitions in SDMMC_BOOT (instance 3)
[0060.201] I> Erasing device 1: 3
[0060.711] I> Writing device 1: 3.
[0060.723] I> Writing device 1: 3.
[0060.747] I> Found 44 partitions in SDMMC_USER (instance 3)
[0060.748] I> Writing device 1: 3.
[0060.768] I> Found 44 partitions in SDMMC_USER (instance 3)
[0060.771] I> Writing mb1 partition.
[0060.813] I> Writing mb1_b partition.
[0060.847] I> Writing spe-fw partition.
[0060.872] I> Writing spe-fw_b partition.
[0060.907] I> Writing mb2 partition.
[0060.937] I> Writing mb2_b partition.
[0060.967] I> Writing mts-preboot partition.
[0060.987] I> Writing mts-preboot_b partition.
[0061.009] I> Writing SMD partition.
[0061.023] I> Writing SMD_b partition.
[0061.037] I> Writing VER_b partition.
[0061.051] I> Writing VER partition.
[0061.066] I> Writing device 1: 3.
[0061.074] I> Writing APP partition.
After I made the APP partition image much smaller though, so that flashing completed within 15 seconds, I could subsequently boot the Linux kernel into the initramfs (but I was missing a root filesystem of course). I can see all of the prints that my images are being properly authenticated and decrypted based on the secure boot fuses as well, so fusing is working. However, the board only stays up for 15 seconds after power up now before this BPMP watchdog expires. I can also see that the PMC reset source printed by Linux was “TEGRA_BPMP_WATCHDOG”.
The problem is that there appears to be no way of kicking or disabling this BPMP_WATCHDOG from the CPU.