jetson-init-source
Set up the BSP source workspace: Linux_for_Tegra overlay tracker, bsp_sources, Crosstool-NG toolchain. Use after jetson-init-image; not for fetching inputs.
Skill body
Initialize BSP Customization Workspace
Overview
This skill bootstraps the source-side workspace that customize-* / build
skills depend on: the Linux_for_Tegra overlay tracker (git repo for
pristine + customization commits), the bsp_sources/ mono-tree (kernel,
OOT, nvgpu, display, hwpm, hardware DTs), and a working NVIDIA
Crosstool-NG cross-compile prefix. It owns only the source: block in
the active profile and the on-disk source workspace under
<source.root_path> (default: <workspace>/Source).
Responsibilities:
- Optionally record a non-default
source.root_path. - Create or mount the
Linux_for_Tegraoverlay tracker. - Materialize
bsp_sourcesusing the precedence in the “Materialize the BSP-sources baseline” step. - Resolve and record
source.toolchain. - Clone extra user-defined repos from
source.repos:.
When to invoke
- The user asks to bootstrap, init, or sync the BSP customization workspace.
- A downstream customization skill refused with “no workspace
tracker at
<source.root_path>/Linux_for_Tegra/”. - After
jetson-init-image(Setup’s next step on a fresh target).
Procedure
Quick-start prefill mapping
Follow the shared
quick_start_prefill contract.
This skill has source-specific mappings:
quick_start_prefill.source.public_sources_archivemaps to the Branch-A archive candidate.quick_start_prefill.source.reposmaps to proposedsource.repos:entries; validate reserved keys andurl:/archive:mutual exclusion before writing.quick_start_prefill.source.toolchainmay be a cross-compile prefix, agccpath, a containingbin/directory, anx-tools.tbz2archive path, orskip.
This skill remains the only owner of source.root_path, source.repos:,
and source.toolchain profile writes.
Resolve the active target + paths
Resolve the active profile + workspace defaults per the contract in
../../context/target-platform-contract.md.
- Refuse if
<bsp_image.root_path>does not containLinux_for_Tegra/(BSP not extracted — route to/jetson-init-image). - If the profile has
source.root_path:, use it. Otherwise<source.root_path>defaults to<workspace>/Source; use that default silently and do not writesource.root_path:to the profile. Ask only for an explicit custom path, unrelated content at the default path, or an unwritable parent.
Read source.repos: (if present) into a map keyed by entry name,
each carrying optional url, ref, subdir, path. Reserved keys:
Linux_for_Tegra (overlay tracker), bsp_sources (kernel-source
repo). Every other key is an extra user-defined repo.
(Optional) prompt for source.root_path override
Only when source.root_path is absent from the profile and one of the
override conditions above applies:
source.root_path: default =<workspace>/Source. Press Enter to accept, or enter an absolute path to override.
- On Enter — keep the default; do not touch the profile.
- On override path — validate the closest existing parent is
writable; refuse and re-prompt if not. Edit
target-platform/<active>.yamlin place to add/updatesource.root_path:. Preserve all other blocks, comments, and quoting — use a round-tripping YAML loader (e.g.ruamel.yaml).
Fires at most once per profile. Otherwise create <workspace>/Source as
needed and continue without prompting.
Materialize Linux_for_Tegra
Mount path is canonical: <source.root_path>/Linux_for_Tegra/.
Default (no source.repos.Linux_for_Tegra entry):
LFT="<source.root_path>/Linux_for_Tegra"
mkdir -p "$LFT"
[ -d "$LFT/.git" ] || git -C "$LFT" init
Empty tracker. Do not commit anything here — pristine imports happen file-by-file when customization skills run.
Override (url, ref, optional subdir):
# Clone the user's repo to a side location, then mount the
# expected tree (subdir or repo root) at the canonical path.
CLONE="<source.root_path>/.repos/Linux_for_Tegra"
git clone <url> -b <ref> "$CLONE"
ln -s "$CLONE/<subdir or .>" "<source.root_path>/Linux_for_Tegra"
If the mount already exists with valid git state, skip; refuse if it exists with unrelated content.
Materialize the BSP-sources baseline
Three branches, dispatched in precedence order against the
profile entry source.repos.bsp_sources:
| Order | Profile state | Branch |
|---|---|---|
| 1 | url: set |
C. Customer git clone (explicit override always wins) |
| 2 | archive: set, OR entry absent AND <workspace>/Downloads/public_sources.tbz2 exists |
A. Local archive extraction (default) |
| 3 | Entry absent AND no local archive | B. source_sync.sh (fallback) |
url: and archive: are mutually exclusive — refuse if both are
set in the same entry.
Branch A is the preferred default because it sidesteps NVIDIA git egress entirely (the most common Setup failure mode). Branch B exists for fresh workspaces with no pre-downloaded tarball. Branch C is for customer forks of the whole BSP layout.
Branch A — Local archive extraction (default)
Default branch: extract a pre-downloaded public_sources.tbz2 into
<source.root_path>/bsp_sources/ as a single mono-repo (git init +
pristine commit). See
references/branch-a-extraction.md
for the full archive shape, path-resolution rules, and the extraction
script (including the Tegra OOT Makefile force-replace workaround for
R36.x).
Branches B and C may produce per-component repos instead; downstream
build logic still walks the canonical sub-paths under
<source.root_path>/bsp_sources/.
Branch B — source_sync.sh (fallback)
Runs only when no local archive is found and no url: is set.
Create the bsp_sources/ mount directory under <source.root_path>
and run source_sync.sh from the extracted BSP with two flags:
mkdir -p "<source.root_path>/bsp_sources"
bash "<bsp_image.root_path>/Linux_for_Tegra/source/source_sync.sh" \
-d "<source.root_path>/bsp_sources" \
-t "jetson_<major.minor>"
-d <source.root_path>/bsp_sources— write clones into thebsp_sources/subdir of the workspace, so the on-disk folder matches the schema key. Without-d, the script writes under its own directory (the BSP itself) — wrong for the overlay model.-t jetson_<major.minor>— pin the tag to the BSP release line. Derive frombsp_image.versionby truncating to the first two dotted components:"38.4.0"→jetson_38.4. Tag-format fallback: if rejected, tryjetson_<bsp_image.version>(older L4T sometimes uses the full form). If that also fails, surface the error and stop — never fall back to “latest” silently.
Refuse if source_sync.sh does not exist: re-run /jetson-init-image
to repopulate Linux_for_Tegra/source/.
source_sync.sh exits 0 even when every clone failed — verify by
counting Failed to clone lines in its output and refuse if
non-zero. The most likely cause of universal failure is blocked
git egress to gitlab.com/nvidia/nv-tegra /
nv-tegra.nvidia.com; surface that explicitly and route the user
to download public_sources.tbz2 via /quick-start for Branch A.
Branch C — Customer git clone (url: override)
Triggered by an explicit url: field. Clone the customer repo once
and expose its canonical kernel-side sub-paths under
<source.root_path>/bsp_sources/. The canonical sub-path list is
read from source_sync.sh’s SOURCE_INFO at runtime — do not
hard-code it, so future NVIDIA additions/removals propagate
automatically:
# Parse canonical sub-paths from source_sync.sh's SOURCE_INFO
# (only the kernel-side entries marked `k:` in the second field).
SUBPATHS=$(grep -oP '^\s*k:[^:]+:' \
"<bsp_image.root_path>/Linux_for_Tegra/source/source_sync.sh" \
| sed 's/^\s*k://; s/:$//')
mkdir -p "<source.root_path>/bsp_sources"
CLONE="<source.root_path>/.repos/bsp_sources"
git clone <url> -b <ref> "$CLONE"
ROOT="$CLONE/<subdir or .>"
for SUB in $SUBPATHS; do
[ -d "$ROOT/$SUB" ] && \
ln -s "$ROOT/$SUB" "<source.root_path>/bsp_sources/$SUB"
done
Report any canonical sub-path expected for the active chip family but not present inside the customer repo (warn, don’t refuse — customer may legitimately not have all repos).
Resolve cross-compile toolchain
The downstream jetson-build-source reads source.toolchain from
this profile and exports it as CROSS_COMPILE. This step must
land a valid prefix before init-source returns, or any subsequent
kernel / OOT / DT build will refuse.
NVIDIA’s official Crosstool-NG Toolchain gcc is the canonical
toolchain for L4T. jetson-download-bsp owns any network fetch of
x-tools.tbz2; this skill only discovers, extracts, validates, and
writes the resolved prefix. Resolution follows a three-step ladder:
Auto-discover
Look under <workspace>/toolchain/x-tools/ for the Crosstool-NG
layout — typically one of:
<workspace>/toolchain/x-tools/aarch64-none-linux-gnu/bin/aarch64-none-linux-gnu-gcc
<workspace>/toolchain/x-tools/aarch64-buildroot-linux-gnu/bin/aarch64-buildroot-linux-gnu-gcc
Glob: <workspace>/toolchain/x-tools/aarch64-*-linux-gnu/bin/aarch64-*-linux-gnu-gcc.
If exactly one match, bind:
TC_PREFIX=<absolute path to that .../bin/<triple>-> # trailing dash mandatory
Skip to “Write to profile” below. If zero matches, fall through
to “Auto-extract from Downloads/x-tools.tbz2” below. If multiple, refuse with the list and ask the user to
remove the unwanted ones (we never pick one silently among
ambiguous installs — different Crosstool-NG flavors produce ABI-
incompatible binaries).
Auto-extract from Downloads/x-tools.tbz2
If <workspace>/Downloads/x-tools.tbz2 exists (mirrors the
public_sources.tbz2 Branch-A pattern in the “Materialize the BSP-sources baseline” step — air-gapped /
no-egress users drop archives there):
file -b "<workspace>/Downloads/x-tools.tbz2" | grep -q "bzip2 compressed" || \
refuse "<workspace>/Downloads/x-tools.tbz2 is not a bzip2 tarball"
mkdir -p "<workspace>/toolchain"
tar xjf "<workspace>/Downloads/x-tools.tbz2" -C "<workspace>/toolchain"
Then re-run the “Auto-discover” pass above. Refuse if extraction succeeds
but no x-tools/aarch64-*-linux-gnu/bin/ is produced (archive
content doesn’t match the Crosstool-NG layout).
Prompt the user
If both Auto-discover and Auto-extract came up empty, ask:
No Crosstool-NG toolchain found at
<workspace>/toolchain/or in<workspace>/Downloads/x-tools.tbz2.Reply with one of:
- absolute path to your
aarch64-*-linux-gnu-gccbinary or its containingbin/directory,cancelto abort.To fetch the archive instead, cancel this run, run
/jetson-download-bsp, then re-run/jetson-init-source.
For a path reply, validate via [ -f "${TC_PREFIX}gcc" ]. Refuse
and re-prompt on failure.
Write to profile
Once $TC_PREFIX resolves and ${TC_PREFIX}gcc exists, write it
into the active profile using a round-tripping YAML loader:
source:
toolchain: <TC_PREFIX> # absolute, with trailing dash
If source: is otherwise empty (no root_path override, no
repos: entries), the source: block is now non-empty and stays
in the profile. Future jetson-init-source runs skip the “Resolve cross-compile toolchain” step
if source.toolchain is already set and points at a working gcc.
Clone extra user-defined repos
For each entry under source.repos: whose name is not
Linux_for_Tegra or bsp_sources:
MOUNT="<source.root_path>/<entry.path or entry.name>"
if [ -n "<entry.subdir>" ]; then
CLONE="<source.root_path>/.repos/<entry.name>"
git clone <entry.url> -b <entry.ref> "$CLONE"
ln -s "$CLONE/<entry.subdir>" "$MOUNT"
else
git clone <entry.url> -b <entry.ref> "$MOUNT"
fi
Refuse if a mount path already exists with unrelated content.
Summary
Print:
- Resolved
<workspace>,<bsp_image.root_path>, and<source.root_path>. - For each materialized component: created, reused, skipped, or refused.
- For
bsp_sources: branch selected plus key evidence (archive path,source_sync.shfailure count, or clone URL/ref). - Toolchain prefix, resolution source, and
${TC_PREFIX}gcc --versionfirst line. - Reminder that customize-* skills stage future BSP edits in
<source.root_path>/Linux_for_Tegra/; promote is what later copies committed overlay changes intobsp_image.
If a downstream skill triggered this run, tell the user to re-issue their original request.
Gotchas
Linux_for_Tegraandbsp_sourcesmount paths are canonical.path:applies only to extra user-defined repos.- The default
Linux_for_Tegratracker is intentionally empty; do not pre-populate it. bsp_sourcesprecedence isurl:→archive:→ auto-discoveredDownloads/public_sources.tbz2→source_sync.sh.url:andarchive:are mutually exclusive.- Branch A auto-discovery does not prompt and is not written back to the
profile. Persist it only with
source.repos.bsp_sources.archive:. - Branch A
$DEST/Makefilecollision. Inner tarballs inpublic_sources.tbz2ship two files namedMakefile: the Tegra orchestrator (kernel_oot_modules_src.tbz2) and the dGPU/OpenRM proprietary Makefile (nvidia_kernel_display_driver_source_without_ root_dir.tbz2). Alphabetical extraction order lets the dGPU one win on R36.x; downstream arm64 cross-builds then fail with'-mlittle-endian' unrecognized. Step 3a force-replaces from<bsp_image>/Linux_for_Tegra/source/Makefilewhen the Tegramodules: hwpm nvidia-oot nvgpu nvidia-displaysignature is missing. R38+ extractions already match; the check is a no-op there. - Branch C customer repos must expose the canonical
source_sync.shsub-path layout, optionally shifted bysubdir:. - Derive the
source_sync.shtag frombsp_image.versionasjetson_<major.minor>first; never fall back to an unpinned latest. jetson-download-bspowns network downloads ofpublic_sources.tbz2andx-tools.tbz2; this skill consumes local archives only.source.toolchainmust be an NVIDIA Crosstool-NG prefix with trailing dash and a working${prefix}gcc. Never silently use$PATH.- Use a round-tripping YAML writer for profile edits.
Prerequisites
- Active target profile resolved per
../../context/target-platform-contract.md. /jetson-init-imagealready run sobsp_image.versionis recorded (Branch Bsource_sync.shtag derives from it).- For Branch A: a local
public_sources.tbz2(and optionallyx-tools.tbz2) staged underDownloads/. - For Branch C: customer Git access to the override repo URL.
Limitations
- Owns only the
source:block; never editsbsp_image,reference_devkit,custom_carrier, ordocuments. - Network egress only for Branch B (
source_sync.sh) and Branch C (customer Git clone); Branch A is fully offline. - Refuses to silently substitute a system toolchain — the NVIDIA Crosstool-NG prefix must be present or extractable.
Troubleshooting
${toolchain}gccnot found — re-stagex-tools.tbz2underDownloads/and rerun, or pass a verified absolute prefix path.source_sync.shcannot resolvejetson_<major.minor>tag — the recordedbsp_image.versionis wrong; re-run/jetson-init-imageto refresh it.Linux_for_Tegra/.gitshows uncommitted hand-edits — abort and ask the user to commit or stash; this skill expects a clean tracker.- Branch C clone missing canonical sub-paths — repo layout doesn’t
match
source_sync.sh; setsubdir:to the right sub-root or fall back to multi-repo overrides undersource.repos:.
References
../../references/platform_template.yaml—source:schema, including therepos:map.../../context/target-platform-contract.md— target-platform contract.../../context/bsp-customization-workflow.md— Workspace edit protocol.../jetson-init-target/SKILL.md— authors the profile this skill consumes.../jetson-init-image/SKILL.md— extracts the BSP and back-fillsbsp_image.version; run before this skill.