# NV Jetson Debugging, Update BootLoader
## 問題描述
發現只要開機之前插入 webcam 就會無法開機,沒有畫面,推測是在 UEFI 或是 Second Bootloader 的時候發生錯誤,後面 Thrid Bootloader 到 Linux 都沒有被成功載入。
通過聽風扇轉速判斷在第一次失敗之後有重新開機過一次,在開機的時候風扇轉速較大,接著轉速維持在一定速率。
由於黑畫面,沒有任何訊息,這時候沒有 printf, gdb 那一些資源可以使用,直覺想到也許可以通過 GPIO, UART,但需要修改 UEFI 讓他的 TX 送出啟動階段的訊息,這時候先查詢 Jetson 使用 GPIO 的方法,發現除了側面 40 pin 的 GPIO 之外還有後面的 micro-USB 可以使用,且 UEFI 會通過這個界面送出訊息,只要接收端設置 baudrate 為 115200 就可以收到訊息。
### 通過 micro-usb 得到 Debug 訊息
將 micro-usb 與 host 相互連接之後會出現 ttyACM0 ~ ttyACM3 設備,選取 ttyAMA0 通過 `minicom` 成功讀取到啟動階段訊息,方便處理我們直接將訊息寫檔之後讀出
```shell
ls /dev/ttyACM*
sudo minicom -D /dev/ttyACM -b 115200 -8 -o -C <output_file_name>
```
訊息如下
```
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 ...
```
通過以上訊息,可以看到出現了 ASSERT 之後卡住,根據名稱判斷這是 UEFI 裡面的 xHCI USB 驅動 (Xhci) 崩潰。
觸發 ASSERT 之後 5 秒強制重新開機,接著無限重新啟動,反映出的結果就是只看到黑畫面,永遠無法進入作業系統。從上面 Interval 判斷這是某個 USB 端點回傳了不合法輪詢的 Interval,或是被 UEFI 解析成非法的範圍,導致 ASSERT 觸發。
關於合法的 Interval,查閱 USB 2.0 標準了解對 Isochronous 的 bInterval 在 Full-/High-Speed 常見的歸範圍 1 到 16,表示 $2^{(n-1)}$ 的 microframe 週期,中斷在 Full/Low-Speed 可以達到 1 到 255。
詳細規格可以閱讀 USB 2.0 與 xHCI 1.1 的相關說明
所以上面這個程式碼很可能是在判斷插入的 USB 2.0 裝置是否符合標準。如果不符合標準則觸發 assertion
### 詳細解讀 boot log
根據 NVIDIA [官方文件](https://docs.nvidia.com/jetson/archives/r35.1/DeveloperGuide/text/AR/BootArchitecture/JetsonAgxOrinBootFlow.html#bootrom),得知啟動流程如以下
- BootROM
- PSCROM
- MB1
- MB2
- UEFI
接著解讀以上啟動訊息
首先可以看到最上面有大量 MB1/MB2 的訊息,包含載入 BPMP_FW, PSC_FW, RCE/DCE/XUSB 等等,屬於 Jetson Boot 啟動流程。SDRAM 初始化,時脈溫度監控等等,沒有看到錯誤訊息,所以在 MB1/MB2 階段沒有發生問題。
接著看到一些警告,可能是來自 OP-TEE 的訊息,像是 Test UEFI variable,看起來像是開發用的測試 key 等等。
在 MB1/MB2 之後,接著進入到 Jetson UEFI,UEFI 階段會載入內建的 xHCI 驅動 (XhciDxe) 掃描鍵盤,隨身碟等等週邊裝置,可能是為了提供 pre-boot I/O 或是從 USB 開機,通過 ASSERT 資訊判斷這是使用 edk2 框架進行開發的 Bootloader,可以看到進入到 UEFI firmware 之後就會崩潰 (判斷這個崩潰應該是在 UEFI 很早期的情況發生的,所以導致我們開機連 BIOS 的畫面都沒有看到)
```
Jetson UEFI firmware (version 36.4.x ...)
ASSERT [XhciDxe] ... XhciSched.c(3154): Interval >= 1 && Interval <= 16
Resetting the system in 5 seconds.
```
我把這個 webcam 插到我的 fedora laptop 上,發現可以正常的開機,這邊我猜想 Linux Kernel 的 xHCI/USB driver 對 out-of-spac 的描述或許比較寬容,於是我查看 Linux Kernel xHCI/USB driver 的相關程式碼,希望把他移植到 edk2 UEFI 上,打上 patch,接著把 Jetson 上面的 Bootloader 抽換掉,解決這個問題。
### 關於 Linux Kernel xHCI/USB
位於 `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;
}
```
USB 的 `bInterval` 因為不同速度或傳輸型別而有不同的意義。而部份設備廠商可能會錯誤的填入資訊,例如把 FS 的語意用在 HS 或是 SS,或是錯誤的寫成 microsecond, microframe 而不是規格要求的 2 的冪次數。
上面的程式碼是為了容錯考慮,猜出一個正確值,或是給出一個合理的預設值,而不是直接報錯中止,如同 edk2 中做的那樣。
`i` 表示合法的下限值 (min),`j` 表示合法的上限值 (max),`n` 表示預設值或是推測之後應該要設置的值。
最下面的程式碼
```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;
}
```
如果超出 min 或是 max,則會將 `bInterval` 設置為 n。
所以目前的想法是希望可以放寬 Bootloader 的 `bInterval`,為此我們需要取得 Bootloader 的 source code,修改完成之後替換掉原先的 Bootloader。
### 環境建置
```shell
# sudo systemctl enable --now docker
# sudo groupadd -f docker
# sudo usermod -aG docker $USER
# newgrp docker
```
接著按照 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}\""
```
### 程式碼修改與編譯
接著修改程式碼,這邊先採用最小可行性方案,以 Linux Kernel 的作法整體概念是猜一個數字放入到 `bInterval`,這裡我們仿造類似的方式,直接使用以下
```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;
}
```
強制讓 Interval 落於一個範圍內,先驗證這樣是否會造成問題,之後再將 Linux Kernel 的作法移入
==TODO: 移植使用 Linux Kernel 的方案==
修改完成之後執行以下開始編譯並產生出二進位檔案
```
edk2_docker edk2-nvidia/Platform/NVIDIA/Jetson/build.sh --init-defconfig edk2-nvidia/Platform/NVIDIA/Jetson/Jetson.defconfig
```
二進位檔案會存在於 `images` 資料夾中,在資料夾中可以看到許多 `.dtbo` 以及 `BOOTAA64_Jetson_RELEASE.efi` 和 `uefi_Jetson_RELEASE.bin`,很明顯 `.efi` 以及 `.bin` 是我們主要需要的兩個檔案,根據 [NVIDIA Jetson Linux Developer Guide](https://docs.nvidia.com/jetson/archives/r38.2/DeveloperGuide/RM/PackageManifest.html) 可以知道這一些檔案的用途
- `BOOTAA64.efi` 為 Jetson Linux OS Launcher UEFI Application,跟我們在 x86 會看到的 `BOOTX64.efi` 是類似的東西,放在 ESP (EFI System Partition) 上的 UEFI 應用程式,由 UEFI 韌體 (`uefi*.bin`) 呼叫,負責找到 Kernel, DTB, initrd 並把控制權交給 Linux。Jetson 預設 Loader 為 L4TLauncher
- `uefi*.bin` 為 Jetson 的 CPU BootLoader,為 UEFI firmware 的本體 (使用 EDK2 框架),燒入在 Jetson 的 Bootloader Partition (在 Jetson 有 Slot A 以及 B,是為了在某一個 Bootloader 啟動失敗之後還能夠 rollback)。負責硬體初始化,載入各種 DXE 驅動,管理 UEFI NVRAM 變數,處理 Capsule 更新跟 A/B rollback,根據 Boot Order 去啟動 OS Loader,也就是上面說的 `BOOTAA64.efi` 會由 `uefi*.bin` 啟動
所以我們修改完 Xhci 相關程式碼之後,我們主要產生的是 `uefi*.bin`。
接著我們需要 L4T,裡面包含打包/燒錄/更新工具等等,能處理 Jetson 機種, Partition Table, A/B slot 等等細節,幫我們把做好的 UEFI 與週邊裝置,如 DTB, DTBO, loader 組織成正確的 Image 或是 Capsule,接著通過 Jetson 內部工具更新 Bootloader。
首先我們將 `uefi*.bin` 以及 `BOOTAA64.efi` 複製到 L4T 專案底下的 bootloader 資料夾中,接著開始打包
```shell
# sudo ./l4t_generate_soc_bup.sh -e t23x_agx_bl_spec t23x
```
使用以上指令產生 BUP (Bootloader Update Payload)
接著使用 BUP 產生 UEFI Capsule
```shell
# ./generate_capsule/l4t_generate_soc_capsule.sh \
-i bootloader/payloads_t23x/bl_only_payload \
-o TEGRA_BL.Cap t234
```
得到 `TEGRA_BL.Cap` 之後將其放到 Jetson AGX Orin 中。
在 Jetson AGX Orin 通過以下指令更新 Bootloader,新的 Bootloader 會被套用到非目前的 Slot,重開機之後我們會切換到該 Slot
```shell
# sudo nv_bootloader_capsule_updater.sh -q TEGRA_BL.Cap
```
在開機的時候可以看到畫面最上方的 firmware 日期更新成我們新的 Bootloader 日期。
而進入系統之後可以通過 `sudo nvbootctrl --dump-slots-info` 中 `Capsule update status` 的訊息,如果為 1 則表示更新成功。
經過以上更新之後,順利進入到系統,解決之前系統黑畫面的問題。但是隨之而來又有新的問題產生
```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).
...
```
可以看到在 dmesg 中有大量的錯誤訊息,關於這部份將在後續檢查 UVC Driver 排除問題。總之目前能夠順利啟動並進入系統了。
### 結論與整理
1. 發現按下開機鍵沒有反應,通過風扇聲音判斷可能是在進入到 OS 之前就 Crash 了,通過 Micro-USB Debuf UART 得到 boot log
2. 發現在 UEFI 階段 (XhciDxe) 在配置 USB 節點時,遇到裝置回傳不在範圍內的 `bInterval`,觸發 ASSERT,導致黑畫面以及卡住。這個範圍參考 USB 2.0 與 xHCI 1.1 相關描述
3. 修改 edk2-nvidia 的 `XhciSched.c` (不是 ASSERT 裡面的路徑,那個是建制該專案電腦上的路徑),將 `bInterval` 強制落於該範圍
4. 將編譯完成的 UEFI 放入 L4T BSP,接著使用 `l4t_generate_soc_bup.sh` 產生 BUP,再用 `lr4_generate_soc_capsule.sh` 產生 `TEGRA_BL.Cap`
5. 在裝置上使用 `TEGRA_BL.Cap` 完成 Bootloader 更新
#### 參考資料,NVIDIA L4T 中的 README
```
# 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.
```
### 關於 DXE
DXE 為 Driver Execution Environment,為 UEPI/PI 架構中的一個開機階段,參考下圖

在 PEI 之後,BDS (Boot Device Selection) 之前。這個階段由 Dispatcher 將各種 DXE 驅動載入到記憶體,初始化平台上大部分硬體,建立 UEFI 的 Boot Services 與整個 protocol, handler 等等,最後把系統交給 BDS 挑選並啟動 boot loader。
以 `xhciDxe` 為例子,他是 DXE 驅動,負責在韌體時期把 xHCI USB 控制器 bring up,讓 UEFI 能夠使用 USB 鍵盤,從 USB 開機等等。
### Capsule
Capsule 為一種帶有標頭簽章的韌體更新包,作業系統把他交給 UEFI 的 `UpdateCapsule()`,UEFI 依照 FMP (Fireware Management Protocol) 驗證與寫入指定韌體區域,通常會在下一次開機執行。
Capsule 包含 header (Capsule GUID, size, flag),後面加上 payload,多數平台使用 FMP Data Capsule,描述要更新的元件,版本以及 Image。UEFI 先使用 `QueryCapsuleCapabilities()` 檢查是否能處理,接著使用 `UpdateCapsule()` 申請更新。如果不使用 Jetson 裡面的腳本,或許也可以通過 `fwnpdtool` 進行 Bootloader 更新。
Capsule 就是軟體更新包,將要更新哪個元件,版本以及 Image 使用標準格式描述並簽章,交給 UEFI 的 FMP 在下次開機安全寫入目標韌體區域,在 Jetson 開機時可以看到寫入階段。而上面的 `TEGRA_BL.Cap` 就是用來更新 bootloader/UEFI 的 Capsule。
<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>