Hardware Platform: Jetson Orin NX
Jetpack Version: 6.2.1 (L4T r36.4.4)
Script: l4t_flash_from_kernel.sh
Issue Description: I have encountered a critical bug in l4t_flash_from_kernel.sh when using l4t_initrd_flash.sh to flash an external NVMe SSD connected to the host PC (via USB reader) rather than the target Jetson.
The flashing process fails to write partitions to the correct locations on the disk, resulting in a device that cannot boot (often unable to find the ESP partition).
Scenario:
-
Direct Connection (Works): When the SSD is connected directly to the Jetson, the Logical Block Size and Physical Block Size are usually identical (often 512 bytes). The script works.
-
Host Connection via USB (Fails): When connecting the NVMe to the host PC via a USB adapter for flashing, the drive often reports as “512e” (512 bytes Logical, 4096 bytes Physical).
Root Cause Analysis: The Linux kernel standardizes the start attribute in /sys/block/.../start to always be in 512-byte sectors, regardless of the actual physical geometry of the disk.
However, in l4t_flash_from_kernel.sh, the script attempts to calculate the byte offset by multiplying this sector count by the Physical Block Size (--getpbsz).
In the script provided with r36.4.4:
-
Line 891 (Internal Dev):
pblksz=$(blockdev --getpbsz "/dev/${partition}") -
Line 905 (External Dev):
pblksz=$(blockdev --getpbsz "/dev/${partition}")
Followed by the calculation: start_offset=$((start_sector * pblksz))
The Math Error: On a 512e drive (Logical: 512, Physical: 4096):
-
Kernel reports
start_sectorin 512-byte units. -
Script retrieves
pblkszas 4096. -
Result: The script writes data to an offset 8x larger than intended (4096/512=8).
Suggested Fix: The script should use the Logical Block Size (--getss) to calculate the byte offset, matching the unit used by the partition table and sysfs.
I have verified that replacing --getpbsz with --getss resolves the issue and allows the external NVMe to be flashed and booted successfully.
Code Diff:
Bash
# Inside l4t_flash_from_kernel.sh
# OLD (Buggy)
pblksz=$(blockdev --getpbsz "/dev/${partition}")
# NEW (Fixed)
pblksz=$(blockdev --getss "/dev/${partition}")
Questions:
-
Is this a known issue with the initrd flash tools in r36.4.4?
-
Can we expect a patch for this in the next L4T release?
-
Is the use of
blockdev --getsssafe for all supported flashing scenarios (Native 4K drives vs 512 native)?
Thanks.