diff --git a/.conform.yaml b/.conform.yaml index 1a04f63..60c8757 100644 --- a/.conform.yaml +++ b/.conform.yaml @@ -1,6 +1,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2024-03-16T13:23:31Z by kres c2d361c. +# Generated on 2026-02-02T00:20:48Z by kres dc032d7. policies: - type: commit @@ -12,7 +12,7 @@ policies: gitHubOrganization: siderolabs spellcheck: locale: US - maximumOfOneCommit: true + maximumOfOneCommit: false header: length: 89 imperative: true diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 506082c..cd97480 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -1,6 +1,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2025-11-12T13:55:37Z by kres 911d166. +# Generated on 2026-02-02T00:20:48Z by kres dc032d7. concurrency: group: ${{ github.head_ref || github.run_id }} @@ -31,7 +31,7 @@ jobs: steps: - name: gather-system-info id: system-info - uses: kenchan0130/actions-system-info@v1.4.0 + uses: kenchan0130/actions-system-info@59699597e84e80085a750998045983daa49274c4 # version: v1.4.0 continue-on-error: true - name: print-system-info run: | @@ -55,13 +55,13 @@ jobs: done continue-on-error: true - name: checkout - uses: actions/checkout@v5 + uses: actions/checkout@8e8c483db84b4bee98b60c0593521ed34d9990e8 # version: v6.0.1 - name: Unshallow run: | git fetch --prune --unshallow - name: Set up Docker Buildx id: setup-buildx - uses: docker/setup-buildx-action@v3 + uses: docker/setup-buildx-action@8d2750c68a42422c14e847fe6c8ac0403b4cbd6f # version: v3.12.0 with: append: | - endpoint: tcp://buildkit-arm64.ci.svc.cluster.local:1234 @@ -74,7 +74,7 @@ jobs: make - name: Login to registry if: github.event_name != 'pull_request' - uses: docker/login-action@v3 + uses: docker/login-action@5e57cd118135c172c3672efd75eb46360885c0ef # version: v3.6.0 with: password: ${{ secrets.GITHUB_TOKEN }} registry: ghcr.io @@ -89,7 +89,7 @@ jobs: make release-notes - name: Release if: startsWith(github.ref, 'refs/tags/') - uses: softprops/action-gh-release@v2 + uses: softprops/action-gh-release@a06a81a03ee405af7f2048a818ed3f03bbf83c7b # version: v2.5.0 with: body_path: _out/RELEASE_NOTES.md draft: "true" diff --git a/.github/workflows/lock.yml b/.github/workflows/lock.yml index 5e9d68d..4390627 100644 --- a/.github/workflows/lock.yml +++ b/.github/workflows/lock.yml @@ -1,6 +1,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2025-11-12T13:55:37Z by kres 911d166. +# Generated on 2026-02-02T00:20:48Z by kres dc032d7. "on": schedule: @@ -14,7 +14,7 @@ jobs: - ubuntu-latest steps: - name: Lock old issues - uses: dessant/lock-threads@v5.0.1 + uses: dessant/lock-threads@7266a7ce5c1df01b1c6db85bf8cd86c737dadbe7 # version: v6.0.0 with: issue-inactive-days: "60" log-output: "true" diff --git a/.github/workflows/slack-notify-ci-failure.yaml b/.github/workflows/slack-notify-ci-failure.yaml index bb76eef..791f8e3 100644 --- a/.github/workflows/slack-notify-ci-failure.yaml +++ b/.github/workflows/slack-notify-ci-failure.yaml @@ -1,6 +1,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2025-11-12T13:55:37Z by kres 911d166. +# Generated on 2026-02-02T00:20:48Z by kres dc032d7. "on": workflow_run: @@ -18,7 +18,7 @@ jobs: if: github.event.workflow_run.conclusion == 'failure' && github.event.workflow_run.event != 'pull_request' steps: - name: Slack Notify - uses: slackapi/slack-github-action@v2 + uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # version: v2.1.1 with: method: chat.postMessage payload: | diff --git a/.github/workflows/slack-notify.yaml b/.github/workflows/slack-notify.yaml index b240c9d..b89d247 100644 --- a/.github/workflows/slack-notify.yaml +++ b/.github/workflows/slack-notify.yaml @@ -1,6 +1,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2025-11-12T13:55:37Z by kres 911d166. +# Generated on 2026-02-02T00:20:48Z by kres dc032d7. "on": workflow_run: @@ -23,7 +23,7 @@ jobs: run: | echo pull_request_number=$(gh pr view -R ${{ github.repository }} ${{ github.event.workflow_run.head_repository.owner.login }}:${{ github.event.workflow_run.head_branch }} --json number --jq .number) >> $GITHUB_OUTPUT - name: Slack Notify - uses: slackapi/slack-github-action@v2 + uses: slackapi/slack-github-action@91efab103c0de0a537f72a35f6b8cda0ee76bf0a # version: v2.1.1 with: method: chat.postMessage payload: | diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml index 4530347..443ca6d 100644 --- a/.github/workflows/stale.yml +++ b/.github/workflows/stale.yml @@ -1,6 +1,6 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2025-11-12T13:55:37Z by kres 911d166. +# Generated on 2026-02-02T00:20:48Z by kres dc032d7. "on": schedule: @@ -15,7 +15,7 @@ jobs: - ubuntu-latest steps: - name: Close stale issues and PRs - uses: actions/stale@v10.1.0 + uses: actions/stale@997185467fa4f803885201cee163a9f38240193d # version: v10.1.1 with: close-issue-message: This issue was closed because it has been stalled for 7 days with no activity. days-before-issue-close: "5" diff --git a/.kres.yaml b/.kres.yaml index deb884e..412d818 100644 --- a/.kres.yaml +++ b/.kres.yaml @@ -13,7 +13,7 @@ spec: - name: PKGS_PREFIX defaultValue: ghcr.io/siderolabs - name: PKGS - defaultValue: v1.12.0 + defaultValue: v1.12.0-32-g4f8efaf - name: TOOLS_PREFIX defaultValue: ghcr.io/siderolabs - name: TOOLS diff --git a/Makefile b/Makefile index 3e511b6..5d1336d 100644 --- a/Makefile +++ b/Makefile @@ -1,15 +1,16 @@ # THIS FILE WAS AUTOMATICALLY GENERATED, PLEASE DO NOT EDIT. # -# Generated on 2025-11-13T09:36:26Z by kres 911d166. +# Generated on 2026-02-02T02:37:59Z by kres dc032d7. # common variables SHA := $(shell git describe --match=none --always --abbrev=8 --dirty) TAG := $(shell git describe --tag --always --dirty --match v[0-9]\*) +TAG_SUFFIX ?= ABBREV_TAG := $(shell git describe --tags >/dev/null 2>/dev/null && git describe --tag --always --match v[0-9]\* --abbrev=0 || echo 'undefined') BRANCH := $(shell git rev-parse --abbrev-ref HEAD) ARTIFACTS := _out -IMAGE_TAG ?= $(TAG) +IMAGE_TAG ?= $(TAG)$(TAG_SUFFIX) OPERATING_SYSTEM := $(shell uname -s | tr '[:upper:]' '[:lower:]') GOARCH := $(shell uname -m | sed 's/x86_64/amd64/' | sed 's/aarch64/arm64/') REGISTRY ?= ghcr.io @@ -25,7 +26,7 @@ SOURCE_DATE_EPOCH := $(shell git log $(INITIAL_COMMIT_SHA) --pretty=%ct) # sync bldr image with pkgfile -BLDR_RELEASE := v0.5.5 +BLDR_RELEASE := v0.5.6 BLDR_IMAGE := ghcr.io/siderolabs/bldr:$(BLDR_RELEASE) BLDR := docker run --rm --user $(shell id -u):$(shell id -g) --volume $(PWD):/src --entrypoint=/bldr $(BLDR_IMAGE) --root=/src @@ -36,6 +37,7 @@ PLATFORM ?= linux/amd64,linux/arm64 PROGRESS ?= auto PUSH ?= false CI_ARGS ?= +WITH_BUILD_DEBUG ?= BUILD_ARGS = --build-arg=SOURCE_DATE_EPOCH=$(SOURCE_DATE_EPOCH) BUILD_ARGS += --build-arg=PKGS_PREFIX="$(PKGS_PREFIX)" BUILD_ARGS += --build-arg=PKGS="$(PKGS)" @@ -50,7 +52,7 @@ COMMON_ARGS += $(BUILD_ARGS) # extra variables PKGS_PREFIX ?= ghcr.io/siderolabs -PKGS ?= v1.12.0 +PKGS ?= v1.12.0-32-g4f8efaf TOOLS_PREFIX ?= ghcr.io/siderolabs TOOLS ?= v1.12.0 @@ -108,6 +110,10 @@ respectively. endef +ifneq (, $(filter $(WITH_BUILD_DEBUG), t true TRUE y yes 1)) +BUILD := BUILDX_EXPERIMENTAL=1 docker buildx debug --invoke /bin/sh --on error build +endif + all: $(TARGETS) ## Builds all targets defined. $(ARTIFACTS): ## Creates artifacts directory. diff --git a/README.md b/README.md index 4c483ff..ac6a44f 100644 --- a/README.md +++ b/README.md @@ -1,11 +1,107 @@ # sbc-jetson -This repo provides the overlay for NVIDIA Jetson Talos image. +This repository provides **overlay support for NVIDIA Jetson single-board computers in Talos Linux**. It creates custom installers that integrate NVIDIA Jetson hardware with Talos Linux, including proper U-Boot bootloader support, device tree configurations, and hardware-specific kernel parameters. -Support for this will be based on [NVIDIA embedded lifecycle](https://developer.nvidia.com/embedded/lifecycle). +Support for this project is based on [NVIDIA embedded lifecycle](https://developer.nvidia.com/embedded/lifecycle). -## Supported Overlay +## Project Overview -| Overlay Name | Board | Description | -| ------------ | ----------- | ------------------- | -| jetson_nano | Jetson Nano | Jetson Nano overlay | +**sbc-jetson** enables Talos Linux to run on NVIDIA Jetson devices by: + +- **Custom Installers**: Device-specific installers that handle hardware configuration during Talos installation +- **U-Boot Integration**: Tegra-optimized U-Boot bootloader support using mainline U-Boot v2026.01 +- **Device Tree Support**: Proper DTB (Device Tree Blob) installation for each Jetson variant using NVIDIA validated device trees +- **Hardware Configuration**: Optimized kernel boot parameters and system settings for Jetson hardware + +## Supported Overlays + +| Overlay Name | Board | Tegra SoC | U-Boot Config | Description | +| ---------------- | ---------------- | --------- | ------------- | ------------------------ | +| jetson_nano | Jetson Nano | Tegra210 | p3450-0000 | Jetson Nano overlay | +| jetson_orin_nano | Jetson Orin Nano | Tegra234 | N/A* | Jetson Orin Nano overlay | +| jetson_agx_orin | AGX Orin | Tegra234 | N/A* | Jetson AGX Orin overlay | + +_*Orin models currently use DTBs only (no custom U-Boot) since mainline lacks Tegra234 configs_ + +### Current Architecture Details + +- **U-Boot Version**: v2026.01 (mainline) +- **Multi-Model Support**: All three Jetson models supported simultaneously +- **Device Trees**: + - Nano: `nvidia/tegra210-p3450-0000.dtb` (built by U-Boot) + - Orin Nano: `nvidia/tegra234-p3768-0000+p3767-0000.dtb` (from NVIDIA L4T r36.4.4) + - AGX Orin: `nvidia/tegra234-p3701-0000+p3737-0000.dtb` (from NVIDIA L4T r36.4.4) +- **Boot Configuration**: Serial console, security hardening, model-specific optimizations +- **Platform**: ARM64/AArch64 +- **DTB Source**: Mainline U-Boot for Nano, NVIDIA L4T BSP for Orin models (since mainline lacks Tegra234 configs) + +## Development + +### Project Structure + +``` +├── artifacts/u-boot/ # U-Boot build configuration (multi-model support) +├── installers/ # Device-specific installers +│ ├── jetson_nano/ # Jetson Nano installer implementation +│ ├── jetson_orin_nano/ # Jetson Orin Nano installer implementation +│ └── jetson_agx_orin/ # Jetson AGX Orin installer implementation +├── profiles/ # Talos image profiles +│ ├── jetson_nano/ # Nano-specific profile +│ ├── jetson_orin_nano/ # Orin Nano-specific profile +│ └── jetson_agx_orin/ # AGX Orin-specific profile +└── internal/ # Shared components +``` + +### Current Implementation Notes + +**Jetson Nano**: Uses mainline U-Boot with built-in Tegra210 support. Both U-Boot binary and device trees are built from source. + +**Orin Models**: Currently use **DTBs only** from NVIDIA L4T r36.4.4 BSP. No custom U-Boot is built since mainline U-Boot v2026.01 doesn't include Tegra234 board configurations yet. These models rely on: +- Stock bootloader from NVIDIA's BSP/flashed firmware +- NVIDIA's validated device trees extracted during build +- Talos overlay system for OS-level integration + +### Updating U-Boot Version + +Current U-Boot version can be updated in [`artifacts/u-boot/pkg.yaml`](artifacts/u-boot/pkg.yaml): + +```yaml +# Current: mainline v2026.01 +- url: https://github.com/u-boot/u-boot/archive/refs/tags/v2026.01.tar.gz + +# Update to newer version: +- url: https://github.com/u-boot/u-boot/archive/refs/tags/v2026.04.tar.gz +``` + +**Version Compatibility Reference**: + +| Jetson Model | Tegra SoC | U-Boot Config | Status in Mainline | +| ------------ | --------- | ------------- | ------------------- | +| Nano | Tegra210 | p3450-0000 | ✅ Supported | +| Orin Nano | Tegra234 | N/A | ❌ Using NVIDIA DTBs | +| AGX Orin | Tegra234 | N/A | ❌ Using NVIDIA DTBs | + +**NVIDIA L4T Integration**: For Orin models, device trees are extracted from NVIDIA's L4T r36.4.4 BSP during build process. + +### Building + +Build all components: +```bash +make +``` + +Build specific installer: +```bash +make jetson-nano-installer +``` + + +### Dev Dependencies + +- golang +- docker +- jq +- graphviz (dot) + +recommended: +- bash-completion \ No newline at end of file diff --git a/artifacts/u-boot/pkg.yaml b/artifacts/u-boot/pkg.yaml index d76789a..fa62099 100644 --- a/artifacts/u-boot/pkg.yaml +++ b/artifacts/u-boot/pkg.yaml @@ -8,25 +8,74 @@ dependencies: - stage: base steps: - sources: - - url: https://github.com/OE4T/u-boot-tegra/archive/refs/tags/v2022.07.tar.gz + - url: https://github.com/u-boot/u-boot/archive/refs/tags/v2026.01.tar.gz destination: u-boot.tar.bz2 - sha256: e8f03d0b3dc2d70db5833f0e6f3ac305c0de0d71ff823c7d6210edee68e29a46 - sha512: 986e79cfe56878f17750144c8e21f03a9f802d94b7e39ca7268336422f8ab99268d85a4debe5c8f48e25a31f8e1e37e02b3fad448c2737dee286fb07486a06ba + sha256: 03bb43c58d2343ee48dd191e0f181f0108425b179d84519add3a977071c3f654 + sha512: bf621285c526afbd22886ace2f04554dad3edc0b0d3c1bd095a851abe6e78676d1197904670a02e745959d83825bc798136970b9b1b87759c1891e4e77e11c01 + # NVIDIA L4T BSP for prebuilt DTBs (Orin Nano/AGX Orin support) + - url: https://developer.nvidia.com/downloads/embedded/l4t/r36_release_v4.4/release/Jetson_Linux_r36.4.4_aarch64.tbz2 + destination: nvidia-l4t.tbz2 + sha256: a6ce11c22100ab0976e419959182417c83d62f4272501bc8714f2e076e010f3b + sha512: eccea1d2ce1907c853b1a282aa4c018585b001633c36452e33f166a4ef507da009fec6487d6a8f8b97054e787c6d79a9b72a8362712956e9e441cfba5c7df599 env: SOURCE_DATE_EPOCH: {{ .BUILD_ARG_SOURCE_DATE_EPOCH }} prepare: - | tar xf u-boot.tar.bz2 --strip-components=1 - - | + + # Extract NVIDIA L4T DTBs + mkdir -p nvidia-dtbs + tar -xf nvidia-l4t.tbz2 -C nvidia-dtbs --strip-components=1 + + # Find and copy required DTB files from L4T package + # Orin Nano: Use standard variant (0000 revision) + find nvidia-dtbs -path "*/dtb/tegra234-p3768-0000+p3767-0000*.dtb" -not -name "*nv*" -exec cp {} dtb-jetson-orin-nano.dtb \; || \ + find nvidia-dtbs -path "*/dtb/tegra234-p3768-*+p3767-*.dtb" -not -name "*nv*" | head -1 | xargs -I {} cp {} dtb-jetson-orin-nano.dtb || \ + echo "Warning: Orin Nano DTB not found in L4T package" + + # AGX Orin: Use standard variant (0000 revision) + find nvidia-dtbs -path "*/dtb/tegra234-p3737-0000+p3701-0000*.dtb" -not -name "*nv*" -exec cp {} dtb-jetson-agx-orin.dtb \; || \ + find nvidia-dtbs -path "*/dtb/tegra234-p3737-*+p3701-*.dtb" -not -name "*nv*" | head -1 | xargs -I {} cp {} dtb-jetson-agx-orin.dtb || \ + echo "Warning: AGX Orin DTB not found in L4T package" + + # Build for Jetson Nano (Tegra210) make p3450-0000_defconfig sed -i "s/CONFIG_TOOLS_LIBCRYPTO=y/# CONFIG_TOOLS_LIBCRYPTO is not set/" .config build: - | + # Build U-Boot for Jetson Nano make -j $(nproc) HOSTLDLIBS_mkimage="-lssl -lcrypto" + cp u-boot.bin u-boot-jetson-nano.bin + + # Copy Jetson Nano DTB (built by U-Boot) + if [ -f arch/arm/dts/tegra210-p3450-0000.dtb ]; then + cp arch/arm/dts/tegra210-p3450-0000.dtb dtb-jetson-nano.dtb + fi + + # Note: Orin models use prebuilt DTBs from NVIDIA L4T since + # mainline U-Boot v2026.01 doesn't have Tegra234 board configs yet + echo "Using prebuilt NVIDIA DTBs for Orin models:" + ls -la dtb-jetson-*.dtb 2>/dev/null || echo "No Orin DTBs found" install: - | mkdir -p /rootfs/artifacts/arm64/u-boot/jetson_nano - cp -v u-boot.bin /rootfs/artifacts/arm64/u-boot/jetson_nano + mkdir -p /rootfs/artifacts/arm64/dtb/nvidia + + # Install Jetson Nano U-Boot and DTB + cp -v u-boot-jetson-nano.bin /rootfs/artifacts/arm64/u-boot/jetson_nano/u-boot.bin + + if [ -f dtb-jetson-nano.dtb ]; then + cp -v dtb-jetson-nano.dtb /rootfs/artifacts/arm64/dtb/nvidia/tegra210-p3450-0000.dtb + fi + + # Install Orin DTBs from NVIDIA L4T (no U-Boot binaries since configs don't exist yet) + if [ -f dtb-jetson-orin-nano.dtb ]; then + cp -v dtb-jetson-orin-nano.dtb /rootfs/artifacts/arm64/dtb/nvidia/tegra234-p3768-0000+p3767-0000.dtb + fi + + if [ -f dtb-jetson-agx-orin.dtb ]; then + cp -v dtb-jetson-agx-orin.dtb /rootfs/artifacts/arm64/dtb/nvidia/tegra234-p3701-0000+p3737-0000.dtb + fi finalize: - from: /rootfs to: /rootfs diff --git a/go.work b/go.work index e599c9c..0b20256 100644 --- a/go.work +++ b/go.work @@ -1,3 +1,5 @@ go 1.25.4 use ./installers/jetson_nano/src +use ./installers/jetson_orin_nano/src +use ./installers/jetson_agx_orin/src diff --git a/installers/jetson_agx_orin/pkg.yaml b/installers/jetson_agx_orin/pkg.yaml new file mode 100644 index 0000000..f0cd313 --- /dev/null +++ b/installers/jetson_agx_orin/pkg.yaml @@ -0,0 +1,32 @@ +name: jetson_agx_orin +variant: scratch +shell: /bin/bash +dependencies: + - stage: base +steps: + - env: + GOPATH: /tmp/go + network: default + cachePaths: + - /.cache/go-build + - /tmp/go/pkg + prepare: + - | + cd /pkg/src + go mod download + - env: + GOPATH: /tmp/go + cachePaths: + - /.cache/go-build + - /tmp/go/pkg + build: + - | + cd /pkg/src + go build -ldflags "${GO_LDFLAGS}" -o /jetson_agx_orin_installer . + install: + - | + mkdir -p /rootfs/installers + cp /jetson_agx_orin_installer /rootfs/installers/ +finalize: + - from: /rootfs + to: /rootfs \ No newline at end of file diff --git a/installers/jetson_agx_orin/src/go.mod b/installers/jetson_agx_orin/src/go.mod new file mode 100644 index 0000000..6782fb4 --- /dev/null +++ b/installers/jetson_agx_orin/src/go.mod @@ -0,0 +1,9 @@ +module github.com/siderolabs/sbc-jetson/installers/jetson_agx_orin + +go 1.22 + +require ( + github.com/siderolabs/go-copy v0.1.0 + github.com/siderolabs/talos/pkg/machinery v1.8.0-alpha.0 + golang.org/x/sys v0.22.0 +) \ No newline at end of file diff --git a/installers/jetson_agx_orin/src/main.go b/installers/jetson_agx_orin/src/main.go new file mode 100644 index 0000000..cc7b06c --- /dev/null +++ b/installers/jetson_agx_orin/src/main.go @@ -0,0 +1,83 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package main + +import ( + _ "embed" + "os" + "path/filepath" + + "github.com/siderolabs/go-copy/copy" + "github.com/siderolabs/talos/pkg/machinery/overlay" + "github.com/siderolabs/talos/pkg/machinery/overlay/adapter" + "golang.org/x/sys/unix" +) + +const ( + // References for Jetson AGX Orin (Tegra234) + // - https://github.com/u-boot/u-boot/blob/master/configs/p3701-0000_defconfig + // - https://developer.nvidia.com/embedded/learn/get-started-jetson-agx-orin-devkit + dtb = "nvidia/tegra234-p3701-0000+p3737-0000.dtb" +) + +func main() { + adapter.Execute(&JetsonAGXOrinInstaller{}) +} + +type JetsonAGXOrinInstaller struct{} + +type jetsonAGXOrinExtraOptions struct{} + +func (i *JetsonAGXOrinInstaller) GetOptions(extra jetsonAGXOrinExtraOptions) (overlay.Options, error) { + return overlay.Options{ + Name: "jetson_agx_orin", + KernelArgs: []string{ + "console=tty0", + "console=ttyS0,115200", + "sysctl.kernel.kexec_load_disabled=1", + "talos.dashboard.disabled=1", + // AGX Orin specific optimizations + "tegra_fbmem=0x2000000@0x278000000", + "lut_mem=0x2008@0x276000000", + // Enhanced memory and performance settings for AGX Orin + "nvdec_enabled", + "nvidia_drm.modeset=1", + }, + }, nil +} + +func (i *JetsonAGXOrinInstaller) Install(options overlay.InstallOptions[jetsonAGXOrinExtraOptions]) error { + var f *os.File + + f, err := os.OpenFile(options.InstallDisk, os.O_RDWR|unix.O_CLOEXEC, 0o666) + if err != nil { + return err + } + + defer f.Close() //nolint:errcheck + + // NB: In the case that the block device is a loopback device, we sync here + // to ensure that the file is written before the loopback device is + // unmounted. + err = f.Sync() + if err != nil { + return err + } + + src := filepath.Join(options.ArtifactsPath, "arm64/dtb", dtb) + dst := filepath.Join(options.MountPrefix, "/boot/EFI/dtb", dtb) + + err = os.MkdirAll(filepath.Dir(dst), 0o600) + if err != nil { + return err + } + + err = copy.File(src, dst) + if err != nil { + return err + } + + return nil +} \ No newline at end of file diff --git a/installers/jetson_orin_nano/pkg.yaml b/installers/jetson_orin_nano/pkg.yaml new file mode 100644 index 0000000..424399b --- /dev/null +++ b/installers/jetson_orin_nano/pkg.yaml @@ -0,0 +1,32 @@ +name: jetson_orin_nano +variant: scratch +shell: /bin/bash +dependencies: + - stage: base +steps: + - env: + GOPATH: /tmp/go + network: default + cachePaths: + - /.cache/go-build + - /tmp/go/pkg + prepare: + - | + cd /pkg/src + go mod download + - env: + GOPATH: /tmp/go + cachePaths: + - /.cache/go-build + - /tmp/go/pkg + build: + - | + cd /pkg/src + go build -ldflags "${GO_LDFLAGS}" -o /jetson_orin_nano_installer . + install: + - | + mkdir -p /rootfs/installers + cp /jetson_orin_nano_installer /rootfs/installers/ +finalize: + - from: /rootfs + to: /rootfs \ No newline at end of file diff --git a/installers/jetson_orin_nano/src/go.mod b/installers/jetson_orin_nano/src/go.mod new file mode 100644 index 0000000..8a30fe8 --- /dev/null +++ b/installers/jetson_orin_nano/src/go.mod @@ -0,0 +1,9 @@ +module github.com/siderolabs/sbc-jetson/installers/jetson_orin_nano + +go 1.22 + +require ( + github.com/siderolabs/go-copy v0.1.0 + github.com/siderolabs/talos/pkg/machinery v1.8.0-alpha.0 + golang.org/x/sys v0.22.0 +) \ No newline at end of file diff --git a/installers/jetson_orin_nano/src/main.go b/installers/jetson_orin_nano/src/main.go new file mode 100644 index 0000000..23f0d84 --- /dev/null +++ b/installers/jetson_orin_nano/src/main.go @@ -0,0 +1,80 @@ +// This Source Code Form is subject to the terms of the Mozilla Public +// License, v. 2.0. If a copy of the MPL was not distributed with this +// file, You can obtain one at http://mozilla.org/MPL/2.0/. + +package main + +import ( + _ "embed" + "os" + "path/filepath" + + "github.com/siderolabs/go-copy/copy" + "github.com/siderolabs/talos/pkg/machinery/overlay" + "github.com/siderolabs/talos/pkg/machinery/overlay/adapter" + "golang.org/x/sys/unix" +) + +const ( + // References for Jetson Orin Nano (Tegra234) + // - https://github.com/u-boot/u-boot/blob/master/configs/p3767-0000_defconfig + // - https://developer.nvidia.com/embedded/learn/get-started-jetson-orin-nano-devkit + dtb = "nvidia/tegra234-p3768-0000+p3767-0000.dtb" +) + +func main() { + adapter.Execute(&JetsonOrinNanoInstaller{}) +} + +type JetsonOrinNanoInstaller struct{} + +type jetsonOrinNanoExtraOptions struct{} + +func (i *JetsonOrinNanoInstaller) GetOptions(extra jetsonOrinNanoExtraOptions) (overlay.Options, error) { + return overlay.Options{ + Name: "jetson_orin_nano", + KernelArgs: []string{ + "console=tty0", + "console=ttyS0,115200", + "sysctl.kernel.kexec_load_disabled=1", + "talos.dashboard.disabled=1", + // Orin Nano specific optimizations + "tegra_fbmem=0x800000@0x278800000", + "lut_mem=0x2008@0x278000000", + }, + }, nil +} + +func (i *JetsonOrinNanoInstaller) Install(options overlay.InstallOptions[jetsonOrinNanoExtraOptions]) error { + var f *os.File + + f, err := os.OpenFile(options.InstallDisk, os.O_RDWR|unix.O_CLOEXEC, 0o666) + if err != nil { + return err + } + + defer f.Close() //nolint:errcheck + + // NB: In the case that the block device is a loopback device, we sync here + // to ensure that the file is written before the loopback device is + // unmounted. + err = f.Sync() + if err != nil { + return err + } + + src := filepath.Join(options.ArtifactsPath, "arm64/dtb", dtb) + dst := filepath.Join(options.MountPrefix, "/boot/EFI/dtb", dtb) + + err = os.MkdirAll(filepath.Dir(dst), 0o600) + if err != nil { + return err + } + + err = copy.File(src, dst) + if err != nil { + return err + } + + return nil +} \ No newline at end of file diff --git a/installers/pkg.yaml b/installers/pkg.yaml index 329f49e..8b335e3 100644 --- a/installers/pkg.yaml +++ b/installers/pkg.yaml @@ -1,14 +1,42 @@ name: sbc-jetson variant: scratch dependencies: + # Currently only Jetson Nano is supported with U-Boot - stage: jetson_nano - stage: u-boot platform: linux/arm64 - stage: profiles - - image: "{{ .BUILD_ARG_PKGS_PREFIX }}/kernel:{{ .BUILD_ARG_PKGS }}" - platform: linux/arm64 - from: /dtb/nvidia/tegra210-p3450-0000.dtb - to: /rootfs/artifacts/arm64/dtb/nvidia/tegra210-p3450-0000.dtb + finalize: - from: /rootfs to: / + +stages: + # Main installer stage - Jetson Nano only for now + - name: jetson_nano + dependencies: + - stage: u-boot + runtime: true + from: /artifacts/arm64/u-boot/jetson_nano/u-boot.bin + to: /artifacts/arm64/u-boot/jetson_nano/u-boot.bin + # DTB now provided by U-Boot stage + - stage: u-boot + runtime: true + from: /artifacts/arm64/dtb/nvidia/tegra210-p3450-0000.dtb + to: /artifacts/arm64/dtb/nvidia/tegra210-p3450-0000.dtb + build: + - | + mkdir -p /rootfs/jetson_nano + cd installers/jetson_nano/src + go mod download + CGO_ENABLED=0 GOOS=linux GOARCH=arm64 go build -o /rootfs/jetson_nano/installer . + install: + - | + mkdir -p /rootfs/artifacts/arm64/installer/jetson_nano + cp -r /rootfs/jetson_nano/* /rootfs/artifacts/arm64/installer/jetson_nano/ + + # TODO: Add Orin support when U-Boot configs become available + # jetson_orin_nano: + # - Waiting for p3767-0000_defconfig in mainline U-Boot + # jetson_agx_orin: + # - Waiting for p3701-0000_defconfig in mainline U-Boot diff --git a/profiles/jetson_agx_orin/jetson_agx_orin.yaml b/profiles/jetson_agx_orin/jetson_agx_orin.yaml new file mode 100644 index 0000000..048a5de --- /dev/null +++ b/profiles/jetson_agx_orin/jetson_agx_orin.yaml @@ -0,0 +1,10 @@ +arch: arm64 +platform: metal +secureboot: false +output: + kind: image + outFormat: .xz + imageOptions: + diskSize: 1306525696 + diskFormat: raw + bootloader: grub \ No newline at end of file diff --git a/profiles/jetson_orin_nano/jetson_orin_nano.yaml b/profiles/jetson_orin_nano/jetson_orin_nano.yaml new file mode 100644 index 0000000..048a5de --- /dev/null +++ b/profiles/jetson_orin_nano/jetson_orin_nano.yaml @@ -0,0 +1,10 @@ +arch: arm64 +platform: metal +secureboot: false +output: + kind: image + outFormat: .xz + imageOptions: + diskSize: 1306525696 + diskFormat: raw + bootloader: grub \ No newline at end of file