Skip to content

nvidia: Thor provisioning leaves RCM, fTPM node, upstream flash helper, Jetson getty mask - #317

Merged
mobileoverlord merged 8 commits into
wrynosefrom
jschneck/thor-provision-fixes
Aug 26, 2026
Merged

nvidia: Thor provisioning leaves RCM, fTPM node, upstream flash helper, Jetson getty mask#317
mobileoverlord merged 8 commits into
wrynosefrom
jschneck/thor-provision-fixes

Conversation

@mobileoverlord

Copy link
Copy Markdown
Contributor

Fixes found while bringing up encrypted-/var (#310) on a Jetson AGX Thor devkit; verified end-to-end on Thor (T264, L4T 6.8) and re-verified on AGX Orin (T234, linux-yocto 6.18).

Thor: provisioning now ends with the board booting the flashed system

  • adb shell reboot -f instead of adb reboot — the device-side adbd64 implements adb reboot via the Android sys.powerctl property, which nothing serves in the flashing initramfs (reboot (reboot,adb) failed).
  • Device-side reboot restored (tegra-target-flash-scripts_%.bbappend) — meta-tegra's sed on NVIDIA's /init drops the /sbin/rebootbusybox reboot -f wrapper; with bash as PID 1, bare busybox reboot is a silent no-op. Reinstated as an update-alternative (priority 100 > busybox 50). Kept in this layer, no vendor patch.
  • Leave RCM via boardctl reset — T264 keeps the RCM boot mode across the warm reset, so the SoC re-enumerates as boot-ROM APX (0955:7026) instead of cold-booting. tegrarcm_v2 --new_session … --reboot coldboot is accepted but does nothing (tested); NVIDIA's bootburn never resets either. initrd-flash.sh now waits ≤60 s for the APX device and presses SYS_RESET through the TOPO debug MCU (boardctl -t $BOARDCTL_TARGET reset, defaulting to thor-jetson-devkit when a 0955:7045 Operator is on the bus); without a TOPO it prints ACTION NEEDED … press RESET.
  • nativesdk-boardctl was unusable — never installed _targets/, and the ${bindir} symlink made os.path.abspath(__file__) resolve to ${bindir}/_targets (FileNotFoundError). Installs _targets/ + __init__.py, ships a wrapper instead of a symlink.

Thor: fTPM device node

  • OVERLAY_DTB_FILE = "tegra264-ftpm.dtbo" — Orin gets firmware/ftpm from tegra-optee.dtbo via TEGRA_PLUGIN_MANAGER_OVERLAYS; Thor's L4T ships it in tegra264-ftpm.dtbo via OVERLAY_DTB_FILE (t264.conf.common), which meta-tegra doesn't carry. Without it the TOS has the TA and UEFI measures into it, the initramfs ships tpm_ftpm_tee.ko, but Linux has no node → no /dev/tpm0 and cryptsetup-var falls back to the recovery key. Now: TPM2 PCR-7 keyslot enrolled.

Thor: drop our stale tegra264-flash-helper.sh

  • It was an untouched R38-era upstream snapshot with zero avocado logic; every diff vs the pinned meta-tegra unified tegra-flash-helper.sh was upstream being newer (CHPID typo, RAMCODE-from-board fallback, get_active_key, --cpubl_rcm, guarded $odmdata_arg). FLASH_HELPER_SCRIPT:tegra264 now points at upstream's helper; tegra234-flash-helper.sh stays (carries the ODMDATA env-precedence fix upstream lacks).
  • MINRATCHET_CONFIG is a bare filename on tegra264 — our conf had the Orin --minratchet_config <dts> form, which the unified helper splits into two args → nvbct-config ValueError: not enough values to unpack. Every other TEGRA_FLASHVAR_* matches upstream agx-thor-t5000.inc.

All Jetsons

  • systemd-jetson-masks in the avocado rootfs — it only rode MACHINE_ESSENTIAL_EXTRA_RDEPENDS, which packagegroup-avocado-rootfs deliberately doesn't expand, so every Jetson still booted degraded with getty@getty.service. Added via RDEPENDS:${PN}:append:tegra on the existing nvidia bbappend.

Verification

  • Thor: provision log ends [found]pressing SYS_RESET via boardctl (target=thor-jetson-devkit) → board boots unattended; systemctl is-system-running = running, /dev/tpm0 present, /var LUKS2 with systemd-tpm2 token.
  • Orin: running, /dev/tpm0, PCR-7 keyslot enrolled, grow-var completes, no failed units.

Companion: avocado-linux/ext-dev#3 (grow-var: resolve the whole disk with lsblk -d; read sizes from sysfs) — the old grow-var wrote a GPT over the LUKS header on dm-backed /var.

adbd64 in NVIDIA's T264 flashing initramfs implements 'adb reboot' by
setting the Android sys.powerctl property, which nothing serves there, so
it always fails ('reboot (reboot,adb) failed') and the board sits in the
initramfs after a successful flash. Run 'reboot -f' over adb shell instead,
which issues the reboot syscall directly.
…sh-helper.sh

Our tegra264-flash-helper.sh was a wholesale snapshot of an R38-era
meta-tegra split helper (added in 609512e, never edited). Diffing it
against the pinned meta-tegra's unified tegra-flash-helper.sh shows no
avocado logic in it -- every difference is upstream being newer: the CHPID
typo, the RAMCODE-from-board fallback when RAMCODE is unset, get_active_key
for T26x PKC keylists, --cpubl_rcm, the guarded $odmdata_arg in the RCM
flashcmd (ours still passed a raw --odmdata $ODMDATA, the same
empty-value hazard ac23aef fixed on t234), and BCTFILE for the SDRAM
config. The --no-flash --rcm-boot path initrd-flash depends on (rcmboot_blob
+ membct_ramcode_file rewrite + rcmdump_blob.tar) is unchanged.

Point FLASH_HELPER_SCRIPT:tegra264 at upstream's helper, stop installing the
copy from tegra-helper-scripts and nativesdk-tegraflash-tools, and have the
SDK recipe copy tegra-flash-helper.sh from the native sysroot instead.
tegraflash-tools-deploy already copies the whole native tegra-flash tree, so
the runtime path needs nothing extra. tegra234-flash-helper.sh stays: it
carries the ODMDATA env-precedence fix upstream does not have.
Our machine conf carried the Orin-style value ('--minratchet_config <dts>').
meta-tegra's Thor includes define it as the bare .dts, and the unified
tegra-flash-helper.sh (now used on Thor) passes it unquoted as
brbct_cfg/minratchet=$MINRATCHET_CONFIG, so the value split into two args and
nvbct-config died on the flag-less second one:

  ValueError: not enough values to unpack (expected 2, got 1)
  ERR: could not update BCT configuration

Our former tegra264-flash-helper.sh snapshot never passed minratchet to
nvbct-config, which is why this stayed hidden. Every other TEGRA_FLASHVAR_*
in the conf matches upstream agx-thor-t5000.inc.
…node

On Orin the firmware/ftpm node comes from tegra-optee.dtbo via
TEGRA_PLUGIN_MANAGER_OVERLAYS. On Thor L4T ships it in tegra264-ftpm.dtbo and
applies it at flash time via OVERLAY_DTB_FILE (t264.conf.common), which
meta-tegra does not carry for tegra264. Result on an AGX Thor devkit with
var.encrypt: the TOS has the fTPM TA and UEFI measures into it, the initramfs
ships tpm_ftpm_tee.ko, but /proc/device-tree has no ftpm node, the tee bus
only enumerates the RNG TA, no /dev/tpm0 appears, and cryptsetup-var opens
/var with the Argon2id recovery key instead of a PCR-7 sealed keyslot.
It was only in MACHINE_ESSENTIAL_EXTRA_RDEPENDS, which
packagegroup-avocado-rootfs.bb intentionally does not expand, so every
avocado-built Jetson rootfs still boots degraded with getty@getty.service.
Two pieces, both in this layer (no vendor-layer patches):

- tegra-target-flash-scripts_%.bbappend: meta-tegra's sed on NVIDIA's /init
  drops the /sbin/reboot wrapper ('busybox reboot -f') together with the mount
  block. PID 1 there is /bin/bash, so bare busybox reboot -- which only signals
  init -- is a silent no-op from init's error/timeout paths, the debug prompt
  and 'adb shell reboot'. Reinstate it as an update-alternative above
  busybox's priority.

- initrd-flash.sh: after 'adb shell reboot -f', T264 keeps the RCM boot mode
  across the warm reset and comes back as the boot-ROM APX device (0955:7026)
  rather than cold-booting the flashed system (observed twice on an AGX Thor
  devkit). NVIDIA's bootburn carries Mb2AppletReset() for exactly this but
  never calls it. Wait up to 60 s for the device to re-enter RCM with
  find-jetson-usb --wait (it matches only RCM PIDs, not the adb gadget) and
  issue 'tegrarcm_v2 --chip 0x26 0 --reboot coldboot'; if it never reappears
  it booted on its own.
First run on the AGX Thor devkit confirmed the device re-enters RCM after
'adb shell reboot -f' ([found]) but the kick failed:

  File rcm_state open failed
  ERROR: failed to read rcm_state

tegrarcm_v2 keeps its RCM session in an rcm_state file in the cwd, written by
--new_session; NVIDIA's generated rcmbootcmd.txt only ever issues '--reboot
recovery' after such a session. Do the same: --new_session --uid in a scratch
dir, then --reboot coldboot.
…oardctl

Tested on the AGX Thor devkit: after 'adb shell reboot -f' the SoC returns
as the boot-ROM APX device, and 'tegrarcm_v2 --new_session --uid' +
'--reboot coldboot' is accepted (BR_CID printed) but leaves it in RCM; the
reset button is what boots the flashed system. Drop the tegrarcm kick and
press SYS_RESET through the devkit's TOPO debug MCU instead:
'boardctl -t $BOARDCTL_TARGET [-s $BOARDCTL_SERIAL] reset', defaulting the
target to thor-jetson-devkit when a 0955:7045 Operator is on the bus and
CHIPID is 0x26. Without a TOPO, print ACTION NEEDED and ask for the button.

nativesdk-boardctl: boardctl was unusable in the SDK -- it scans _targets/
next to itself (FileNotFoundError), and the  symlink made
os.path.abspath(__file__) resolve there. Install _targets/ and __init__.py
and replace the symlink with a wrapper.
@mobileoverlord
mobileoverlord merged commit 25c324d into wrynose Aug 26, 2026
2 checks passed
@mobileoverlord
mobileoverlord deleted the jschneck/thor-provision-fixes branch August 26, 2026 16:58
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant