WSL2上でJetPack 6.0 DPをセットアップする

## はじめに

<https://docs.nvidia.com/sdk-manager/wsl-systems/index.html>にWSL2でSDK Managerを実行してJetPackをセットアップする手順が書いてあります。ただし、JetPack SDK 6.0 DPで試したところ、以下のようなエラーが出てしまいました。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/31158/ea807c42-99d6-9208-052a-b413cd4be358.png)

本記事ではこのエラーを回避する方法を探った過程をまとめます。基本的には<https://forums.developer.nvidia.com/t/wsl2-flashing-with-nvidia-sdk-manager/273823/9>の方法を参考にしています。

## 動作確認環境

今回用いた環境は以下の通りです。

- Windows 10 Pro 22H2
- WSL2: 2.0.14.0
- Jetson Device: reComputer J4012(Jetson Orin NX 16GB)
- Jetson Linux 36.2 <https://developer.nvidia.com/embedded/jetson-linux-r362>

バージョンやデバイスによってはここで紹介した方法でうまくいかない可能性があります。

## Ubuntu 20.04インストール

以下のコマンドを実行してWSL2上にUbuntu 20.04の環境を作ります。

```shell
wsl --update
wsl --install Ubuntu-20.04
```

Ubuntu 20.04のLinuxカーネルバージョンを確認します。

```shell
$ uname -a
Linux DESKTOP-UGHOTR0 5.15.133.1-microsoft-standard-WSL2 #1 SMP Thu Oct 5 21:02:42 UTC 2023 x86_64 x86_64 x86_64 GNU/Linux
```

この結果からLinuxカーネルのバージョンは`5.15.133.1-microsoft-standard-WSL2`であることがわかります。

## カスタムLinuxカーネルのビルド

Ubuntu 20.04上で以下のコマンドを実行して、カスタムLinuxカーネルのビルドに必要なパッケージをインストールします。

```shell
sudo apt-get update
sudo apt install build-essential flex bison dwarves libssl-dev libelf-dev bc
```

<https://forums.developer.nvidia.com/t/flash-jetson-orin-nano-wsl2/263654/9>に添付されているconfig.gzをダウンロードし、展開します。

```shell
gunzip config.gz
```

Ubuntu 20.04上で以下のコマンドを実行して、カスタムLinuxカーネルのビルドします。

```shell
git clone https://github.com/microsoft/WSL2-Linux-Kernel.git -b linux-msft-wsl-5.15.137.3
cd WSL2-Linux-Kernel
git submodule init
git submodule update
make KCONFIG_CONFIG=$HOME/config -j8
```

Ubuntu 20.04上で、ビルドして生成したvmlinuxをコピーします。`<username>`はご自身のアカウント名に置き換えてください。

```shell
cp vmlinux /mnt/c/Users/<username>/AppData/Local/Temp
```

ビルドして生成したvmlinuxを使用するようにWindows上にある`%USERPROFILE%\.wslconfig`に以下の記述を追記します。`<username>`はご自身のアカウント名に置き換えてください。

```shell
[wsl2]
kernel=C:\\Users\\<username>\\AppData\\Local\\Temp\\vmlinux
```

設定を反映するためにWindows上でWSL2をシャットダウンして起動します。

```shell
wsl --shutdown
wsl
```

Ubuntu 20.04上で`uname -a`を実行し、Linuxカーネルバージョンを確認します。

```shell
$ uname -a
Linux DESKTOP-UGHOTR0 5.15.137.3-microsoft-standard-WSL2+ #1 SMP Wed Jan 3 13:38:36 JST 2024 x86_64 x86_64 x86_64 GNU/Linux
```

この結果からカスタムLinuxカーネル（`5.15.137.3-microsoft-standard-WSL2+`）が使われていることがわかります。

## Force Recoveryモード

JetsonデバイスをForce Recoveryモードで起動し、Windows PCに接続します。reComputer J4012(Jetson Orin NX 16GB)の場合、<https://qiita.com/dandelion1124/items/58210e472b3057af97f5#11-force-recovery-mode起動>を参照ください。

## usbipd-winインストール

WSL2上でUSBデバイスにアクセスするために[usbipd-win](https://github.com/dorssel/usbipd-win)をインストールします。<https://github.com/dorssel/usbipd-win/releases>からインストーラを入手し、インストールします。今回、`usbipd-win_4.0.0.msi`を用いました。

## USBデバイスのアタッチ

Ubuntu 20.04上で以下のコマンドを実行します。

```shell
sudo apt install linux-tools-generic hwdata
sudo update-alternatives --install /usr/local/bin/usbip usbip /usr/lib/linux-tools/*-generic/usbip 20
```

管理者権限でPowerShellを開き、以下のコマンドを実行します。

```shell
usbipd list
```

実行例は以下の通りです。`APX`があるため、WindowsからForce Recoveryモードで起動したJetsonデバイスが認識できていることがわかります。

```shell
Connected:
BUSID  VID:PID    DEVICE                                                        STATE
1-1    0955:7323  APX                                                           Not shared
```

以下のコマンドを実行して、WSL2からUSBデバイスにアクセスできるようにします。

```shell
usbipd bind --busid 1-1
usbipd attach --busid 1-1 --wsl Ubuntu-20.04
```

Ubuntu 20.04上で`lsusb`を実行すると`NVIDIA Corp. APX`が表示されており、WSL2からJetsonデバイスが認識できていることがわかります。

```shell
$ lsusb
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 0955:7323 NVIDIA Corp. APX
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
```

## 前準備

<https://developer.nvidia.com/embedded/jetson-linux-r362>から以下のファイルをダウンロードします。

- Driver Package (BSP): `Jetson_Linux_R36.2.0_aarch64.tbz2`
- Sample Root Filesystem: `Tegra_Linux_Sample-Root-Filesystem_R36.2.0_aarch64.tbz2`

Ubuntu 20.04上で以下のコマンドを実行して前準備をします。

```shell
sudo apt-get install qemu-user-static sshpass abootimg nfs-kernel-server libxml2-utils lbzip2
sudo update-binfmts --import qemu-aarch64
sudo update-binfmts --import qemu-arm
sudo update-binfmts --import qemu-armeb
tar xf Jetson_Linux_R36.2.0_aarch64.tbz2
sudo tar xpf Tegra_Linux_Sample-Root-Filesystem_R36.2.0_aarch64.tbz2 -C Linux_for_Tegra/rootfs/
cd Linux_for_Tegra/
sudo ./apply_binaries.sh
sudo ./tools/l4t_flash_prerequisites.sh
```

## OSイメージ作成

Ubuntu 20.04上で以下のコマンドを実行します。

```shell
sudo ./tools/kernel_flash/l4t_initrd_flash.sh --no-flash --external-device nvme0n1p1 -p "-c ./bootloader/generic/cfg/flash_t234_qspi.xml" -c ./tools/kernel_flash/flash_l4t_t234_nvme.xml --showlogs --network usb0 jetson-orin-nano-devkit nvme0n1p1
```

を実行すると処理途中で以下のエラーメッセージが表示されます。

> Error: Unrecognized module SKU

エラーメッセージを読む限り、何らかの理由でSKU情報が取得できていないようです。また、前述のコマンド実行でUSBデバイスのアタッチが外れているので、管理者権限で開いたPowerShellで以下のコマンドを実行してUSBデバイスをアタッチします。

```shell
usbipd attach --busid 1-1 --wsl Ubuntu-20.04
```

<https://docs.nvidia.com/jetson/archives/r36.2/DeveloperGuide/IN/QuickStart.html#jetson-modules-and-configurations>を読むと、Jetson Orin NX 16GB-DRAMの場合、

- BOARDID: 3767
- BOARDSKU: 0000
- board: jetson-orin-nano-devkit

となっているため、環境変数をセットした状態で実行します。

```shell
sudo BOARDID=3767 BOARDSKU=0000 FAB=TS4 ./tools/kernel_flash/l4t_initrd_flash.sh --no-flash --external-device nvme0n1p1 -p "-c ./bootloader/generic/cfg/flash_t234_qspi.xml" -c ./tools/kernel_flash/flash_l4t_t234_nvme.xml --showlogs --network usb0 jetson-orin-nano-devkit nvme0n1p1
```

以下のメッセージが表示されていたらOSイメージが生成できていることがわかります。

```shell
Success
Cleaning up...
Finish generating flash package.
Put device in recovery mode, run with option --flash-only to flash device.
```

## OSイメージFlash

Ubuntu 20.04上で以下のコマンドを実行します。

```shell
sudo ./tools/kernel_flash/l4t_initrd_flash.sh --flash-only
```

処理が進むとデバイスのブートを待機している旨を表している以下のメッセージが表示されます。

> Unknown device "/sys/class/net/bonding_masters": No such device
> Waiting for target to boot-up...

このメッセージが表示されてからしばらくするとWindows上で「USB大容量記憶装置」として認識されるタイミングがあります。そのタイミングで管理者権限で開いたPowerShellで以下のコマンドを実行してWSL2上にUSBデバイスをアタッチします。

```shell
usbipd bind --busid 1-1
usbipd attach --busid 1-1 --wsl Ubuntu-20.04
```

アタッチ後、インストール処理が進むのでしばらく待ちます。以下のコマンドが表示されるとOSイメージがFlashできていることがわかります。

```shell
Flash is successful
Reboot device
Cleaning up...
```

## Reference

- <https://docs.nvidia.com/sdk-manager/wsl-systems/index.html>
- <https://docs.nvidia.com/jetson/archives/r36.2/DeveloperGuide/SD/FlashingSupport.html#sd-flashingsupport-flashshorinnxnano>
- <https://learn.microsoft.com/en-us/windows/wsl/connect-usb>
- <https://forums.developer.nvidia.com/t/wsl2-flashing-with-nvidia-sdk-manager/273823/9>