---
# System prepended metadata

title: 'NV Jetson Debugging, Update BootLoader (EN.)'

---

# NV Jetson Debugging, Update BootLoader (EN.)
It was observed that if a webcam is connected before power on system, the boot process will fail, resulting in a black screen. I hypothesized that the error occurs during the Unified Extensible Firmware Interface (UEFI) stage or the second-stage bootloader, preventing the third-stage bootloader and the Linux kernel from being successfully loaded.

By listening the fan speed, it was determined that the system performs an automatic reboot after the initial failure. During the reboot sequence, the fan spins at a higher speed before stabilizing at a constant rate.

Since the screen remains black with no diagnostic output, conventional debugging tools such as printf or gdb cannot be employed. An intuitive approach is to use General-Purpose Input/Output (GPIO) or Universal Asynchronous Receiver-Transmitter (UART) interfaces. However, this requires modifying the UEFI firmware to transmit boot-stage messages through the UART transmit (TX) line. Investigation into Jetson hardware indicates that, in addition to the 40-pin GPIO header, the rear micro-USB port can be utilized. Furthermore, UEFI is configured to output messages through this interface, which can be captured by a receiving device configured to a baud rate of 115200.

## Retrieving Debug Messages via Micro-USB

After connecting the micro-USB interface to the host machine, four devices (`ttyACM0` through `ttyACM3`) become available. Among these, selecting `ttyAMA0` and using a serial communication tool such as minicom successfully provides access to boot-stage debug messages.

For convenience in later analysis, these messages can be redirected to a file, allowing for subsequent inspection and troubleshooting. This method ensures reliable collection of early-stage UEFI and bootloader logs, even in scenarios where the display remains blank.

```
ls /dev/ttyACM*
sudo minicom -D /dev/ttyACM -b 115200 -8 -o -C <output_file_name>
```

And the following output is boot log
```
CPU switching to normal world boot

Jetson UEFI firmware (version 36.4.4-gcid-41062509 built on 2025-06-16T15:25:51+00:00)


I/TC: Reserved shared memory is disabled
I/TC: Dynamic shared memory is enabled
I/TC: Normal World virtualization support is disabled
I/TC: Asynchronous notifications are disabled
I/TC: WARNING: Test UEFI variable auth key is being used !
I/TC: WARNING: UEFI variable protection is not fully enabled !

[     6.318531] Camera-FW on t234-rce-safe started
TCU early console enabled.
[     6.380337] Camera-FW on t234-rce-safe ready SHA1=e2238c99 (crt 1.360 ms, total boot 63.229 ms)
3h
ASSERT [XhciDxe] /out/nvidia/bootloader/uefi/Jetson_RELEASE/edk2/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c(3154): Interval >= 1 && Interval <= 16

Resetting the system in 5 seconds.
Shutdown state requested 1
Rebooting system ...

[0000.062] I> MB1 (version: 1.4.0.4-t234-54845784-e89ea9bc)
[0000.067] I> t234-A01-1-Silicon (0x12347) Prod
[0000.072] I> Boot-mode : Coldboot
[0000.075] I> Entry timestamp: 0x00000000
[0000.078] I> last_boot_error: 0x0
[0000.082] I> BR-BCT: preprod_dev_sign: 0
[0000.085] I> rst_source: 0xb, rst_level: 0x1
[0000.089] I> Task: SE error check
[0000.093] I> Task: Bootchain select WAR set
[0000.097] I> Task: Enable SLCG
[0000.100] I> Task: CRC check
[0000.102] I> Task: Initialize MB2 params
[0000.107] I> MB2-params @ 0x40060000
[0000.110] I> Task: Crypto init
[0000.113] I> Task: Perform MB1 KAT tests
[0000.117] I> Tas
[0000.124] I> Task: MSS Bandwidth limiter settings for iGPU clients
[0000.130] I> Task: Enabling and initialization of Bandwidth limiter
[0000.136] I> No request to configure MBWT settings for any PC!
[0000.142] I> Task: Secure debug controls
[0000.146] I> Task: strap war set
[0000.149] I> Task: Initialize SOC Therm
[0000.153] I> Task: Program NV master stream id
[0000.157] I> Task: Verify boot mode
[0000.163] I> Task: Alias fuses
[not supported.
[0000.173] I> Task: Print SKU type
[0000.177] I> FUSE_OPT_CCPLEX_CLUSTER_DISABLE = 0x00000000
[0000.182] I> FUSE_OPT_GPC_DISABLE = 0x00000000
[0000.186] I> FUSE_OPT_TPC_DISABLE = 0x00000000
[0000.190] I> FUSE_OPT_DLA_DISABLE = 0x00000000
[0000.195] I> FUSE_OPT_PVA_DISABLE = 0x00000000
[0000.199] I> FUSE_OPT_NVENC_DISABLE = 0x00000000
[0000.203] I> FUSE_OPT_NVDEC_DISABLE = 0x00000000
[0000.208] I> FUSE_OPT_FSI_DISABLE = 0x00000000
[0000.212] I> FUSE_OPT_EMC_DISABLE = 0x00000000
[0000.216] I> FUSE_BOOTROM_PATCH_VERSION = 0x7
[0000.221] I> FUSE_PSCROM_PATCH_VERSION = 0x7
[0000.225] I> FUSE_OPT_ADC_CAL_FUSE_REV = 0x2
[0000.229] I> FUSE_SKU_INFO_0 = 0xd0
[0000.232] I> FUSE_OPT_SAMPLE_TYPE_0 = 0x3 PS 
[0000.236] I> FUSE_PACKAGE_INFO_0 = 0x2
[0000.240] I> SKU: Prod
[0000.242] I> Task: Boost clocks
[0000.245] I> Initializing NAFLL for BPMP_CPU_NIC.
[0000.250] I> BPMP NAFLL: fll_lock = 1, dvco_min_reached = 0
[0000.256] 42, divisor = 0
[0000.264] I> Initializing PLLC2 for AXI_CBB.
[0000.268] I> AXI_CBB : src = 35, divisor = 0
[0000.272] I> Task: Voltage monitor
[0000.275] I> VMON: Vmon re-calibration andHSIO UPHY init done
[0000.289] W> Skipping GBE UPHY config
[0000.292] I> Task: Boot device init
[0000.295] I> Boot_device: QSPI_FLASH instance: 0
[0000.300] I> Qspi clock source : pllc_out0
[0000.304] I> QSPI Flash: Macronix 64MB
[0000.308] I> QSPI-0315] I> Task: Load membct
[0000.318] I> RAM_CODE 0x4000431
[0000.321] I> Loading MEMBCT 
[0000.324] I> Slot: 0
[0000.326] I> Binary[0] block-3840 (partition size: 0x40000)
[0000.331] I> B92
[0000.338] I> Size of crypto header is 8192
[0000.342] I> strt_pg_num(3840) num_of_pgs(16) read_buf(0x40050000)
[0000.348] I> BCH of MEM-BCT-0 read from storage
[0000.353] I> BCH address is : 0x40050000
[0000.357] I> MEM-BCT-0 header integrity checEM0
[0000.367] I> component binary type is 0
[0000.370] I> strI> MEM-BCT-0 binary is read from storage
[0000.382] I> MEM-BCT-0 binary integrity check is success
[0000.387] I> Binary MEM-BCT-0 loaded successfully at 0x40040000 (0xe580)
[0000.394] I> RAM_CODE 0x4000431
[0000.399] I> RAM_CODE 0x4000431
[0000.403] Iams override
[0000.411] I> Task: Save mem-bct info
[0000.414] I> Task: Carveout allocate
[0000.418] I> RCM blob carveout will not be allocated
[0000.423] I> Update CCPLEX IST carveout from MB1-BCT
[0000.427] I> ECC region[0]: Start:0x0, End:0x0
[0000.432] I> ECC region[1]: Start:0x0, End:0x0
[0000.436] I> ECC region[2]: Start:0x0, End:0x0
[0000.440] I> ECC region[3]: Start:0x0, End:0x0
[0000.445] I> ECC region[4]: Start:0x0, End:0x0
[0000.449] I> Non-ECC region[0]: Start:0x80000000, End:0x10800000ECC region[3]: Start:0x0, End:0x0
[0000.469] I> Non-ECC region[d(CO:31) base:0x1040000000 size:0x8000000 align: 0x8000000
[0000.494] I> allocated(CO:43) base:0x103c000000 size:0x4000000 align: 0x200000
[0000.501] I> allocated(CO:39) base:0x1039e00000 size:0x2200000 align: 0x10000
[0000.508] I> allocated(CO:20) base:0x1036000000 size:0x2000000 align: 0x2000000
[0000.515] I> allocated(CO:24) base:0x1034000000 size:0x2000000 align: 0x2000000
[0000.523] I> allocated(CO:28) base:0x1032000000 size:0x2000000 align: 0x2000000
[0000.530] I> allocated(CO:29) base:0x1030000000 size:0x2000000 align: 0x2000000
[0000.537] I> allocated(CO:22) base:0x1048000000 size:0x1000000 align: 0x1000000
[0000.544] I> allocated(CO:35) base:0x1038e00000 size:0x1000000 align: 0x100000
[0000.551] I> allocated(CO:41) base:0x102f000000 size:0x1000000 align: 0x100000
[0000.558] I> allocated(CO:02) base:0x1049000000 size:0x800000 align: 0x800000
[0000.565] I> allocated(CO:03) base:0x1038000000 size:0x800000 align: 0x800000
[0000.572] I> allocated(CO:06) base:0x102e800000 size:0x800000 align: 0x800000
[0000.579] I> allocated(CO:56) base:0x102e000000 size:0x800000 align: 0x200000
[0000.586] I> allocated(CO:07) base:0x1038800000 size:0x400000 align: 0x400000
[0000.594] I> allocated(CO:33) base:0x102dc00000 size:0x400000 align: 0x200000
[0000.601] I> allocated(CO:19) base:0x102d980000 size:0x280000 align: 0x10000
[0000.607] I> allocated(CO:23) base:0x1038c00000 size:0x200000 align: 0x200000
[0000.615] I> allocated(CO:01) base:0x102d800000 size:0x100000 align: 0x100000
[0000.622] I> allocated(CO:05) base:0x102d700000 size:0x100000 align: 0x100000
[0000.629] I> allocated(CO:08) base:0x102d600000 size:0x100000 align: 0x100000
[0000.636] I> allocated(CO:09) base:0x102d500000 size:0x100000 align: 0x100000
[0000.643] I> allocated(CO:12) base:0x102d400000 size:0x100000 align: 0x100000
[0000.650] I> allocated(CO:15) base:0x102d300000 size:0x100000 align: 0x100000
[0000.657] I> allocated(CO:17) base:0x102d200000 size:0x100000 align: 0x100000
[0000.664] I> allocated(CO:27) base:0x102d100000 size:0x100000 align: 0x100000
[0000.671] I> allocated(CO:42) base:0x102d000000 size:0x100000 align: 0x100000
[0000.678] I> allocated(CO:54) base:0x102d900000 size:0x80000 align: 0x80000
[0000.685] I> allocated(CO:34) base:0x102cff0000 size:0x10000 align: 0x10000
[0000.692] I> allocated(CO:72) base:0x102cdf0000 size:0x200000 align: 0x10000
[0000.698] I> allocated(CO:47) base:0x102c800000 size:0x400000 align: 0x200000
[0000.706] I> allocated(CO:50) base:0x102c600000 size:0x200000 align: 0x100000
[0000.713] I> allocated(CO:52) base:0x102cdc0000 size:0x30000 align: 0x10000
[0000.719] I> allocated(CO:48) base:0x102cda0000 size:0x20000 align: 0x10000
[0000.726] I> allocated(CO:69) base:0x102cd80000 size:0x20000 align: 0x10000
[0000.733] I> allocated(CO:49) base:0x102cd70000 size:0x10000 align: 0x10000
[0000.740] I> NSDRAM base: 0x80000000, end: 0x102cdf0000, size: 0xfacdf0000
[0000.747] I> Task: Thermal check
[0000.750] I> Using min_chip_limit as min_tmon_limit
[0000.755] I> Using max_chip_limit as max_tmon_limit
[0000.759] I> BCT max_tmon_limit = 105
[0000.763] I> BCT min_tmon_limit = -28
[0000.766] I> BCT max_tmon_limit = 105
[0000.770] I> BCT min_tmon_limit = -28
[0000.773] I> SKU specific max_chip_limit = 105
[0000.777] I> SKU specific min_chip_limit = -28
[0000.782] I> BCT max_chip_limit = 105
[0000.785] I> BCT min_chip_limit = -28
[0000.789] I> enable_soctherm_polling = 0
[0000.793] I> max temp read = 37
[0000.795] I> min temp read = 36
[0000.798] I> Enabling thermtrip
[0000.801] I> Task: Update FSI SCR with thermal fuse data
[0000.807] I> Task: Enable WDT 5th expiry
[0000.810] I> Task: I2C register
[0000.813] I> Task: Set I2C bus freq
[0000.817] I> Task: Reset FSI
[0000.819] I> Task: Pinmux init
[0000.823] I> Task: Prod config init
[0000.826] I> Task: Pad voltage init
[0000.829] I> Task: Prod init
[0000.832] I> Task: Program rst req config reg
[0000.836] I> Task: Common rail init
[0000.841] W> DEVICE_PROD: module = 13, instance = 4 not found in device prod.
[0000.851] I> DONE: Thermal config
[0000.856] I> DONE: SOC rail config
[0000.859] W> PMIC_CONFIG: Rail: MEMIO rail config not found in MB1 BCT.
[0000.866] I> DONE: MEMIO rail config
[0000.869] I> DONE: GPU rail info
[0000.873] I> DONE: CV rail info
[0000.876] I> Task: Mem clock src
[0000.879] I> Task: Misc. board config
[0000.883] I> PMIC_CONFIG: Platform config not found in MB1 BCT.
[0000.889] I> Task: SDRAM init
[0000.892] I> MemoryType: 4 MemBctRevision: 8
[0000.899] I> MSS CAR: PLLM/HUB programming for MemoryType: 4 and MemBctRevision: 8
[0000.906] I> MSS CAR: Init PLLM
[0000.909] I> MSS CAR: Init PLLHUB
[0000.914] I> Encryption:   MTS: en, TX: en, VPR: en, GSC: en
[0000.926] I> SDRAM initialized!
[0000.929] I> SDRAM Size in Total 0x1000000000
[0000.933] I> Task: Dram Ecc scrub
[0000.936] I> Task: DRAM alias check
[0000.952] I> Task: Program NSDRAM carveout
[0000.956] I> NSDRAM carveout encryption is enabled
[0000.961] I> Program NSDRAM ck: Enable clock-mon
[0000.982] I> FMON: Fmon re-programming done
[0000.986] I> Task: Mapper init
[0000.989] I> Task: SC7 Context Init
[0000.993] I> Task: CCPLEX IST init
[0000.996] I> Task: CPU WP0
[0001.000] I> Loading MCE
[0001.002] I> Slot: 0
[0001.004] I> Binary[8] block-22784 (partition size: 0x80000)
[00 is 8192
[0001.016] I> Size of crypto header is 8192
[0001.020] I> strt_pg_num(22784) num_of_pgs(16) read_buf(0x4003e000)
[0001.027] I> BCH of MCE read from storage
[0001.031] I> BCH addresuccess
[0001.039] I> Binary magic in BCH component 0 is MTSM
[0001.044] I> component binary type is 8
[0001.048] I> Size of crypto header is 8192
[0001.051] I> strt_pg_num(22800) num_of_pgs(350) read_buf(0x40000000)
[0001.060] I> MCE binary is read from storage
[0001.064] I> MCE binary integrity check is success
[0001.069] I> Binary MCE loaded successfully at 0x40000000 (0x2baf0)
[0001.075] I> Size of crypto header is 8192
[0001.086] I> Size of crypto header is 8192
[0001.090] I> Sending WP0 mailbox command to PSC
[0001.099] I> Task: XUSB Powergate
[0001.102] I> Skipping powergate XUSB.
[0001.106] I> Task: MB1 fixed firewalls
[0001.112] W> Firewall readback mismatch
[0001.117] I> Task: Load bpmp-fw
[0001.120] I> Slot: 0
[0001.122] I> Binary[15] block-9984 (partition size: 0x180000)
[0001.128] I> Binary name: BPMP_FW
[0001.131] I> Size of crypto header is 8192
[0001.135] I> Size of crypto header is 8192
[0001.139] I> strt_pg_num(9984) num_of_pgs(16) read_buf(0x807fe000)
[0001.145] I> BCH of BPMP_FW read from storage
[0001.149] I> BCH address is : 0x807fe000
[0001.153] I> BPMP_FW header integrity check is success
[0001.158] I> Binary magic in BCH component 0 is BPMF
[0001.163] I> component binary type is 15
[0001.166] I> Size of crypto header is 8192
[0001.170] I> strt_pg_num(10000) num_of_pgs(1990) read_buf(0x80000000)
[0001.188] I> BPMP_FW binary is read from storage
[0001.194] I> BPMP_FW binary integrity check is success
[0001.199] I> Binary BPMP_FW loaded successfully at 0x80000000 (0xf8bc0)
[0001.206] I> Slot: 0
[0001.208] I> Binary[16] block-13056 (partition size: 0x400000)
[0001.213] I> Binary name: BPMP_FW_DTB
[0001.217] I> Size of crypto header is 8192
[0001.221] I> Size of crypto header is 8192
[0001.225] I> strt_pg_num(13056) num_of_pgs(16) read_buf(0x807fc000)
[0001.231] I> BCH of BPMP_FW_DTB read from storage
[0001.236] I> BCH address is : 0x807fc000
[0001.239] I> BPMP_FW_DTB header integrity check is success
[0001.245] I> Binary magic in BCH component 0 is BPMD
[0001.250] I> component binary type is 16
[0001.253] I> Size of crypto header is 8192
[0001.257] I> strt_pg_num(13072) num_of_pgs(502) read_buf(0x807bd3f0)
[0001.266] I> BPMP_FW_DTB binary is read from storage
[0001.272] I> BPMP_FW_DTB binary integrity check is success
[0001.277] I> Binary BPMP_FW_DTB loaded successfully at 0x807bd3f0 (0x3eb40)
[0001.284] I> Task: BPMP fw ast config
[0001.287] I> Task: Load psc-fw
[0001.290] I> Slot: 0
[0001.292] I> Binary[17] block-21248 (partition size: 0xc0000)
[0001.298] I> Binary name: PSC_FW
[0001.301] I> Size of crypto header is 8192
[0001.305] I> Size of crypto header is 8192
[0001.309] I> strt_pg_num(21248) num_of_pgs(16) read_buf(0x80ffe000)
[0001.315] I> BCH of PSC_FW read from storage
[0001.319] I> BCH address is : 0x80ffe000
[0001.323] I> PSC_FW header integrity check is success
[0001.328] I> Binary magic in BCH component 0 is PFWP
[0001.333] I> component binary type is 17
[0001.337] I> Size of crypto header is 8192
[0001.340] I> strt_pg_num(21264) num_of_pgs(591) read_buf(0x80fb4200)
[0001.350] I> PSC_FW binary is read from storage
[0001.355] I> PSC_FW binary integrity check is success
[0001.360] I> Binary PSC_FW loaded successfully at 0x80fb4200 (0x49df0)
[0001.366] I> Task: Load nvdec-fw
[0001.369] I> Slot: 0
[0001.371] I> Binary[7] block-6400 (partition size: 0x100000)
[0001.377] I> Binary name: NVDEC
[0001.380] I> Size of crypto header is 8192
[0001.384] I> Size of crypto header is 8192
[0001.388] I> strt_pg_num(6400) num_of_pgs(16) read_buf(0x800fe000)
[0001.394] I> BCH of NVDEC read from storage
[0001.398] I> BCH address is : 0x800fe000
[0001.402] I> NVDEC header integrity check is success
[0001.407] I> Binary magic in BCH component 0 is NDEC
[0001.411] I> component binary type is 7
[0001.415] I> Size of crypto header is 8192
[0001.419] I> strt_pg_num(6416) num_of_pgs(560) read_buf(0x80000000)
[0001.428] I> NVDEC binary is read from storage
[0001.433] I> NVDEC binary integrity check is success
[0001.438] I> Binary NVDEC loaded successfully at 0x80000000 (0x46000)
[0001.444] I> Size of crypto header is 8192
[0001.456] I> Task: Load tsec-fw
[0001.459] I> TSEC-FW load support not enabled
[0001.463] I> Task: GPIO interrupt map
[0001.467] I> Task: SC7 context save
[0001.470] I> Slot: 0
[0001.472] I> Binary[27] block-0 (partition size: 0x100000)
[0001.477] I> Binary name: BR_BCT
[0001.480] I> Size of crypto header is 8192
[0001.484] I> Size of crypto header is 8192
[0001.488] I> Size of crypto header is 8192
[000001.498] I> BR_BCT binary is read from storage
[0001.503] I> BR_BCT binary integrity check is success
[0001.507] I> Binary BRlot: 0
[0001.516] I> Binary[13] block-23808 (partition size: 0x30000)
[0001.521] I> Binary name: SC7-FW
[0001.524] I> Size of crypto header is 8192
[0001.528] I> Size of crypto header is 8192
[0001.532] I> Size of crypto header is 8192
[0001.536] I> Size of crypto header is 8192
[0001.540] I> strt_pg_num(23808) num_of_pgs(16) read_buf(0xa0002000)
[0001.546] I> BCH of SC7-FW read from storage
[0001.551] I> BCH address is : 0xa0002000
[0001.554] I> SC7-FW header integrity check is success
[0001.559] I> Binary magic in BCH component 0 is WB0B
[0001.564] I> component binary type is 13
[0001.568] I> Size of crypto header is 8192
[0001.572] I> strt_pg_num(23824) num_of_pgs(349) read_buf(0xa0004000)
[0001.580] I> SC7-FW binary is read from storage
[0001.585] I> SC7-FW binary integrity check is success
[0001.590] I> Binary SC7-FW loaded successfully at 0xa0004000 (0x2ba00)
[0001.596] I> Slot: 0
[0001.598] I> Binary[22] block-24192 (partition size: 0x30000)
[0001.604] I> Binary name: PSC_RF
[0001.607] I> Size of crypto header is 8192
[0001.611] I> Size of crypto header is 8192
[0001.615] I> Size of crypto header is 8192
[0001.618] I> Size of crypto header is 8192
[0001.622] I> strt_pg_num(24192) num_of_pgs(16) read_buf(0xa002fa00)
[0001.629] I> BCH of PSC_RF read from storage
[0001.633] I> BCH address is : 0xa002fa00
[0001.637] I> PSC_RF header integrity check is success
[0001.641] I> Binary magic in BCH component 0 is PSCR
[00(224) read_buf(0xa0031a00)
[0001.662] I> PSC_RF binary is read a00 (0x1be60)
[0001.680] I> Task: Save WP0 payload to SC7 ctx
[0001.685] I> Task: Load MB2rf binary to SC7 ctx
[0001.689] I> Slot: 0
[0001.691] I> Binary[14] block-24576 (partition size: 0x20000)
[0001.697] I> Binary name: MB2_RF
[0001.700] I> Size of crypto header is 8192
[0001.704] I> Size of crypto header is 8192
[0001.708] I> Size of crypto header is 8192
[0001.712] I> Size of crypto header is 8192
[0001.715] I> strt_pg_num(24576) num_of_pgs(16) read_buf(0xa00d5d10)
[0001.722] I> BCH of MB2_RF read from storage
[0001.726] I> BCH address is : 0xa00d5d10
[0001.730] I> MB2_RF header integrity check is success
[0001.735] I> Binary magic in BCH component 0 is MB2R
[0001.739] I> component binary type is 14
[0001.743] I> Size of crypto header is 8192
[0001.747] I> strt_pg_num(24592) num_of_pgs(224) read_buf(0xa00d7d10)
[0001.755] I> MB2_RF binary is read from storage
[0001.759] I> MB2_RF binary integrity check is success
[0001.764] I> Binary MB2_RF loaded successfully at 0xa00d7d10 (0x1bf60)
[0001.771] I> Task: Save fuse alias data to SC7 ctx
[0001.775] I> Task: Save PMIC data to SC7 ctx
[0001.779] I> Task: Save Pinmux data to SC7 ctx
[0001.784] I> Task: Save Pad Voltage data to SC7 ctx
[0001.788] I> Task: Save controller prod data to SC7 ctx
[0001.793] I> Task: Save prod cfg data to SC7 ctx
[0001.798] I> Task: Save I2C bus freq data to SC7 ctx
[0001.803] I> Task: Save SOCTherm data to SC7 ctx
[0001.807] I> Task: Save FMON data to SC7 ctx
[0001.811] I> Task: Save VMON data to SC7 ctx
[0001.815] I> Task: Save TZDRAM data to SC7 ctx
[0001.820] I> Task: Save GPIO int data to SC7 ctx
[0001.824] I> Task: Save clock data to SC7 ctx
[0001.828] I> Task: Save debug data to SC7 ctx
[0001.832] I> Task: Save MBWT data to SC7 ctx
[0001.840] I> SC7 context save done
[0001.844] I> Task: Load MB2/Applet/FSKP
[0001.847] I> Loading MB2
[0001.850] I> Slot: 0
[0001.852] I> Binary[6] block-8448 (partition size: 0x80000)
[0001.857] I> Binary name: MB2
[0001.860] I> Size of crypto header is 8192
[0001.864] I> Size of crypto header is 8192
[0001.868] I> strt_pg_num(8448) num_of_pgs(16) read_buf(0x8007e000)
[0001.874] I> BCH of MB2 read from storage
[0001.878] I> BCH address is : 0x8007e000
[0001.882] I> MB2 header integrity check is success
[0001.886] I> Binary magic in BCH component 0 is MB2B
[0001.891] I> component binary type is 6
[0001.895] I> Size of crypto header is 8192
[0001.899] I> strt_pg_num(8464) num_of_pgs(846) read_buf(0x80000000)
[0001.910] I> MB2 binary is read from storage
[0001.915] I> MB2 binary integrity check is success
[0001.919] I> Binary MB2 loaded successfully at 0x80000000 (0x69a70)
[0001.926] I> Task: Map CCPLEX SHARED carveout
[0001.930] I> Task: Prepare MB2 params
[0001.934] I> Task: Dram ecc test
[0001.937] I> Task: Misc NV security settings
[0001.941] I> NVDEC sticky bits programming done
[0001.945] I> Successfully powergated NVDEC
[0001.949] I> Task: Disable/Reload WDT
[0001.953] I> Task: Program misc carveouts
[0001.957] I> Program IPC carveouts
[0001.960] I> Task: Disable SCPM/POD reset
[0001.964] I> SLCG Global override status := 0x0
[0001.968] I> MB1: MSS reconfig completed
I> MB2 (version: 0.0.0.0-t234-54845784-22833a33)
I> t234-A01-1-Silicon (0x12347)
I> Boot-mode : Coldboot
I> Emulation: 
I> Entry timestamp: 0x001e7647
I> Regular heap: [base:0x40040000, size:0x10000]
I> DMA heap: [base:0x102e000000, size:0x800000]
I> Task: SE error check
I> Task: Crypto init
I> Task: MB2 Params integrity check
I> Task: Enable CCPLEX WDT 5th expiry
I> Task: ARI update carveout TZDRAM
I> Task: Configure OEM set LA/PTSA values
I> Task: Check MC errors
I> Task: SMMU external bypass disable
I> Task: Enable hot-plug capability
I> Task: TZDRAM heap init
I> Task: PSC mailbox init
I> Task: Enable clock for external modules
I> Task: Measured Boot init
I> Task: fTPM silicon identity init
I> fTPM is not enabled.
I> Task: OEM SC7 context save init
I> Task: I2C register
I> Task: Map CCPLEX_INTERWORLD_SHMEM carveout
I> Task: Program CBB PCIE AMAP regions
I> Task: Boot device init
I> Boot_device: QSPI_FLASH instance: 0
I> QSPI-0l initialized successfully
I> Secondary storage device: QSPI_FLASH instance: 0
I> Secondary storage device: SDMMC_USER instance: 3
I> sdmmc HS400 mode enabled
I> Task: Partition Manager Init
I> strt_pg_num(1) num_of_pgs(1) read_buf(0x102e001000)
I> strt_pgm(131039) num_of_pgs(32) read_buf(0x102e001200)
I> Found 60 partitions in QSPI_FLASH (instance 0)
W> Cannot find any partition table for 00000003
W> PARTITION_MANAGER: Failed to publish partition.
I> Found 15 partitions in SDMMC_USER (instance 3)
I> Task: Pass DRAM ECC PRL Flag to FSI
I> Task: Load and authenticate registered FWs
I> Task: Load AUXP FWs
I> Successfully regisCE FW load task with MB2 loader
I> Successfully register DCE FW load task with MB2 loader
I> Unpowergating APE
I> Unpowergate done
I> Successfully register APE FW load task with MB2 loader
I> Skipping FSI FW load
I> Successfully register XUSB FW load task with MB2 loader
I> Successfully register PVA FW load task with MB2 loader
I> Partition name: A_spe-fw
I> Size of partition: 589824
I> Binary@ device:3/0 block-55040 (partition size: 0x90000), name: A_spe-fw
I> strt_pg_num(55040) num_of_pgs(16) read_buf(0x40067a30)
I> strt_pg_num(55056) num_of_pgs(512) read_buf(0x102d600000)
I> Partition name: A_rce-fw
I> Size of partition: 1048576
I> Binary@ device:3/0 block-56192 (partition size) read_buf(0x40067a30)
I> strt_pg_num(56208) num_of_pgs(880) reinary spe loaded successfully at 0x102d600000
I> Partition name: A_dce-fw
I> Size of partition: 5242880
I> Binary@ device:3/0_pg_num(44800) num_of_pgs(16) read_buf(0x40067a30)
I> rce: Authentication Finalize Done
I> Binary rce loaded successfully at 0x102d200000
I> Successfully register RCE FW context save task wtrt_pg_num(44816) num_of_pgs(1) read_buf(0x102e1403d8)
I> strt_a-blob integrity check is success.
I> strt_pg_num(44824) num_of_pgs(512) read_buf(0x102e0003c0)
I> strt_pg_num(45336) num_of_p 0x1036000000
I> version 1 Bin 1 BCheckSum 0 content_size 0 Conerved11 0
I> strt_pg_num(45848) num_of_pgs(512) read_buf(0x102e0803c0)
I> dce : decompressed to 12067600 bytes
I> dce: plain binary integrity check is success
I> Partition name: A_adsp-fw
I> Size of partition: 2097152
I> Binary@ device:strt_pg_num(58240) num_of_pgs(16) read_buf(0x40067a30)
I> strt_ 0x1036000000
I> Partition name: A_xusb-fw
I> Size of partition: 262144
I> Binary@ device:3/0 block-9472 (partition size: 0x40000), name: A_xusb-fw
I> strt_pg_num(9472) num_of_pgs(16) read_buf(0x40067a30)
I> strt_pg_num(9488) num_of_pgs(312) read_buf(0x102d700000)
I> ape: Authentication Finalize Done
I> Binary ape loaded successfully at 0x1038800000
I> Successfully register APE FW context save task with MB2 loader
I> Partition name: A_pva-fw
I> Size of partition: 262144
I> Binary@ device:3/0 block-62336 (partition size: 0x40000), name: A_pva-fw
I> strt_pg_num(62336) num_of_pgs(16) read_buf(0x40067a30)
I> xusb: Authentication Finalize Done
I> Binary xusb loaded successfully at 0x102d700000
I> Successfully register XUSB FW context save task with MB2 loader
I> pva-fw : oem authentication of header done
I> strt_pg_num(62352) num_of_pgs(1) read_buf(0x102e1403d8)
I> strt_pg_num(62352) num_of_pgs(8) read_buf(0x102e1403d8)
I> pva-fw : meta-blob integrity check is success.
I> strt_pg_num(62360) num_of_pgs(512) read_buf(0x102e0003c0)
I> pva-fw : will be decompressed at 0x102d980000
I> version 1 Bin 1 BCheckSum 0 content_size 0 Content ChkSum 1 reserved_00  0
I> Reserved10 0 BlockMaxSize 5 Reserved11 0
I> pva-fw : decompressed to 2156512 bytes
I> pva-fw: plain binary integrity check is success
I> pva-fw: Authentication Finalize Done
I> Binary pva-fw loaded successfully at 0x102d980000
I> Successfully register PVA FW context save task with MB2 loader
I> Task: Check MC errors
I> Task: Carveout setup
I> Program remaining OEM carveouts
I> Task: Enable FSITHERM
I> Task: Enable FSI VMON
I> FSI VMON: FSI Vmon re-calibration and fine tuning done
I> Task: Validate FSI Therm readings
I> Task: Restore XUSB sec
I> Task: Enable FSI SE clock
I> Enable FSI-SE clock...
I> Task: Initialize SBSA UART CAR
I> Task: Initialize CPUBL Params
I> CPUBL-params @ 0x1032000000
I> Task: Ratchet update
W> Skip ratchet update - OPTIN fuse not set
I> Task: Prepare eeprom data
I> Task: Revoke PKC fuse
I> PKC revoke fuse burn not requested
I> Task: FSI padctl context save
I> Task: Unpowergate APE
W> mb2_unpowergate_ape: skip! APE is in unpowergated state
I> Task: Memctrl reconfig pending clients
I> Task: OEM firewalls
I> OEM firewalls configured
I> Task: Powergate APE
I> Powergating APE
I> Powergate done
I> Task: OEM firewall restore saved settings
I> Task: Unhalt AUXPs
I> Unhalting SPE..
I> Enabling combined UART 
spe: early_init
vic initialized
tsc initialized
aon lic initialized
spe: tag is 524398t
scheduler initialized
aon hsp initialized
tag initialized
tcu initialized
bpmp ipc initialized
spe: late init
cpu_nic clock initialized
apb clock initialized
pm initialized
bpmp hsp initialized
top1 hsp initialized
ccplex ipc initialized
spe: start scheduler

I> Task: Trigger mailbox for PSC-BL1 exit
I> Sending opcode 0x4d420802 to psc
I> Received ACK from psc
I> Task: Start secure NOR provision
I> Skip Secure NOR provisioning
I> Task: Trigger load FSI keyblob
I> Skipping FSI key blob copy
I> Task: Complete load FSI keyblob
I> Skipping FSI key blob copy
I> Task: MB2-PSC_FW Key Manager Init
I> Sending opcode OP_PSC_KEY_MANAGER to psc-fw
I> Sending opcode 0x4b45594d t
hwwdt_init: WDT boot cfg 0x710010 sts 0x10
bpmp: socket 0
bpmp: base binary md5 is da583751bbfe2b7f6e204562d97ff39e
bpmp: combined binary md5 is 39f77b2baaf3f0522607569dd3ae9a48
bpmp: firmware tag is 39f77b2baaf3f0522607-da583751bbf
initialized vwdt
initialized mail_early
initialized fuse
initialized vfrel
initialized adc
fmon_populate_monitors: found 199 monitors
initialized fmon
initialized mc
initialized reset
initialized uphy_early
initialized emc_early
initialized pm
465 clocks registered
initialized clk_mach
initialized clk_cal_early
initialized clk_mach_early_config
initialized io_dpd
initialized soctherm
initialized regime
initialized i2c
vrmon_dt_init: vrmon node not found
vrmon_chk_boot_state: found 0 rail monitors
initialized vrmon
initialized regulator
o psc
I> Received ACK from psc
I> Task: Unhalt FSI
I> FSI unhalt skipped
I> Task: Unhalt AUXPs
I> Unhalting RCE
I> RCE unhalt successful
I> Unhalting DCE
I> DCE unhalt successful
I> APE unhalt skipped
I> Task: Load HV/CPUBL
I> Task: Load TOS
I> Task: Trigger load TS[     2.609271] Camera-FW on t234-rce-safe started
initialized avfs_clk_platform
initialized powergate
TCU early console enabled.
EC leyinitialized dvs
initialized clk_mach_config
suspend progress: 0x80000000
initialized suspend
initialized strap
initialized mce_dbell
blob

I> Sending opcode 0x53535452 to psc
I> Sent opcode to psc
I> Task: Load and authenticate registered FWs
I> Partition name: A_cpu-bootloader
I> Size of partition: 3670016
I> Binary@ device:3/0 block-24832 (partition size: 0x380000), name: A_cpu-bootloader
DCE Started
I> strt_pg_num(24832) num_of_pgs(16) read_buf(0x40067a30)
I> cpubl : oem authentication of header done
DCE_R5_Init
I> strt_pg_num(24848) num_of_pgs(1) read_buf(0x102e143f98)
I> strt_pg_num(24848) num_of_pgs(8) read_buf(0x102e143f98)
I> cpubl : meta-blob integrity check isinitialized emc
initialized emc_mrq
MPU enabled
 success.
I> strt_pg_num(24856)initialized clk_cal
initialized uphy_dt
initialized uphy_mrq
HSIO UPHY reset has been de-asserted 0x0
 num_oinitialized uphy
f_pgs(512) r
swdtimer_init: reg polling start w period 47 ms
initialized swdtimer
initialized hwwdt_late
initialized bwmgr
initialized thermal_host_trip
initialized thermal_mrq
initialized oc_mrq
initialized reset_mrq
initialized mail_mrq
initialized fmon_mrq
initialized clk_mrq
initialized avfs_mrq
initialized i2c_mrq
initialized tag_mrq
initialized bwmgr_mrq
initialized console_mrq
missing prod DT calibration data for 199 fmons
initialized clk_sync_fmon_post
DCE_SW_Init
80)
I> strt_pg_num(25368) num_of_pgs(512) read_buf(0x10initialized clk_cal_late
initialized noc_late
initialized cvc
2e043f80)
I> cpubl : will be decompreinitialized avfs_clk_mach_post
initialized avfs_clk_platform_post
initialized cvc_late
initialized rm
initialized console_late
handling unreferenced clks
enable can1_core
enable can1_host
enable can2_core
enable can2_host
enable pwm3
enable mss_encrypt
enable maud
enable pllg_ref
enable dsi_core
enable aza_2xbit
enable pllc4_muxed
enable sdmmc4_axicif
enable xusb_ss
enable xusb_fs
enable xusb_falcon
enable xusb_core_mux
enable dsi_lp
enable sdmmc_legacy_tm
initialized clk_mach_post
initialized pg_post
[     2.811175] Camera-FW on t234-rce-safe ready SHA1=e2238c99 (crt 12.427 ms, total boot 215.403 ms)
initialized regulator_post
initialized profile
initialized mrq
initialized patrol_scrubber
initialized cactmon
initialized extras_post
bpmp: init complete
ssed at 0x102c800000
I> version 1 Bin 1 BCheckSum 0 content_size 0 Content ChkSum 1 reserved_00  0
I> Reserved10 0 BlockMaxSize 5 Reserved11 0
I> strt_pg_num(25880) num_of_pgs(512) read_buf(0x102e083f80)
I> strt_pg_num(26392) num_of_pgs(512) read_buf(0x102e0c3f80)
I> strt_pg_num(26904) num_of_pgs(512) read_buf(0x102e103f80)
I> strt_pg_num(27416) num_of_pgs(512) read_buf(0x102e003f80)
I> strt_pg_num(27928) num_of_pgs(512) read_buf(0x102e043f80)
I> strt_pg_num(28440) num_of_pgs(512) read_buf(0x102e083f80)
I> strt_pg_num(28952) num_of_pgs(512) read_buf(0x102e0c3f80)
I> strt_pg_num(29464) num_of_pgs(512) read_buf(0x102e103f80)
I> strt_pg_num(29976) num_of_pgs(512) read_buf(0x102e003f80)
Admin Task Init
Admin Task Init complete
Print Task Init
RM Task Init
SHA Task Init
Admin Task Started
I> strt_pg_num(30488) num_of_pgs(512) read_buf(0x102e043f80)
DCE SC7 SHA Enabled
RM Task Started
RM Task Running
Print Task Started
Print Task Running
SHA Task Started
DCE: FW Boot Complete
Admin Task Running
Sf(0x102e083f80)
I> cpubl : decompressed to 3661952 bytes
I> cpubl: plain binary integrity check is success
I> Partition name: A_secure-os
I> Size of partition: 4194304
I> Binary@ device:3/0 block-32000 (partition size: 0x400000), name: A_secure-os
I> strt_pg_num(32000) num_of_pgs(16) read_buf(0x40067a30)
I> strt_pg_num(32016) num_of_pgs(3672) read_buf(0x103fd35000)
I> MB2-params @ 0x40060000
I> NSDRAM carveout base: 0x80000000, size: 0xfacdf0000
I> cpubl_params: nsdram: carveout: 1, encryption: 1
I> cpubl: Authentication Finalize Done
I> Binary cpubl loaded ne
I> Binary tos loaded successfully at 0x103fd35000
I> Relocating OP-TEE dtb from: 0x103feff180 to 0x103c040020, size: 0x2754
I> [0] START: 0x80000000, SIZE: 0xfacdf0000
I> [1] START: 0x1E dtb finished.
I> Partition name: A_eks
I> Size of partition: 262144
I> Binary@ device:3/0 block-44288 (partition size: 0x40000), name: A_eks
I> strt_pg_num(44288) num_of_pgs(16) read_bufc020000)
I> eks: Authentication Finalize Done
I> Binary eks lo0) @ VA:0x103c020000
I> Task: Add cpubl params integrity check
I> Added cpubl params digest.
I> Task: Prepare TOS params
I> Setting EKB blob info to OPTEE dtb finished.
I> Setting OPTEE arg3: 0x103c040020
I> NVRNG: Health check success
I> NVRNG: Health check success
I> Task: OEM SC7 context save
I> OEM sc7 context saved
I> Task: Disable MSS perf stats
I> Task: Program display sticky bits
I> Task: Storage device deinit
I> Task: SMMU init
I> Task: Program GICv3 registers
I> Task: Audit firewall settings
I> Task: Bootchain failure check
I> Current Boot-Chain Slot: 0
I> BR-BCT Boot-Chain is 1, and status is 1. Set UPDATE_BRBCT bit to 1
I> Task: Burn RESERVED_ODM0 fuse
I> Task: Lock fusing
I> Task: Clear dec source key
I> MB2 finished

NOTICE:  BL31: v2.8(release):e12e3fa93
NOTICE:  BL31: Built : 17:14:28, Jan  7 2025
I/TC: 
I/TC: Non-secure external DT found
I/TC: OP-TEE version: 4.2 (gcc version 11.3.0 (BuildrootTC: WARNING: This OP-TEE configuration might be insecure!
I/TC: WARNING: Please check https://optee.readthedocs.io/en/latest/architecture/porting_guidelines.html
I/TC: Primary CPU initializing
I/TC: Test OEM keys are being used. This is insecure for shipping products!
I/TC: fTPM ID is not enabled.
I/TC: ftpm-helper PTA: fTPM DT or EKB is not available. fTPM provisioning is not supported.
I/TC: Primary CPU switching to normal world boot

Jetson UEFI firmware (version 36.4.3-gcid-38968081 built on 2025-01-08T01:18:20+00:00)

I/TC: Reserved shared memory is disabled
I/TC: Dynamic shared memory is enabled
I/TC: Normal World virtualization support is disabled
I/TC: Asynchronous notifications are disabled
I/TC: WARNING: Test UEFI variable auth key is being used !
I/TC: WARNING: UEFI variable protection is not fully enabled !

[     6.143531] Camera-FW on t234-rce-safe started
TCU early console enabled.
[     6.205341] Camera-FW on t234-rce-safe ready SHA1=e2238c99 (crt 1.367 ms, total boot 63.240 ms)

3h

ASSERT [XhciDxe] /out/nvidia/bootloader/uefi/Jetson_RELEASE/edk2/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c(3154): Interval >= 1 && Interval <= 16

Resetting the system in 5 seconds.
Shutdown state requested 1
Rebooting system ...
MMof crypto header is 8192
[0000.344] I> strt_pg_num(66816) num_of_pgs(16) read_buf(0x40050000)
[0000.350] I> BCH of MEM-BCT-0 read from storage
...

I/TC: Reserved shared memory is disabled
I/TC: Dynamic shared memory is enabled
I/TC: Normal World virtualization support is disabled
I/TC: Asynchronous notifications are disabled
I/TC: WARNING: Test UEFI variable auth key is being used !
I/TC: WARNING: UEFI variable protection is not fully enabled !
[     6.145784] Camera-FW on t234-rce-safe started
TCU early console enabled.
[     6.207503] Camera-FW on t234-rce-safe ready SHA1=e2238c99 (crt 1.357 ms, total boot 63.140 ms)
3h
ASSERT [XhciDxe] /out/nvidia/bootloader/uefi/Jetson_RELEASE/edk2/MdeModulePkg/Bus/Pci/XhciDxe/XhciSched.c(3154): Interval >= 1 && Interval <= 16

Resetting the system in 5 seconds.
Shutdown state requested 1
Rebooting system ...
```
Based on the captured messages, the system halts after an ASSERT, indicating a crash in the xHCI USB driver (Xhci) within UEFI.

After the ASSERT, the firmware forces a reboot after five seconds, entering an infinite reboot loop. The observable symptom is a persistent black screen, and the operating system never boots. From the reported interval values, it appears that a USB endpoint returned an invalid polling interval—or the value was parsed into an illegal range by UEFI—thereby triggering the ASSERT.

Regarding valid intervals: according to the Universal Serial Bus (USB) 2.0 specification, for isochronous endpoints at full-/high-speed, the common normalized range for bInterval is 1 to 16, representing a period of $2^{(n-1)}$ microframes. For interrupt endpoints at full/low-speed, bInterval can range from 1 to 255. Detailed requirements are specified in USB 2.0 and the xHCI 1.1 specification.

Therefore, the code in question is likely validating whether the connected USB 2.0 device adheres to the specification. If the interval is out of range, the assertion is triggered.

## Dig in boot log
According to NVIDIA’s official documentation, the boot sequence is as follows:

- BootROM
- PSCROM
- MB1
- MB2
- UEFI

Next, I try to dig in the captured boot messages.

At the beginning, there is a large volume of MB1/MB2 output, including loading of BPMP_FW, PSC_FW, and RCE/DCE/XUSB, which are part of the Jetson boot flow. SDRAM initialization and clock/thermal monitoring are also shown. No error messages are present, so it appears that nothing failed during the MB1/MB2 stages.

Subsequently, several warnings appear, likely originating from OP-TEE, such as “Test UEFI variable,” which looks like development/testing keys or similar artifacts.

After MB1/MB2 completes, control transfers to Jetson UEFI. During the UEFI phase, the built-in xHCI driver (XhciDxe) initializes and enumerates peripherals such as keyboards and USB flash drives—presumably to support pre-boot I/O or USB boot. Based on the ASSERT information, this bootloader is developed using the EDK II framework. Once the firmware enters UEFI, it crashes (this failure likely occurs very early in the UEFI stage, which explains why no BIOS/firmware setup screen is ever displayed).

```
Jetson UEFI firmware (version 36.4.x ...)
ASSERT [XhciDxe] ... XhciSched.c(3154): Interval >= 1 && Interval <= 16
Resetting the system in 5 seconds.
```

I connected the webcam to my Fedora laptop and confirmed that the system boots normally. I hypothesize that the Linux kernel’s xHCI/USB driver is more tolerant of out-of-spec descriptor values. Consequently, I examined the relevant Linux kernel xHCI/USB driver code with the goal of porting its handling logic to EDK II (UEFI), applying a patch, and then replacing the bootloader on the Jetson platform to resolve this issue.

### About Linux Kernel xHCI/USB
In `drivers/usb/core/config.c`
```c
/*
	 * Fix up bInterval values outside the legal range.
	 * Use 10 or 8 ms if no proper value can be guessed.
	 */
	i = 0;		/* i = min, j = max, n = default */
	j = 255;
	if (usb_endpoint_xfer_int(d)) {
		i = 1;
		switch (udev->speed) {
		case USB_SPEED_SUPER_PLUS:
		case USB_SPEED_SUPER:
		case USB_SPEED_HIGH:
			/*
			 * Many device manufacturers are using full-speed
			 * bInterval values in high-speed interrupt endpoint
			 * descriptors. Try to fix those and fall back to an
			 * 8-ms default value otherwise.
			 */
			n = fls(d->bInterval*8);
			if (n == 0)
				n = 7;	/* 8 ms = 2^(7-1) uframes */
			j = 16;

			/*
			 * Adjust bInterval for quirked devices.
			 */
			/*
			 * This quirk fixes bIntervals reported in ms.
			 */
			if (udev->quirks & USB_QUIRK_LINEAR_FRAME_INTR_BINTERVAL) {
				n = clamp(fls(d->bInterval) + 3, i, j);
				i = j = n;
			}
			/*
			 * This quirk fixes bIntervals reported in
			 * linear microframes.
			 */
			if (udev->quirks & USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL) {
				n = clamp(fls(d->bInterval), i, j);
				i = j = n;
			}
			break;
		default:		/* USB_SPEED_FULL or _LOW */
			/*
			 * For low-speed, 10 ms is the official minimum.
			 * But some "overclocked" devices might want faster
			 * polling so we'll allow it.
			 */
			n = 10;
			break;
		}
	} else if (usb_endpoint_xfer_isoc(d)) {
		i = 1;
		j = 16;
		switch (udev->speed) {
		case USB_SPEED_HIGH:
			n = 7;		/* 8 ms = 2^(7-1) uframes */
			break;
		default:		/* USB_SPEED_FULL */
			n = 4;		/* 8 ms = 2^(4-1) frames */
			break;
		}
	}
	if (d->bInterval < i || d->bInterval > j) {
		dev_notice(ddev, "config %d interface %d altsetting %d "
		    "endpoint 0x%X has an invalid bInterval %d, "
		    "changing to %d\n",
		    cfgno, inum, asnum,
		    d->bEndpointAddress, d->bInterval, n);
		endpoint->desc.bInterval = n;
	}

```
The semantic meaning of bInterval in Universal Serial Bus (USB) differs by link speed and transfer type. Some device vendors may populate this field incorrectly—for example, applying full-speed (FS) semantics at high-speed (HS) or SuperSpeed (SS), or specifying values in microseconds or microframes rather than powers of two as required by the specification.

The code above implements fault tolerance: it infers a plausible correct value or falls back to a reasonable default instead of failing hard as EDK II currently does.

Here, i denotes the lower bound of the valid range (min), j denotes the upper bound (max), and n denotes the default or the post-inference value that should be programmed.

(The code at the end …)
```c
if (d->bInterval < i || d->bInterval > j) {
		dev_notice(ddev, "config %d interface %d altsetting %d "
		    "endpoint 0x%X has an invalid bInterval %d, "
		    "changing to %d\n",
		    cfgno, inum, asnum,
		    d->bEndpointAddress, d->bInterval, n);
		endpoint->desc.bInterval = n;
	}
```
If the value falls outside the `min ~ max` range, bInterval is set to n.

Accordingly, the current plan is to relax the bootloader’s handling of bInterval. To do so, we must obtain the bootloader’s source code, implement the necessary modifications, and then replace the original bootloader with the patched version.

### Env Build
```shell
# sudo systemctl enable --now docker
# sudo groupadd -f docker
# sudo usermod -aG docker $USER
# newgrp docker 
```
Then according to NVIDIA-edk2 wiki
```shell
# Point to the Ubuntu-22 dev image
export EDK2_DEV_IMAGE="ghcr.io/tianocore/containers/ubuntu-22-dev:latest"

# Required
export EDK2_USER_ARGS="-v \"${HOME}\":\"${HOME}\" -e EDK2_DOCKER_USER_HOME=\"${HOME}\""

# Required, unless you want to build in your home directory.
# Change "/build" to be a suitable build root on your system.
export EDK2_BUILD_ROOT="/build"
export EDK2_BUILDROOT_ARGS="-v \"${EDK2_BUILD_ROOT}\":\"${EDK2_BUILD_ROOT}\""

# Create the alias
alias edk2_docker="docker run -it --rm -w \"\$(pwd)\" ${EDK2_BUILDROOT_ARGS} ${EDK2_USER_ARGS} \"${EDK2_DEV_IMAGE}\""
```

### Modify and Compile
Next, we modify the code, starting with a minimal viable solution. Following the Linux kernel’s approach, the overarching idea is to infer a reasonable value for `bInterval`. Here, we adopt a similar strategy and directly use the following.

```diff
else if ((DeviceSpeed == EFI_USB_SPEED_HIGH) || (DeviceSpeed == EFI_USB_SPEED_SUPER)) {
          Interval = EpDesc->Interval;
-         ASSERT (Interval >= 1 && Interval <= 16);
+         if(Interval < 1 || Interval > 16) {
+         Interval = (Interval < 1) ? 1 : 16;
          }
```

We enforce the interval to fall within a predefined range and first verify whether this approach introduces any issues. We will subsequently integrate the Linux kernel’s method.

==TODO: Port and adopt the Linux kernel approach==

After completing the modifications, execute the following steps to compile and generate the binary.

```
edk2_docker edk2-nvidia/Platform/NVIDIA/Jetson/build.sh --init-defconfig edk2-nvidia/Platform/NVIDIA/Jetson/Jetson.defconfig
```
The compiled binaries are located in the images directory. Within this directory, multiple .dtbo files are present, along with two key artifacts:

- BOOTAA64_Jetson_RELEASE.efi
- uefi_Jetson_RELEASE.bin

It is clear that the .efi and .bin files are the primary outputs required for deployment. According to the NVIDIA Jetson Linux Developer Guide, their purposes are as follows:
- `BOOTAA64.efi` is the Jetson Linux OS Launcher UEFI application. It is similar to `BOOTX64.efi` found on x86 platforms. This UEFI application resides in the ESP (EFI System Partition) and is invoked by the UEFI firmware (`uefi*.bin`). Its role is to locate the kernel, device tree blob (DTB), and initrd, and then transfer control to Linux. The default loader on Jetson is L4TLauncher.
- `uefi*.bin` is the CPU bootloader for Jetson, serving as the UEFI firmware itself (implemented using the EDK II framework). It is flashed into the Jetson bootloader partition (with Slot A and Slot B available, enabling rollback in case one bootloader fails). Its responsibilities include hardware initialization, loading various DXE drivers, managing UEFI NVRAM variables, handling capsule updates and A/B rollback, and—based on the boot order—launching the operating system loader. In this context, `BOOTAA64.efi` is invoked by `uefi*.bin`.

After modifying the Xhci-related code, the primary artifact we produce is `uefi*.bin.`

Next, we need L4T, which includes packaging/flashing/update tools capable of handling details such as Jetson models, partition tables, and A/B slots. These tools organize the prepared UEFI and peripheral components—such as DTB, DTBO, and the loader—into the correct image or capsule, and then update the bootloader using Jetson’s internal tooling.

First, copy `uefi*.bin` and `BOOTAA64.efi` into the bootloader directory under the L4T project, and then begin packaging.


```shell
# sudo ./l4t_generate_soc_bup.sh -e t23x_agx_bl_spec t23x
```
Use the above command to generate a BUP (Bootloader Update Payload).

Then, use the BUP to create a UEFI capsule.
```shell
# ./generate_capsule/l4t_generate_soc_capsule.sh \
    -i bootloader/payloads_t23x/bl_only_payload \
    -o TEGRA_BL.Cap t234
```
After obtaining `TEGRA_BL.Cap`, place it onto the Jetson AGX Orin.

On the Jetson AGX Orin, run the following command to update the bootloader. The new bootloader will be applied to the inactive slot. After a reboot, the system will switch to that slot.

```shell
# sudo nv_bootloader_capsule_updater.sh -q TEGRA_BL.Cap
```
During boot, the firmware date displayed at the top of the screen updates to the date of our new bootloader.

After entering the system, you can verify the result via `sudo nvbootctrl --dump-slots-info`; if the Capsule update status is 1, the update succeeded.

With the above update, the system boots successfully, resolving the previous black-screen issue. However, a new problem has subsequently arisen.

```shell
[   29.317410] usb 1-4.4: Failed to query (GET_DEF) UVC control 2 on unit 1: -32 (exp. 1).
[   29.318661] usb 1-4.4: Failed to query (GET_DEF) UVC control 2 on unit 1: -32 (exp. 1).
[   29.319911] usb 1-4.4: Failed to query (GET_DEF) UVC control 2 on unit 1: -32 (exp. 1).
[   29.321161] usb 1-4.4: Failed to query (GET_DEF) UVC control 2 on unit 1: -32 (exp. 1).
[   29.322426] usb 1-4.4: Failed to query (GET_DEF) UVC control 2 on unit 1: -32 (exp. 1).
[   29.323664] usb 1-4.4: Failed to query (GET_DEF) UVC control 2 on unit 1: -32 (exp. 1).
...
```

In the dmesg output, a large number of error messages can be observed. This indicates that while the system now boots successfully, there are runtime issues—most likely related to the UVC (USB Video Class) driver.

These errors will need to be investigated in the next phase by examining the UVC driver’s handling of descriptors and ensuring compatibility with the previously problematic webcam. For now, the important outcome is that the system can successfully start up and reach the operating system, resolving the earlier black-screen failure.

## Conclusion and Summary
1. When the power button was pressed, the system showed no response. From the fan noise, it was inferred that the crash occurred before reaching the operating system. Using the Micro-USB debug UART, the boot log was captured.
2. During the UEFI phase (`XhciDxe`), while configuring USB endpoints, the device returned an out-of-range `bInterval`. This triggered an `ASSERT`, resulting in a black screen and a system halt. The valid range was determined based on USB 2.0 and xHCI 1.1 specifications.
3. In edk2-nvidia, the file `XhciSched.c` was modified (note that the path in the assertion corresponds to the build machine’s environment, not the actual repository path). The change forced `bInterval` to fall within the valid range.
4. The recompiled UEFI firmware was integrated into the L4T BSP. Using `l4t_generate_soc_bup.sh`, a BUP (Bootloader Update Payload) was created, followed by `lr4_generate_soc_capsule.sh` to produce `TEGRA_BL.Cap`.
5. On the device, `TEGRA_BL.Cap` was applied to update the bootloader.

## Reference, README from L4T
```
# SPDX-FileCopyrightText: Copyright (c) 2023 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: LicenseRef-NvidiaProprietary
#
# NVIDIA CORPORATION, its affiliates and licensors retain all intellectual
# property and proprietary rights in and to this material, related
# documentation and any modifications thereto. Any use, reproduction,
# disclosure or distribution of this material and related documentation
# without an express license agreement from NVIDIA CORPORATION or
# its affiliates is strictly prohibited.

The NVIDIA Public release Package provides a tool to update the QSPI flash partitions
of Jetson devkits. This document provides information about updating the bootloader in
the QSPI flash.


1. Prerequisites:

   - This tool is in the Public Release Package. It must be extracted to the Jetson
     Linux Package work directory (${Your_path}/Linux_for_Tegra/).


2. Preparation.

   - Download the Jetson Linux Package and make it ready for flashing. The work
     directory is "${Your_path}/Linux_for_Tegra/".


3. Generate the QSPI flash bootloader payload.

   Here take the IGX as an example.

   a. Generate the BUP payload.
         $ cd ${Your_path}/Linux_for_Tegra/
         $ sudo ./l4t_generate_soc_bup.sh -e t23x_igx_bl_spec t23x

   b. Pack the generated BUP to the Capsule payload.
          $ ./generate_capsule/l4t_generate_soc_capsule.sh \
              -i ./bootloader/payloads_t23x/bl_only_payload \
              -o ./Tegra_IGX_BL.Cap t234

      Refer to the Jetson-Linux Developer Guide for more information about the Capsule payload.

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.

```

## About DXE
DXE stands for Driver Execution Environment, which is one of the boot phases defined in the UEFI/PI (Platform Initialization) architecture, as illustrated in the figure.
![image](https://hackmd.io/_uploads/r1z6qoacxg.png)
It occurs after PEI (Pre-EFI Initialization) and before BDS (Boot Device Selection). During this phase, the dispatcher loads various DXE drivers into memory. These drivers are responsible for initializing most of the platform hardware, establishing UEFI Boot Services, and setting up protocols, handlers, and related infrastructure. Once complete, control is handed over to BDS, which selects and launches the boot loader.

For example, xhciDxe is a DXE driver responsible for bringing up the xHCI USB controller during the firmware stage. This enables UEFI to support USB keyboards, boot from USB storage devices, and perform other pre-boot USB operations.

### Capsule
A capsule is a firmware update package with a signed header. The operating system passes the capsule to UEFI via `UpdateCapsule()`. UEFI then validates and writes it to the designated firmware region using the Firmware Management Protocol (FMP), typically executing the update during the next boot.

A capsule consists of a header (Capsule GUID, size, flags) followed by the payload. Most platforms use an FMP Data Capsule, which specifies the component to be updated, its version, and the image itself. UEFI first calls `QueryCapsuleCapabilities()` to verify that the update can be processed, and then applies it through `UpdateCapsule()`. If Jetson-specific scripts are not used, tools such as `fwupdtool` may also be used to update the bootloader.

In essence, a capsule is a standardized, signed software update package that describes which component to update, which version to apply, and which image to use. UEFI’s FMP ensures that the update is securely written to the target firmware region at the next boot. On Jetson devices, the write stage can be observed during startup. The `TEGRA_BL.Cap` file is precisely such a capsule, used to update the bootloader/UEFI.


<style>
/* for code block（HackMD using .markdown-body container） */
.markdown-body pre {
  /* if line grater than 20, using rowing */
  max-height: 20lh;         
  overflow: auto;             /* 水平/垂直捲動 */
}

/* rollback：using em */
@supports not (max-height: 1lh) {
  .markdown-body pre {
    line-height: 1.4;       
    max-height: calc(20 * 1.4em);
  }
}

.markdown-body pre > code {
  display: block;
}

@media print {
  .markdown-body pre { max-height: none; overflow: visible; }
}
</style>
