nvidia/jetson-init-source
>- bsp_sources, Crosstool-NG toolchain. Use after jetson-init-image; not for fetching inputs.
npx skills add https://github.com/NVIDIA/skills --skill jetson-init-source
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:
source.root_path.Linux_for_Tegra overlay tracker.bsp_sources using the precedence in the "Materialize the BSP-sources baseline" step.source.toolchain.source.repos:.workspace.
tracker at <source.root_path>/Linux_for_Tegra/".
jetson-init-image (Setup's next step on a fresh target).Follow the shared
quick_start_prefill contract.
This skill has source-specific mappings:
quick_start_prefill.source.public_sources_archive maps to theBranch-A archive candidate.
quick_start_prefill.source.repos maps to proposed source.repos:entries; validate reserved keys and url: / archive: mutual
exclusion before writing.
quick_start_prefill.source.toolchain may be a cross-compile prefix,a gcc path, a containing bin/ directory, an x-tools.tbz2 archive
path, or skip.
This skill remains the only owner of source.root_path, source.repos:,
and source.toolchain profile writes.
Resolve the active profile + workspace defaults per the contract in
../../context/target-platform-contract.md.
<bsp_image.root_path> does not containLinux_for_Tegra/ (BSP not extracted — route to /jetson-init-image).
source.root_path:, use it. Otherwise<source.root_path> defaults to <workspace>/Source; use that default
silently and do not write source.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.
source.root_path overrideOnly 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.
writable; refuse and re-prompt if not. Edit
target-platform/<active>.yaml in place to add/update
source.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.
Linux_for_TegraMount 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.
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.
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/.
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 from bsp_image.version by truncating to the first two
dotted components: "38.4.0" → jetson_38.4. **Tag-format
fallback**: if rejected, try jetson_<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.
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).
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:
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).
Downloads/x-tools.tbz2If <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).
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-gcc binary or its
> containing bin/ directory,
> - cancel to 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.
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.
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.
Print:
<workspace>, <bsp_image.root_path>, and<source.root_path>.
bsp_sources: branch selected plus key evidence (archive path,source_sync.sh failure count, or clone URL/ref).
${TC_PREFIX}gcc --versionfirst line.
<source.root_path>/Linux_for_Tegra/; promote is what later copies
committed overlay changes into bsp_image.
If a downstream skill triggered this run, tell the user to re-issue
their original request.
Linux_for_Tegra and bsp_sources mount paths are canonical.path: applies only to extra user-defined repos.
Linux_for_Tegra tracker is intentionally empty; do notpre-populate it.
bsp_sources precedence is url: → archive: → auto-discoveredDownloads/public_sources.tbz2 → source_sync.sh. url: and
archive: are mutually exclusive.
profile. Persist it only with source.repos.bsp_sources.archive:.
$DEST/Makefile collision. Inner tarballs inpublic_sources.tbz2 ship two files named Makefile: 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/Makefile when the Tegra
modules: hwpm nvidia-oot nvgpu nvidia-display signature is
missing. R38+ extractions already match; the check is a no-op there.
source_sync.shsub-path layout, optionally shifted by subdir:.
source_sync.sh tag from bsp_image.version asjetson_<major.minor> first; never fall back to an unpinned latest.
jetson-download-bsp owns network downloads of public_sources.tbz2and x-tools.tbz2; this skill consumes local archives only.
source.toolchain must be an NVIDIA Crosstool-NG prefix with trailingdash and a working ${prefix}gcc. Never silently use $PATH.
../../context/target-platform-contract.md.
/jetson-init-image already run so bsp_image.version is recorded(Branch B source_sync.sh tag derives from it).
public_sources.tbz2 (and optionallyx-tools.tbz2) staged under Downloads/.
source: block; never edits bsp_image,reference_devkit, custom_carrier, or documents.
source_sync.sh) and Branch C(customer Git clone); Branch A is fully offline.
Crosstool-NG prefix must be present or extractable.
${toolchain}gcc not found — re-stage x-tools.tbz2 underDownloads/ and rerun, or pass a verified absolute prefix path.
source_sync.sh cannot resolve jetson_<major.minor> tag — therecorded bsp_image.version is wrong; re-run /jetson-init-image
to refresh it.
Linux_for_Tegra/.git shows uncommitted hand-edits — abort andask the user to commit or stash; this skill expects a clean tracker.
match source_sync.sh; set subdir: to the right sub-root or fall
back to multi-repo overrides under source.repos:.
../../references/platform_template.yaml — source: schema, including the repos: 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-fills bsp_image.version; run before this skill.Take nvidia/jetson-init-source from the repository into ~/.claude/skills for personal
use, or into .claude/skills inside a project.
The agent identifies a skill by the name field in its header. Two skills with the
same name cannot sit side by side — one of them will be ignored.