Jetson NanoでSDカードのルートファイルシステムをUSBメモリへコピーしてUSBメモリから起動する方法

# はじめに

JetPack 4.5でUSBドライブから起動する機能が実装され、試してみた結果を記事に書きました。

https://qiita.com/kitazaki/items/8894eb37bd7dceed7992

既存で使用しているSDカードの中身をUSBメモリへコピー(クローン)してUSB起動させることはできないか、という問い合わせを受けましたので、Jetson Nano 2GBで試してみました。

![スクリーンショット 2021-03-17 17.58.19.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/72479/056e7bd9-1457-86e6-0146-1b3233dd8e50.png)

# 前提条件

USBドライブから起動するにはJetson NanoがJetPack 4.5以降(2021年3月17日時点でJetPack 4.5または4.5.1)に含まれるU-Boot(バージョン2020.04)に更新されている必要があります。
一度、新規にJetPack 4.5以降をインストールすれば条件を満たすことができます。

# 環境

- Jetson Nano 2GB  
  - JetPack 4.5をインストール起動して、U-Boot(バージョン2020.04)に更新済
- SDカード 16GB (JetPack 4.4.1)  
- USBメモリ 16GB

```bash
$ uname -a
Linux jetson-desktop 4.9.140-tegra #1 SMP PREEMPT Fri Oct 16 12:32:46 PDT 2020 aarch64 aarch64 aarch64 GNU/Linux

$ cat /etc/nv_tegra_release 
# R32 (release), REVISION: 4.4, GCID: 23942405, BOARD: t210ref, EABI: aarch64, DATE: Fri Oct 16 19:44:43 UTC 2020

$ cat /etc/os-release 
NAME="Ubuntu"
VERSION="18.04.5 LTS (Bionic Beaver)"
ID=ubuntu
ID_LIKE=debian
PRETTY_NAME="Ubuntu 18.04.5 LTS"
VERSION_ID="18.04"
HOME_URL="https://www.ubuntu.com/"
SUPPORT_URL="https://help.ubuntu.com/"
BUG_REPORT_URL="https://bugs.launchpad.net/ubuntu/"
PRIVACY_POLICY_URL="https://www.ubuntu.com/legal/terms-and-policies/privacy-policy"
VERSION_CODENAME=bionic
UBUNTU_CODENAME=bionic
```

# 手順

### 1. SDカードから起動する

通常とおりSDカードからOSを起動します。

### 2. USBメモリを挿す

OSが起動したらUSBメモリを挿し、USBメモリが認識されたことを確認します。
dmesgコマンドで以下のようなログが出力されれば正常です。
/dev/sdaとして認識されています。

```bash
$ dmesg
... (省略) ...
[ 1602.930225] usb 2-1: new SuperSpeed USB device number 2 using tegra-xusb
[ 1602.959535] usb 2-1: New USB device found, idVendor=090c, idProduct=3267
[ 1602.959604] usb 2-1: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[ 1602.959648] usb 2-1: Product: Flash Disk
[ 1602.959692] usb 2-1: Manufacturer: USB
[ 1602.959732] usb 2-1: SerialNumber: AA18102420001141
[ 1602.966588] usb-storage 2-1:1.0: USB Mass Storage device detected
[ 1602.968800] scsi host0: usb-storage 2-1:1.0
[ 1604.109140] scsi 0:0:0:0: Direct-Access     USB      Flash Disk       1100 PQ: 0 ANSI: 6
[ 1604.118480] sd 0:0:0:0: [sda] 31129600 512-byte logical blocks: (15.9 GB/14.8 GiB)
[ 1604.127513] sd 0:0:0:0: [sda] Write Protect is off
[ 1604.132368] sd 0:0:0:0: [sda] Mode Sense: 43 00 00 00
[ 1604.132997] sd 0:0:0:0: [sda] Write cache: enabled, read cache: enabled, doesn't support DPO or FUA
[ 1604.151846]  sda: sda1 sda2 sda3 sda4 sda5 sda6 sda7 sda8 sda9 sda10 sda11 sda12 sda13 sda14
[ 1604.155352] sd 0:0:0:0: [sda] Attached SCSI removable disk
```

### 3. USBメモリのパーティション作成、フォーマット(ext4)

パーティションを作成します。

```bash
$ sudo fdisk /dev/sda

Welcome to fdisk (util-linux 2.31.1).
Changes will remain in memory only, until you decide to write them.
Be careful before using the write command.

Command (m for help): p ← p を入力
Disk /dev/sda: 14.9 GiB, 15938355200 bytes, 31129600 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Disklabel type: gpt
Disk identifier: 7E4729B3-D842-8D46-90AF-25AC14C4D43D

Command (m for help): n ← n を入力
Partition number (1-128, default 1): (改行) ← Enter を入力
First sector (2048-31129566, default 2048): (改行) ← Enter を入力
Last sector, +sectors or +size{K,M,G,T,P} (2048-31129566, default 31129566): (改行) ← Enter を入力

Created a new partition 1 of type 'Linux filesystem' and of size 14.9 GiB.

Command (m for help): w ← w を入力
The partition table has been altered.
Calling ioctl() to re-read partition table.
Syncing disks.
```

※ USBメモリが空でない場合(既存パーティションが存在するなど)は、d コマンドでパーティションを全て削除してからパーティションを作成してください。

次にext4でフォーマットを行います。

```bash
$ sudo mkfs -t ext4 /dev/sda1

mke2fs 1.44.1 (24-Mar-2018)
Creating filesystem with 3890939 4k blocks and 972944 inodes
Filesystem UUID: 7e25ad28-ac8c-4728-a790-9dec03a58321
Superblock backups stored on blocks: 
	32768, 98304, 163840, 229376, 294912, 819200, 884736, 1605632, 2654208

Allocating group tables: done                            
Writing inode tables: done                            
Creating journal (16384 blocks): done
Writing superblocks and filesystem accounting information: done
```

### 4. SDカードからUSBメモリへコピー(クローン)

USBメモリをマウントします。

```bash
$ sudo mount /dev/sda1 /mnt
```

次にSDカードの中身をUSBメモリへコピー(クローン)します。

```bash
$ sudo rsync -axHAWX --numeric-ids --info=progress2 --exclude={"/dev/","/proc/","/sys/","/tmp/","/run/","/mnt/","/media/*","/lost+found"} / /mnt

 12,887,666,586  96%   10.83MB/s    0:18:55 (xfr#145213, to-chk=0/212390)    ← 処理状況が表示される
```

### 5. 起動パーティションの変更(extlinux.confファイルの変更)

起動パーティションの設定はSDカードから起動することを前提としていますので、USBメモリから起動するようにextlinux.confファイルを編集します。

```bash
$ cd /mnt/boot/extlinux
$ sudo cp extlinux.conf extlinux.conf_org
$ sudo vi extlinux.conf
```

下記の例では、10行目のroot=の値を/dev/mmcblk0p1 (SDカード)から/dev/sda1 (USBメモリ)に変更しています。
※ 使用している環境によって、行番号が異なる場合があります。

```text:diff
$ diff extlinux.conf extlinux.conf_org 
10c10
<       APPEND ${cbootargs} quiet root=/dev/sda1 rw rootwait rootfstype=ext4 console=ttyS0,115200n8 console=tty0 fbcon=map:0 net.ifnames=0 
---
>       APPEND ${cbootargs} quiet root=/dev/mmcblk0p1 rw rootwait rootfstype=ext4 console=ttyS0,115200n8 console=tty0 fbcon=map:0 net.ifnames=0 
```

### 6. USBメモリから起動

Jetson Nanoの電源を落とし、SDカードを抜いて電源を入れると、USBメモリから起動します。