# Nvidia Jetson L4T Integration

**URL:** <https://hub.mender.io/t/nvidia-jetson-l4t-integration/3968>\
**Category:** Debian family\
**Tags:** nvidia, jetson\
**Created:** [August 4, 2021, 6:00am UTC](https://hub.mender.io/t/nvidia-jetson-l4t-integration/3968 "2021-08-04T06:00:00Z")\
**Posts on this page:** 5\
**Page:** 2

<div class="post-metadata">

**Author:** ![petarkalafatic](https://yyz2.discourse-cdn.com/flex036/user_avatar/hub.mender.io/petarkalafatic/32/1875_2.png) [@petarkalafatic](https://hub.mender.io/u/petarkalafatic)\
**Post date:** [April 25, 2023, 1:37pm UTC](https://hub.mender.io/t/nvidia-jetson-l4t-integration/3968/21 "2023-04-25T13:37:48Z")

</div>

Hi @lramirez

I have a question regarding the OTA update.  
Following the above steps I encounter a small issue. Everything goes fine and there is a partition swap with all my data exchanged between partitions A and B after the artifact update but there is no system update. Before and after the update when I do `cat / etc / nv_tegra_release` I get the same 32.6.1 version. I wanted to update from version 32.6.1 to version 32.7.3

Here are all my steps that I followed through the installation process:

Install a fresh Jetpack Linux version on AGX that supports A/B update ( I used 32.6.1 ):

On Host computer:

Download version from here:

> **[Jetson Linux Archive](https://developer.nvidia.com/embedded/jetson-linux-archive)**
>
> Find previous L4T releases and which Jetson modules they support.

tar xpf Jetson\_Linux\__aarch64.tbz2  
cd ./Linux\_for\_Tegra/rootfs  
sudo tar -jxpf …/…/Tegra-Linux-Sample-Root-Filesystem_\<release\_type\>.tbz2  
cd …/…  
tar xpf ./ota\_tools\__aarch64.tbz2  
tar xpf ./secureboot_\_aarch64.tbz2  
cd Linux\_for\_Tegra

Check the Sector size and No. of sectors of the hard drive you want to flash:  
sector size: cat /sys/block/nvme0n1/queue/hw\_sector\_size  
num\_sectors: cat /sys/block/nvme0n1/size  
In the Linux\_for\_Tegra/tools/kernel\_flash/flash\_l4t\_nvme\_rootfs\_ab.xml `<device type="nvme" instance="0" sector_size="512" num_sectors="1000215216">`

sudo ./apply\_binaries.sh

sudo ROOTFS\_AB=1 ./tools/kernel\_flash/l4t\_initrd\_flash.sh --external-device nvme0n1 -c ./tools/kernel\_flash/flash\_l4t\_nvme\_rootfs\_ab.xml --external-only -S 32GiB --showlogs jetson-agx-xavier-devkit external

On Jetson AGX Xavier:  
sudo mkfs.ext4 /dev/nvme0n1p12

sudo mkdir -p /data  
sudo su -c “echo ‘/dev/nvme0n1p12 /data ext4 defaults 0 0’ \>\> /etc/fstab”  
sudo mount -a

sudo apt update && sudo apt upgrade  
sudo apt install curl  
sudo apt install nano

curl -fLsS [https://get.mender.io](https://get.mender.io) -o get-mender.sh  
sudo bash get-mender.sh mender-client

configure mender client → hosted mender server credentials.

sudo mv /var/lib/mender /data  
sudo ln -s /data/mender /var/lib/mender  
sudo mkdir -p /usr/share/mender/modules/v3  
sudo touch /usr/share/mender/modules/v3/rootfs-image-jetson  
cd /usr/share/mender/modules/v3  
sudo nano rootfs-image-jetson

```auto
#!/bin/sh

set -ue

STATE="$1"
FILES="$2"

ota_payload_package="$FILES"/files/ota_payload_package.tar.gz
nvidia_tools="$FILES"/files/ota_tools_aarch64.tbz2

# Nvidia uses the concept of "slots", they will
# be always 0 and 1 values for A and B partitions

MENDER_ROOTFS_PART_A_NUMBER="0"
MENDER_ROOTFS_PART_B_NUMBER="1"

# Some useful information for integrity check
mkdir -p "/data/fs_update/"
mender_boot_part="/data/fs_update/mender_boot_part"
active_num="$(nvbootctrl get-current-slot)"

if test $active_num -eq $MENDER_ROOTFS_PART_A_NUMBER; then
    passive_num=$MENDER_ROOTFS_PART_B_NUMBER
else
    passive_num=$MENDER_ROOTFS_PART_A_NUMBER
fi

case "$STATE" in
      Download)
        if ["$(nvbootctrl get-number-slots)" != "2"]; then
            echo "Your device need to be configured to use A/B partitioning"
            exit 1
        fi
        ;;

    ArtifactInstall)
        # Let's record what slot we expect to boot next time
        echo $passive_num > $mender_boot_part
        # Let's enable Nvidia's scripts
        mkdir -p "$HOME"/workdir
        export WORKDIR="$HOME"/workdir
        tar -jxvf $nvidia_tools -C $WORKDIR
        # UDA partition as temp location disabled initially
        UDA=""
        # If you have a big enough UDA partition or a small rootfs
        # partition size, uncomment the following line  
        #UDA="data/"
        # Let's move the payload
        mkdir -p "/${UDA}ota/"
        mv $ota_payload_package "/${UDA}ota/"
        mkdir -p "/${UDA}ota_work"
        if [! -z "$UDA"]
        then
            ln -sfn "/${UDA}ota_work" "/ota_work"
        fi
        # Let's run the upgrade process
        cd ${WORKDIR}/Linux_for_Tegra/tools/ota_tools/version_upgrade
        ./nv_ota_start.sh /dev/nvme0n1 "/${UDA}ota/ota_payload_package.tar.gz"
        # nv_ota_start.sh set the unused slot to active for next reboot
        >&2 echo "Next boot will load Slot $passive_num" 
        #cleaning up the disk
        if [! -z "$UDA"]; then
            rm -rf "/${UDA}ota_work"
            rm -rf "/${UDA}ota/"
        fi   
        ;;

    PerformsFullUpdate)
        echo "Yes"
        ;;

    NeedsArtifactReboot)
        echo "Automatic"
        ;;

    SupportsRollback)
        echo "Yes"
        ;;

    ArtifactVerifyReboot)
        # We use stderr for logging as Mender protocol uses stdout for exchanging messages with the server.
        >&2 echo "ArtifactVerifyReboot: The active partition is $active_num while the last passive was $(cat $mender_boot_part)"
        if test "$(cat $mender_boot_part)" != "$active_num"; then
            exit 1
        fi
        # Recommend calling sync at the end here as well
        sync
        ;;

    ArtifactVerifyRollbackReboot)
        >&2 echo "ArtifactVerifyRollbackReboot: The active partition is $active_num while the last passive was $(cat $mender_boot_part)"
        if test "$(cat $mender_boot_part)" = "$active_num"; then
            exit 1
        fi
        # Recommend calling sync at the end here as well
        sync
        ;;

    ArtifactCommit)
        >&2 echo "ArtifactCommit: The active partition is $active_num while the last passive was $(cat $mender_boot_part)"
        if test "$(cat $mender_boot_part)" = "$active_num"; then
            nvbootctrl mark-boot-successful
        else
            # If we get here, an upgrade in standalone mode failed to  
            # boot and the user is trying to commit from the old OS.
            # This communicates to the user that the upgrade failed.
            echo "Upgrade failed and was reverted: refusing to commit!"
            exit 1
        fi
        ;;

    ArtifactRollback)
        >&2 echo "ArtifactRollback: The active partition is $active_num while the last passive was $(cat $mender_boot_part)"
        if test "$(cat $mender_boot_part)" = "$active_num"; then
            nvbootctrl set-active-boot-slot $passive_num
        fi
        sync
        ;;

esac
exit 0

```

a small note-----\> I replaced in this part of the script the internal with my external drive: `./nv_ota_start.sh /dev/nvme0n1 "/${UDA}ota/ota_payload_package.tar.gz"`

sudo chmod +x /usr/share/mender/modules/v3/rootfs-image-jetson  
sudo systemctl restart mender-client

sudo su  
sudo mender snapshot dump | ssh $USER@$HOST /bin/sh -c ‘cat \> $HOME/my-jetson-fs.raw’

on Host computer:

New Jetpack version ( I used 32.7.3 ):

> **[Jetson Linux Archive](https://developer.nvidia.com/embedded/jetson-linux-archive)**
>
> Find previous L4T releases and which Jetson modules they support.

tar xpf Jetson\_Linux\__aarch64.tbz2  
cd ./Linux\_for\_Tegra/rootfs  
sudo tar -jxpf …/…/Tegra-Linux-Sample-Root-Filesystem_\<release\_type\>.tbz2  
cd …/…  
tar xpf ./ota\_tools\_\_aarch64.tbz2  
cd Linux\_for\_Tegra

BASE\_BSP=/tmp/Jetpack\_Linux/32\_6\_1/Linux\_for\_Tegra  
TARGET\_BSP=/tmp/Jetpack\_Linux/32\_7\_3/Linux\_for\_Tegra

check:  
echo $TARGET\_BSP  
echo $BASE\_BSP

sudo ./tools/ota\_tools/version\_upgrade/build\_base\_recovery\_image.sh jetson-agx-xavier-devkit R32-6 ${BASE\_BSP} ${BASE\_BSP}/rootfs ${TARGET\_BSP}

go to the Mender snapshot file and run this commands to mount it as a filesystem image:  
mkdir -p tmp-fs  
sudo mount -o loop my-jetson-fs.raw tmp-fs  
cd tmp-fs  
sudo tar -cvpzf …/image\_fs.tar.gz --exclude=./data --exclude=./image\_fs.tar.gz --one-file-system ./  
cd …

cp tools/ota\_tools/version\_upgrade/nv\_ota\_rootfs\_updater.sh rootfs\_updater.sh  
sudo ./tools/ota\_tools/version\_upgrade/l4t\_generate\_ota\_package.sh -sr -o rootfs\_updater.sh -f /home/petar/jetson/image\_fs.tar.gz jetson-agx-xavier-devkit R32-6

Create Mender Arthefact:  
ARTIFACT\_NAME=“R37\_2\_3\_update”  
DEVICE\_TYPE=“jetson-agx-xavier”  
OUTPUT\_PATH=“/home/petar/R37\_2\_3\_update.mender”  
IMAGE=“/tmp/Jetpack\_Linux/32\_7\_3/Linux\_for\_Tegra/bootloader/jetson-agx-xavier-devkit/ota\_payload\_package.tar.gz”  
OTA\_TOOLS=“/tmp/Jetpack\_Linux/32\_7\_3/ota\_tools\_aarch64.tbz2”  
mender-artifact write module-image -T rootfs-image-jetson -n ${ARTIFACT\_NAME} -t ${DEVICE\_TYPE} -o ${OUTPUT\_PATH} -f ${IMAGE} -f ${OTA\_TOOLS}

upload to mender server using GUI or CLI

check jetpack version:  
cat / etc / nv\_tegra\_release

---

<div class="post-metadata">

**Author:** ![lramirez](https://yyz2.discourse-cdn.com/flex036/user_avatar/hub.mender.io/lramirez/32/1195_2.png) [@lramirez](https://hub.mender.io/u/lramirez)\
**Post date:** [April 27, 2023, 10:06pm UTC](https://hub.mender.io/t/nvidia-jetson-l4t-integration/3968/22 "2023-04-27T22:06:37Z")

</div>

Hello @petarkalafatic,

Regarding the delta feature this is not possible. In another thread I shared a workaround and the technical challenge on why this is not possible. I hope it helps 🙂

> [@How to perform OS OTA delta updates to Jetson Xavier NX 5.1.1JetPack using Mender?](https://hub.mender.io/t/how-to-perform-os-ota-delta-updates-to-jetson-xavier-nx-5-1-1jetpack-using-mender/5768/3):
>
> Hello @user_1, Sadly the delta updates are not compatible with your configuration. rootfs-image updates are exclusively with Operating Systems where we integrated Mender with the bootloader. For example, a yocto-based OS that has Mender layer included or a Debian/Ubuntu-based system that uses GRUB or u-boot. In the case of Jetson Linux (Ubuntu-based) from Nvidia, we created an Update Module that makes usage of the official Nvidia utilities (like nvbootctrl) to handle the swap from Active to In…

---

<div class="post-metadata">

**Author:** ![lramirez](https://yyz2.discourse-cdn.com/flex036/user_avatar/hub.mender.io/lramirez/32/1195_2.png) [@lramirez](https://hub.mender.io/u/lramirez)\
**Post date:** [April 27, 2023, 10:10pm UTC](https://hub.mender.io/t/nvidia-jetson-l4t-integration/3968/23 "2023-04-27T22:10:46Z")

</div>

Hello @petarkalafatic,

Regarding the second question about not seeing the rootfs updated. Did you check with `nvbootctrl` that the device was able to actually perform the flip between slots? Can you check the inactive/passive slot to see if the content was copied as expected but the bootloader did not flip the partitions?

BR,  
Luis

---

<div class="post-metadata">

**Author:** ![Pandananana](https://yyz2.discourse-cdn.com/flex036/user_avatar/hub.mender.io/pandananana/32/2503_2.png) [@Pandananana](https://hub.mender.io/u/Pandananana)\
**Post date:** [June 3, 2025, 11:48am UTC](https://hub.mender.io/t/nvidia-jetson-l4t-integration/3968/24 "2025-06-03T11:48:23Z")

</div>

Is Ubuntu 18.04 (Bionic) no longer supported? When i run the get-mender script I get

```auto
ERROR: your distribution's version (bionic) is either not recognized or not supported.

```

I can’t seem to find any information about when support was dropped, or what to do in this case?

Also, from reading other forum posts, it seems that Jetpack +5 is not supported, which means that I can’t install Ubuntu 20.04?

---

<div class="post-metadata">

**Author:** ![lramirez](https://yyz2.discourse-cdn.com/flex036/user_avatar/hub.mender.io/lramirez/32/1195_2.png) [@lramirez](https://hub.mender.io/u/lramirez)\
**Post date:** [June 6, 2025, 10:47pm UTC](https://hub.mender.io/t/nvidia-jetson-l4t-integration/3968/25 "2025-06-06T22:47:28Z")

</div>

Hello @Pandananana,

I think the script dropped the support for 18.04, however, you can still install it by getting it from [/repos/debian/pool/main/m/mender-client](https://downloads.mender.io/repos/debian/pool/main/m/mender-client/)

For a newer Jetson Linux release for Orin devices, you can use this guide instead [Nvidia Jetson Orin L4T image Update](https://hub.mender.io/t/nvidia-jetson-orin-l4t-image-update/6985)

[Previous page](https://hub.mender.io/t/nvidia-jetson-l4t-integration/3968.md?page=1)
