MacでJetson AGX XavierをNVME-SSDからbootさせる。

# 目的
MacのParallels上で動作するHOSTで、JetPack 4.6 (L4T 32.6.1)を利用したjetsonhacks提供のスクリプトを使用すると、イメージのUSB経由での書き込みに失敗する。そこで、Xavierでイメージの書き込みを行う。

# 必要なもの
* Jetson AGX Xavier devkit
* RAMが16GB以上ディスク空き容量100GB程度のMac（使用したMac:MBP15 2013late）
* parallels
* SDやUSBメモリなどの64GB以上のbootイメージ保存用メディア
* USB-boot用の128GB以上のUSBメモリー
* 128GB以上のNVME-SSD

# 手順
1. AGX Xavierのhostとして使用する64bit版ubuntu18をMacの仮想環境にインストール
1. SDK Managerでjetson AGX XavierのemmcにLinuxをインストール
1. Mac上のubuntu上で、nvme-bootのイメージファイルを作成。
1. Jetson AGX Xavier devkitにnvmeSSDの装着
1. Xavierをemmcからbootし、Macで作成したnvme-bootイメージファイルをNVME-SSDにflash
1. Xavierをnvmeからbootし、Jetpackをインストール

# AGX Xavierのホスト用Ubuntuのインストール
Macでの作業
1. MACの仮想環境（parallels）にubuntu18.02をインストール
1. ubuntu動作環境を
*  Memory:8GB
*  Disk:128GB
   に変更
 
# AGX XavierのemmcにOSを書き込む
ホスト用ubuntuでの作業
1. hostのパーティションを128GB以上にリサイズ
1. SDK Managerのインストール
1. Xavierをrecovery modeにし、HOSTにUSBケーブルを接続。
1. SDK managerを使用してXavierにOSを書き込む。

# nvmeからブートするlinuxイメージを作成
ubuntuのターミナルでの作業
1. イメージ作成用のファイル入手スクリプトをクローン
   ```
   git clone https://github.com/jetsonhacks/bootFromExternalStorage.git
   ```
1. クローンしたディレクトリに移動し、スクリプトを実行
   ```
   cd bootFromExternalStorage
   get_jetson_files.sh
   install_dependencies.sh
   ```
1. 二つのスクリプト実行後にできる R32.6.1/Linux_for_Tegra ディレクトリで、イメージ作成プログラムを実行
   ```
   sudo BOOTDEV=nvme0n1p1 ./flash.sh --no-flash jetson-agx-xavier-devkit nvme0n1p1
   ```
   'nvme0n1p1'は、Linuxから見たrootファイルシステムがあるデバイスファイル名。
イメージファイルは R32.6.1/Linux_for_Tegra/bootloaderに作成される。ファイル名はsystem.img.raw
   . https://docs.nvidia.com/jetson/archives/l4t-archived/l4t-3261/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide/flashing.html#wwpID0E0QN0HA
のFlashing and Booting the Target Deviceを参照

# NVMEにファイルシステム作成。
Xavierでの作業、emmcでブートし、 nvmeにパーティションテーブルの作成、 パーティションの作成、 フォーマットを行う。

   ```
   sudo parted /dev/nvme0n1 mklabel gpt
   sudo parted /dev/nvme0n1 mkpart APP 0GB 36GB
   sudo mkfs.ext4 /dev/nvme0n1p1
   ```
* 128GB以上にしない。rsyncでエラーが出る。リブート後初期設定のスクリプトで拡張できる。
# NVMEにブートイメージを書き込む。
1. autoマウント機能の停止と、 マウントポイントの作成、マウント
   ```
   sudo systemctl stop udisks2

   sudo mkdir /mnt/src
   sudo mkdir /mnt/dist
   sudo mount system.img.raw /mnt/src
   sudo mount /dev/nvme0n1p1 /mnt/dist
   ```
1. nvme-SSDにbootイメージを書き込む。
   ```
   sudo rsync -axHAWX --numeric-ids --info=progress2 --exclude=/proc /mnt/src/ /mnt/dist
   ```
# cbootでbootメディアの変更
Xavierのmicro USBポート経由でMacからターミナルソフトでアクセス。
|順位| ブートデバイス | c-bootコマンド |
|:-:|:-:|:-:|
|1|microSD   | setvar boot-order sd  |
|2| USB  | setvar boot-order usb  |   
|3|nvme   | setvar boot-order nvme |
|4|内蔵emmc   | setvar boot-order emmc  | 

デバイスを指定後
```
boot
```
この変更は一時的。リブートの毎に設定する。
ブートデバイスごとにhostnameを変えると、ssh接続のknownhostsのバッティングが起こらなくて便利

# Jetpackのインストール
Xavierをnvmeから起動し、'install_jetson_default_packages.sh'を実行

# 最後に
emmcの容量は32GBでbootイメージを保存することができない。また破損の問題もある。
対してUSB-bootは、バージョンアップや、比較などに便利。
nvme-SSDをUSBにバックアップすることができれば、再構築の面倒を避けることができる。
イメージ作成のflash.shのなかで呼びだすプログラムがXavier上で利用できるようになれば、hostレスで環境構築できるようになる。今後のバージョンアップに期待。


# パーティションの拡張手順
parted デバイスファイル
print free
resizepart 2 128GB      
# フォーマットの拡張
resize2fs デバイスファイル
# ボリュームのマウント
元ボリュームのマウント
sudo mount /dev/sdx2 /mnt/src
先ボリュームのマウント
sudo mount /dev/sdy2 /mnt/dist
# コピー
sudo rsync -axHAWX --numeric-ids --info=progress2 --exclude=/proc /mnt/src/ /mnt/dist/
# c-bootのデバイス名とLinuxカーネルのデバイスファイルの関係

| メディア | c-boot | linux |
|:-:|:-:|:-:|
|microSD  | sd  | mmcblk1  |
|nvmeデバイス  | nvme | nvme0n1  |
|USB上のSD  | usb  | sda  |
|内蔵mmc| emmc  | mmcblk0  |

usb上に複数のSDカードスロットがあっても、c-bootからはそれを指定できない。
linuxからはsda,sdb...などusbの位置によって自動的に割り当てられる。

# linuxカーネルに対するブートデバイスの指定方法
ブートデバイスの/boot/extlinux/extlinux.confで指定している。
以下はmicroSDの内容
```
TIMEOUT 30
DEFAULT primary

MENU TITLE L4T boot options

LABEL primary
      MENU LABEL primary kernel
      LINUX /boot/Image
      INITRD /boot/initrd
      APPEND ${cbootargs} quiet root=/dev/mmcblk1p1 rw rootwait rootfstype=ext4 console=ttyTCU0,115200n8 console=tty0 fbcon=map:0 net.ifnames=0 rootfstype=ext4 
```