Jetson AGX Xavierへkernel module(nls_utf8.ko)をインストール

# Jetson AGX Xavierにない！

Xavier君は、32Gの不揮発メモリしか積んでいないので、単体で弄り倒すのは、かなり難しい。
そこで、sambaで稼働しているネットワークファイルをマウントすべく、mount.cifsを使おうと頑張った。結果として、このトピックに転がりました。

~~必要なのは、nls_utf8.ko。このコをビルドして、展開するのが今回の記録です。
トライアンドエラーで進めたので、途中ディレクトリ名称が一致しないのはご愛嬌デス。気にしないように。~~当方の場合、嘘情報でした。結局、network-managerをやめて、netplanへ差し替えれば、良かった模様。


# ビルド手順

まず、環境を整えます。[本家](https://docs.nvidia.com/jetson/l4t/index.html)に手順が示されているので、従います。

##ソースコードのダウンロードと展開
今回は、ubuntu18.04の環境がなかったので、[Manually Downloading and Expanding Kernel Sources](https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide/kernel_custom.html#wwpID0E0CE0HA)で、ソースコードを用意します。(執筆時点では、versionチェックがあって、20.04ではsdkmanagerが実行できなかった)

本家の手順は不親切で、[ソースコードのリンク](https://developer.nvidia.com/embedded/l4t/r32_release_v6.1/sources/t186/public_sources.tbz2)がないので、ここに展開します。執筆時点では、32.6.1になります。上から、リンクをたどります。せっかちな人は、下3つのリンクで大丈夫です。(順序を記録したのは、自分の備忘録です)
- [Jetson Download Center](https://developer.nvidia.com/embedded/downloads)
- [Jetson Linux R32.6.1 Release Page](https://developer.nvidia.com/embedded/linux-tegra-r3261)
- [L4T Driver Package (BSP)](https://developer.nvidia.com/embedded/l4t/r32_release_v6.1/t186/jetson_linux_r32.6.1_aarch64.tbz2)
- [Sample Root Filesystem](https://developer.nvidia.com/embedded/l4t/r32_release_v6.1/t186/tegra_linux_sample-root-filesystem_r32.6.1_aarch64.tbz2)
- [L4T Driver Package (BSP) Sources](https://developer.nvidia.com/embedded/l4t/r32_release_v6.1/sources/t186/public_sources.tbz2)

ダウンロード後、本家の手順に従い、展開します。
基本、Linux_for_Tegraの下に展開されるように構成されています。

```
$ apt-get install qemu-user-static build-essential bc libncurses5-dev
$ tar xjfv jetson_linux_r32.6.1_aarch64.tbz2
$ cd Linux_for_Tegra/rootfs
$ sudo tar xvjf tegra_linux_sample-root-filesystem_r32.6.1_aarch64.tbz2
$ cd Linux_for_Tegra
$ sudo ./apply_binaries.sh
$ cd ..
$ tar -xjf public_sources.tbz2
$ cd Linux_for_Tegra/source/public
$ tar -xjf kernel_src.tbz2
```
すると、kernelというディレクトリが現れます。

##お試しビルド
(飛ばしてもいいと思う)
初回は、ビルド環境の確認を兼ねて、手順通りビルドしました。

###toolchainのインストール
本家おすすめの通り、クロスコンパイル環境を整えます。

```
$ wget http://releases.linaro.org/components/toolchain/binaries/7.3-2018.05/aarch64-linux-gnu/gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu.tar.xz
$ tar xf gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu.tar.xz
$ ln -s gcc-linaro-7.3.1-2018.05-x86_64_aarch64-linux-gnu l4t-gcc
```


###環境変数の設定


```
$ export TEGRA_KERNEL_OUT=/home/ubuntu/xavier/build
$ export CROSS_COMPILE=/home/ubuntu/bin/l4t-gcc/bin/aarch64-linux-gnu-
$ export LOCALVERSION=-tegra
$ export KERNEL_SOURCE=/home/ubuntu/xavier/Linux_for_Tegra/source/public/kernel/kernel-4.9
$ export RELEASE_PACKAGEP=/home/ubuntu/xavier
$ export TOP=/home/ubuntu/xavier
$ export MODULES_INSTALL_PATH=/home/ubuntu/xavier/Linux_for_Tegra/rootfs
```


\<outdir\>は、ビルドディレクトリを指定します。どこでも良い。
\<cross_prefix\>は、toolchainのディレクトリを指定します。
そのほか、 [本家](https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide/kernel_custom.html#) に登場する摩訶不思議な参照を解読したものを登録しました。



### .config作成
本家の手順に従います。

```
$ cd Linux_for_Tegra/source/public/kernel/kernel-4.9 (ダウンロードしたあと、public_source.tgz2を展開したディレクトリ)
$ mkdir -p $TEGRA_KERNEL_OUT
$ make ARCH=arm64 O=$TEGRA_KERNEL_OUT tegra_defconfig
```

###ビルド

```
$ make ARCH=arm64 O=$TEGRA_KERNEL_OUT
```

エラーが出なければ、環境設定はOKでしょう。本番ビルドにいきます。


##本番ビルド

###前回のビルドの痕跡を消して、初期化
本家には書いてないですが、やったほうがよいので、記載します。うまく行かないときは、試してみて。

```
$ make mrproper
$ make ARCH=arm64 O=$TEGRA_KERNEL_OUT tegra_defconfig
```

###.configの改修
nls_utf8を設定します。

修正するのは、$TEGRA_KERNEL_OUTにある.configです。

```
$ cd $TEGRA_KERNEL_OUT
$ vi .config
```

とりあえず、以下のように書き換えました。

```
CONFIG_NLS_CODEPAGE_932=m
CONFIG_NLS_UTF8=m
```

CODEPAGE_932: こちらは、MSDOSのコードページなので、採用
NLS_UTF8: こちらは、本命なので、採用


###ビルドと確認

```
$ make ARCH=arm64 O=$TEGRA_KERNEL_OUT
(snip)
$ ls -1 $TEGRA_KERNEL_OUT/fs/*/*.ko
/home/ubuntu/Linux_for_Tegra/kernel/fs/btrfs/btrfs.ko
/home/ubuntu/Linux_for_Tegra/kernel/fs/cifs/cifs.ko
/home/ubuntu/Linux_for_Tegra/kernel/fs/fuse/cuse.ko
/home/ubuntu/Linux_for_Tegra/kernel/fs/fuse/fuse.ko
/home/ubuntu/Linux_for_Tegra/kernel/fs/nfs_common/nfs_acl.ko
/home/ubuntu/Linux_for_Tegra/kernel/fs/nfsd/nfsd.ko
/home/ubuntu/Linux_for_Tegra/kernel/fs/nls/nls_cp932.ko
/home/ubuntu/Linux_for_Tegra/kernel/fs/nls/nls_euc-jp.ko
/home/ubuntu/Linux_for_Tegra/kernel/fs/nls/nls_iso8859-1.ko
/home/ubuntu/Linux_for_Tegra/kernel/fs/nls/nls_utf8.ko
/home/ubuntu/Linux_for_Tegra/kernel/fs/overlayfs/overlay.ko
```

nls_utf8.koが完成していることが、確認できます。

###パッキング
パックしていきます。本家の手順のままです。

```
$ cp -r $TEGRA_KERNEL_OUT/arch/arm64/boot/Image* $RELEASE_PACKAGEP/Linux_for_Tegra/kernel/
$ cp -r $TEGRA_KERNEL_OUT/arch/arm64/boot/dts/* $RELEASE_PACKAGEP/Linux_for_Tegra/kernel/dtb/.
$ cd $KERNEL_SOURCE
$ sudo make ARCH=arm64 O=$TEGRA_KERNEL_OUT modules_install INSTALL_MOD_PATH=$RELEASE_PACKAGEP/Linux_for_Tegra/rootfs/
$ cd $MODULES_INSTALL_PATH
$ sudo tar --owner root --group root -cvjf kernel_supplements.tbz2 lib/modules
$ sudo mv kernel_supplements.tbz2 ../kernel/
```

###本体へ焼き付け
ここで、本体へ焼き付けます。

先に、本体をUSBモードで起動します。(真ん中を押しながら電源ON)
なお、内臓eMMCを利用する場合は、mmcblk0p1ですが、後載せ内蔵NVMeを利用する場合は、nvme0n1p1となります。

```
$ cd Linux_for_Tegra
$ sudo ./flash.sh jetson-xavier mmcblk0p1
(snip)
[ 287.3643 ] Flashing completed

[ 287.3644 ] Coldbooting the device
[ 287.3673 ] tegrarcm_v2 --ismb2
[ 287.6099 ] 
[ 287.6125 ] tegradevflash_v2 --reboot coldboot
[ 287.6139 ] Bootloader version 01.00.0000
[ 287.7476 ] 
*** The target t186ref has been flashed successfully. ***
Reset the board to boot from internal eMMC.
```

nvmcへ焼き付けるためには、外からrsyncで書き込まなければいけないらしいです。
[本家のコピー](https://docs.nvidia.com/jetson/l4t/index.html#page/Tegra%20Linux%20Driver%20Package%20Development%20Guide/flashing.html#wwpID0E0QN0HA)

いちいちJestson XavierからNVMeを外してられないので、xavier上でやってます。
- system.img.rawをどこかにマウント
- nvme0n1p1をどこかへマウント

```
$ cd Linux_for_Tegra/
$ sudo BOOTDEV=nvme0n1p1 ./flash.sh --no-flash jetson-xavier nvme0n1p1
$ sudo mkdir tmp_system
$ sudo mount system.img.raw ./tmp_system
$ sudo rsync -axHAWX --numeric-ids --info=progress2 --exclude=/proc ./tmp_system/ /mnt
```

# Jetson AGX Xavierにある！
指示どおり、ボードをリスタートすると、すっかり初期化されたxavier君に出会います。
ポチポチと、ライセンスの承認など設定をして、ターミナル画面を出します。

```
$ sudo modprobe nls_utf8
$ lsmod
Module                  Size  Used by
nls_utf8                2058  0
(snip)
```

modprobeで組み込めることが確認できました。これで動きます。この方法でも確認できます。大したサイズでもないので、モジュール("m")ではなくて、"y"でも良かったかも。

```
$ zcat /proc/config.gz | grep -e ^CONFIG_NLS
CONFIG_NLS=y
CONFIG_NLS_DEFAULT="iso8859-1"
CONFIG_NLS_CODEPAGE_437=y
CONFIG_NLS_CODEPAGE_932=m
CONFIG_NLS_ISO8859_1=y
CONFIG_NLS_UTF8=m
```

とりあえず、今日はここまで！

意味なく終〜了〜