Xavier NXのアップデート＋NVMEを初期化なしでダイレクトブート

#はじめに
JETPACKの4．6がリリースされました。これにともなって、
[Jetson Xavier NXでNVMe SSD ドライブから起動する方法 (※JetPack4.6)](https://qiita.com/kitazaki/items/da5fb46c03781eb7b406)
にあるように、ブートローダがついに更新されNVMEからのダイレクトブートができるようになりました。
ここではrootOnNVMeをつかって既に/にNVMeがマウンとされている環境をダイレクトブートに変更する方法を記載しています。
あんまり需要がないかもしれないですが。一応

~~# 31st August update.~~
~~とりあえずこのPostは忘れてください。SDカードぬくとbootしない。。。時間があるときに修正します。~~
# 31st August 2nd update.
とりあえずBOOTできるようになりましたのでアップデートします。でも手間を考えると、バックアップして再度NVMEをリイメージした方がはやいかも



#モチベーション
rootOnNVMeをつかっていると、ブートシーケンスの途中でchrootを行う都合上
[Jetson Xavier NX でルートファイルシステムを NVMe SSD ドライブへ変更した際の注意点](https://qiita.com/kitazaki/items/057d91d18690cda29bcc)
にあるように、/boot , /lib/modules内に更新が出る度に、aptでのアップデート後にNVMeとSDカードの間でSYNCを行う必要がありました。
これがどうにも面倒くさくてトラブルの元なのでダイレクトにNVMeからのブートに切り替えます。

#手順の概要
- JETPACKの4．6へのアップデート
- BOOTローダのアップデートのためのリブート
- ~~- NVMeからのブート設定~~
- extlinux.conの書き換え
- SDカードのリイメージ
- SDカードからリブート
- gpartedのインストール
- 既存パーティションのRESIZE+MOVE
- SDカードと同様のパーティションの作成
- SDカードからイメージをコピー
- 確認
- 最後に

#JETPACKの4．6へのアップデート
ここは普通に
[NVIDIA JetPackとL4Tのアップグレード方法 (OTA)](https://qiita.com/ntrlmt/items/5faf16d73102feeb5856)
にあるとおりです。
とりあえず書くと
これが必要かは微妙ですが、
sudo apt update
sudo apt upgrade
sudo rsync -av /boot/ /media/{loginユーザ名}/{SDカードのUUID}/boot/
sudo rsync -av /lib/modules/ /media/{loginユーザ名}/{SDカードのUUID}/lib/modules/
してリブートしてバージョンアップ前に最新にしておきます。
そして本番
sudo vi /etc/apt/sources.list.d/nvidia-l4t-apt-source.list
して
r32.xになっている2カ所を ｒ32.6に書き換えます。

``` nvidia-l4t-apt-source.list
deb https://repo.download.nvidia.com/jetson/common r32.6 main
deb https://repo.download.nvidia.com/jetson/t194 r32.6 main
```
で、
sudo apt update
sudo apt dist-upgrade
します。
upgradeじゃなくて、dist-upgradeなので注意を。。。間違うと CUDNNのアップデートのどこかでエラーになって、dpkgで--force-allするはめになります。

# ブートローダアップデートのためのリブート

dist-upgradeが終わると、以下のダイアログが表示されます。
![PostInstallNotification](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119262/4969fd61-1b35-deb1-468d-37913f9475fd.png "PostInstall notification")
ブートローダは、リブート時に書き換わりますので、SSDからもう一度リブートする必要があります。（と思います。）

その前に
sudo apt install nvidia-jetpack
してJetpack自身も入れておきます。

リブートするので、
SDカード　もしくは、AGXだったら、ブートVolumeをマウントしておいて、
sudo rsync -av /boot/ /media/{loginユーザ名}/{SDカードのUUID}/boot/
sudo rsync -av /lib/modules/ /media/{loginユーザ名}/{SDカードのUUID}/lib/modules/
もやっておきます。
ここでリブートすることで、ブートローダが書き換わり、Jetpackが4．6．1になって起動してきます。

# extlinux.confの書き換え

rootOnNVMEつかっていると、
rootが
root=/dev/mmcblk0p1
になっているとおもうので、以下のように書き換えておきます。

xavier NXだと、そのまま/boot/extlinux/extlinux.conf
AGXだと、引き続きKernelよむとこまではeMMCから行くので eMMCをマウントしたあと
/media/{loginユーザ名}/{SDカードのUUID}/boot/extlinux/extlinux.conf
を編修する必要があります。

```
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/nvme0n1p1 rw rootwait rootfstype=ext4 console=ttyTCU0,115200n8 console=tty0 fbcon=map:0 net.ifnames=0 rootfstype=ext4

```
/bootをrsyncしちゃったので、XavierAGXが実際にどう動いているか微妙なんですが、AGXだと、SDカードとちがって、eMMCはずっとあるので、ここまでやったらおしまいで大丈夫なのを期待してます。
次のバージョンアップで、/bootをrsyncしないでどうなるかで分かりますね。。。

以降はXavierNX用ということで

# ~~NVMeからのブートに書き戻し~~
~~rootOnNVMeを使っているとインストールスクリプトが勝手にインストールを行いますが、~~
~~rootOnNVMe内のsetup-service.sh を見ると~~
~~/etc/setssdroot.conf~~
~~を消すことで起動時のchrootをdisableできることが分かります。~~
~~まあ、なにかの時にまたchrootしたくなるかもしれないので、serviceそのものはとっておいて、/etc/setssdroot.confを消すことにします。~~
~~SDカード　もしくは、AGXだったら、ブートVolumeをマウンとしておいて、~~
~~sudo rm /media/{loginユーザ名}/{SDカードのUUID}/etc/setssdroot.conf~~
~~次に　SDカード上のextlinux.confを書き換えます。~~
~~SDカードなしでのブートは試してないので、私のとこだとこの設定でブートが切り替わってるはずです。~~
~~sudo vi /media/{loginユーザ名}/{SDカードのUUID}/boot/extlinux/extlinux.conf~~
~~して、root=の記載をmmcblkからnvme0n1p1に書き換えます~~

~~SDカードなしでのブートには~~
~~sudo vi /boot/extlinux/extlinux.conf~~
~~も同様に変更しておけばいいはずです。　＃やってみてないですが。。~~
上記はこのあとSDカード消しちゃうのでいらないです。
AGXもrootがNVMeからになってるので、やらなくて大丈夫なはず。。

# 31st August 追記 - XavierNXでSDカードなしでブート
ここまででextlinux.confだけ書き換えればブートローダがEXT4読み込んでくれると思ったんですが、そんなに賢くないんですね。SDカード抜いたらブートしませんでした。
SDカードをリイメージしてPARTIONを見ると
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119262/9d3e4023-e7c9-7aa6-2fb3-897758c3a10f.png)
とかパーティションが11個もあって、これらのパーティションをつかってブートするようなので、ここからの手順でNVMe上に同一のパーティションをコピーして強引に立ち上がるようにします。

# SDカードのリイメージ
rootOnNVMEをつかっていると、SDカードは/boot と、/lib/modulesのみが最新で、他の部分はNVMe内から読み込んでいるため、すでにそのままではNVMeなしではGUIまでブートできないSDカードになっているかとおもいます。
一方で、NVMeのパーティションテーブルを書き換えないことには、上にあるAPP以外のパーティションがつくれないので、NVMeをマウントせずにパーティションテーブルを書き換える必要があります。
そこで現在のSDカードは、どうせもう使わないので、全てJETPACK4．6のイメージでリイメージします。
SDカードは
[JetPack SDK | NVIDIA Developer](https://developer.nvidia.com/embedded/jetpack)
からダウンロードしてリイメージします。
もともとNVMeを'/'にマウントしているので、中身はどうせいらないので。。

# SDカードからブート
リイメージしたSDカードをXavierにさしてブートします。
新規なので、当然ユーザ設定、ネットワーク設定などが必要ですが、特に気にせずバンバンすすみます。

# gpartedのインストール
パーティションテーブルを書き換えるときに既存データを含め保持したままパーティションテーブルを書き換える必要があるので、私はgpartedを使いました。
sudo apt -y install gparted
でインストールします。

# 既存パーティションのRESIZE+MOVE
sudo gparted　でgparted を起動したら、右上のデバイス設定で NVMeを選択します。
rootOnNVMEをつかっていると通常は1パーティションがディスクいっぱいをつかっているかとおもいます。
gpartedから、パーティションを選択し、Resizeを選択します。
BOOT用の細かいパーティションはシリンダ番号含め同一としたいので、パーティションをシュリンクして開始シリンダ番号を870400以降にします。（870400はリイメージしたSDカードのAPPパーティションの開始シリンダ番号）
残念ながら、gpartedが単位としてMiBしか受け付けないので、ぴったりあわせられるかどうか分かりませんが、リサイズから
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119262/02f05a55-7c73-8b71-01aa-e507b138f560.png)
などとやって、Free space precedingに870400 シリンダ以上の空きができるようにします。
緑のチェックをおして実行するのを忘れないように。。。恐い人はバックアップしといてください。
基本的には870400*512/1024/1024 でMiBになりますが、丸められて微妙にあわないかも。。。
たぶん425MiBか、426です。私は間違えてやりなおしたので、やってみた下さい。足りなくなると10分以上リサイズに時間がかかるので、ちょっと多めがいいかも。。
終わると、以下のように空きパーティションが前にできます。（ここでは301MiBになってますが、425MiBになるべきです、スクリーンショットは私が間違えたときの奴）
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119262/aad50707-3887-8cb3-ce69-b7f00670be2e.png)

# SDカードと同様のパーティションの作成
gpartedだと、シリンダ単位でパーティションがつくれなかったので、gdisk をつかいました
sudo gdisk /dev/nvme0n1
としてgdisk を起動し、パーティショをつくっていきます。
nコマンド入力
パーティション番号を2 から　　ー　1はすでにAPPとして存在しているのでデフォルトで2になってるはずです
First sectorにSDカードのStart sector
End sector にSDカードのEND sector
HEX code に　8300　（もしくはただリターン）
としてSDカード上に同一Startセクタ、Endセクタで、10個パーティションを追加します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119262/9193897b-d3dd-8745-20a8-d6d7c0f979c9.png)
こんな感じ
次に名前はあんまりきにしないとおもうんですが、一応

cコマンド入力
パーティション番号を指定
名前を指定して、
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/119262/ae766321-bb8d-9ed5-ad23-861e391054f7.png)
こんな感じ

最後wコマンドでパーティションテーブルを書きこんで終了

# SDカードからイメージをコピー
以下のコマンド（SUDOがいります）でSDカードのパーティション2から11までをコピーします。
くれぐれも、パーティション1はいじらないように。。。当然ですが　2からです。
bsは気分です。

```
dd if=/dev/mmcblk0p2 of=/dev/nvme0n1p2 bs=8192
dd if=/dev/mmcblk0p3 of=/dev/nvme0n1p3 bs=8192
dd if=/dev/mmcblk0p4 of=/dev/nvme0n1p4 bs=8192
dd if=/dev/mmcblk0p5 of=/dev/nvme0n1p5 bs=8192
dd if=/dev/mmcblk0p6 of=/dev/nvme0n1p6 bs=8192
dd if=/dev/mmcblk0p7 of=/dev/nvme0n1p7 bs=8192
dd if=/dev/mmcblk0p8 of=/dev/nvme0n1p8 bs=8192
dd if=/dev/mmcblk0p9 of=/dev/nvme0n1p9 bs=8192
dd if=/dev/mmcblk0p10 of=/dev/nvme0n1p10 bs=8192
dd if=/dev/mmcblk0p11 of=/dev/nvme0n1p11 bs=8192
```



# 確認
~~dmesg | grep Kernel ~~
~~＃ Kが大文字です~~
~~すると~~
~~となって、nvme0n1p1からダイレクトに起動しているのが確認できます。~~
SDカードぬいて起動してみてください。私のところではこれで起動しました。

#最後に
~~そもそもrootOnNVMeとか覚えてれば難しいことないとおもいますが、すでに1年以上前の話なのでとりあえず書いてみました。~~
~~これで、apt upgradeするたびにrsyncの呪縛から逃れることができてとてもHappyです。~~
先にQiitaに書き込んでなければ、絶対 NVMeをリイメージしてました。
書いちゃった以上、最後までやらないときがすまなかった。。。この方法だと大分面倒くさいし、パーティションのリサイズ＋MOVEとかやって結構危険なので、正直、バックアップしてリイメージした方がはやいです。