NanoPi-NEO2 で nfs boot

# 概要

NanoPi-NEO2をnfsブートさせます。
1GbpsのLAN あるんだから、もったいない。

u-bootのNetworkが無効になっているので、それを有効化させるところから始めます。
今回 @__tkz__さんと結託・協力頂きました。ありがとうございますm(_ _)m

## 必要なもの

- NanoPi-NEO2
- UART-USBのモジュール
- HostPC (Ubuntu16.04のVMかPCか) ビルドに使います
- ServerPC (TFTP,NFSサーバ用のPCかNAS)

# 手順

各種設定のファイルパス等の辻褄合わせは適宜お願いしますm(_ _)m

## TFTPサーバ、NFSサーバの準備

各自セットアップしてください。
こちらでは、SynologyのNASをTFTP､NFSサーバとして実施しています。

/volume1/NanoPi-NEO2/20181208/ にrootfsを置いて
/volume1/NanoPi-NEO2/20181208/boot に bootを置く感じで構成します。

TFTPのルートは、/volume1/NanoPi-NEO2 に設定します。

## rootfsの準備

HostPCで作業します。
OfficialRomImageを吸い上げてそれを使います。
パーティションが２つあるのでboot/rootfsそれぞれを指定しマウントする必要があります。

```console:HostPC
sudo su

fdisk -l -u nanopi-neo2_FriendlyCore-Xenial_4.14.0_20171208.img 
-----
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: dos
Disk identifier: 0x00000000

Device                                                    Boot  Start     End Sectors  Size Id Type
nanopi-neo2_FriendlyCore-Xenial_4.14.0_20171208.img1            49152  253951  204800  100M 83 Linux
nanopi-neo2_FriendlyCore-Xenial_4.14.0_20171208.img2           253952 7617185 7363234  3.5G 83 Linux
-----
mkdir rootfs
mkdir boot
mount -o loop,offset=25165824 nanopi-neo2_FriendlyCore-Xenial_4.14.0_20171208.img ./boot
mount -t ext4 -o loop,offset=130023424 nanopi-neo2_FriendlyCore-Xenial_4.14.0_20171208.img  ./rootfs

cd rootfs
tar -zcvf ../20171208.tar.gz .
cd ..
tar -zcvf 20171208_boot.tar.gz boot
```
※mountのoffset=25165824 や 130023424は、SectorSize*Start で計算した結果を入れる。

出来たファイルを ServerPCの /volume1/NanoPi-NEO2 へコピーしておきます。
そして、ファイルを展開します。

```console:ServerPC
sudo su

cd /volume1/NanoPi-NEO2

mkdir 20171208
cd 20171208
sudo tar -zxvf ../20171208.tar.gz 
sudo tar -zxvf ../20171208_boot.tar.gz 

chmod 777 boot -r
```



## u-boot のコンパイルとBootSD作成

http://wiki.friendlyarm.com/wiki/index.php/Mainline_U-boot_and_Linux

の

export PATH=/opt/FriendlyARM/toolchain/gcc-linaro-6.3.1-2017.02-x86_64_aarch64-linux-gnu/bin:$PATH
export GCC_COLORS=auto
. ~/.bashrc

まで終わっている前提です。
SDカードは、/dev/sdb を前提にしています。

```console:HostPC
git clone https://github.com/friendlyarm/u-boot.git
cd u-boot
git checkout sunxi-v2017.x
nano arch/arm/dts/sun50i-h5-nanopi-neo2.dts
-----
↓ 末尾に追加

&emac {
        pinctrl-names = "default";
        pinctrl-0 = <&emac_rgmii_pins>;
        status = "okay";
        phy = <&phy1>;
        phy-mode = "rgmii";
        phy1: ethernet-phy@1 {
                reg = <0>;
        };
};

-----
make nanopi_h5_defconfig CROSS_COMPILE=aarch64-linux-gnu-
make CROSS_COMPILE=aarch64-linux-gnu-

# dd if=/dev/zero of=/dev/sdb bs=1M count=8 ※必要に応じ実施
dd if=spl/sunxi-spl.bin of=/dev/sdb bs=1024 seek=8
dd if=u-boot.itb of=/dev/sdb bs=1024 seek=40
```

## u-bootの設定

UART繋いだ状態で NanoPi-NEO2起動して u-bootで止めます。

```console:NanoPi-NEO2
setenv ipaddr 192.168.1.101
setenv serverip 192.168.1.9
setenv gatewayip 192.168.1.1
setenv dnsip 192.168.1.1
setenv netmask 255.255.255.0

setenv image_path 20171208
setenv rootpath /volume1/NanoPi-NEO2/${image_path}

setenv fsck.repair yes
setenv ramdisk rootfs.cpio.gz
setenv kernel Image
setenv env_addr 0x45000000
setenv kernel_addr 0x46000000
setenv ramdisk_addr 0x47000000
setenv dtb_addr 0x48000000
setenv fbcon map:0

setenv bootargs_nfs "console=ttyS0,115200 earlyprintk ip=${ipaddr}:${serverip}:${gatewayip}:${netmask} root=/dev/nfs rw nfsroot=${serverip}:${rootpath} rootwait fsck.repair=${fsck.repair} panic=10 ${extra} fbcon=${fbcon}"

setenv bootcmd_tftp "setenv bootargs ${bootargs_nfs};ping ${serverip}; tftp ${kernel_addr} ${image_path}/boot/${kernel};tftp ${ramdisk_addr} ${image_path}/boot/${ramdisk};tftp ${dtb_addr} ${image_path}/boot/sun50i-h5-${board}.dtb;fdt addr ${dtb_addr};fdt set ethernet0 local-mac-address ${mac_node};booti ${kernel_addr} ${ramdisk_addr}:500000 ${dtb_addr};"

setenv bootcmd 'run bootcmd_tftp;run distro_bootcmd'
saveenv
reset
```

※１
 起動すると、mmcblk0p1が無いぞ？と怒られますので、
 nano /etc/fstab で、mmcblk0p1の mountを削除します。
 そうすると、boot の部分がnfsサーバー内の物が使用されます。

※２
 そのうち、nanopi-neo2-v1.1 が出るかもしれませんが、その場合、別途対応が必要になると思います。

※３
 u-boot内での初回ネットワーク接続が高確率で失敗するため、pingを撃つようにしています。

# 結果

```console:NanoPi-NEO2
root@NanoPi-NEO2:~# df
Filesystem                                 1K-blocks       Used  Available Use% Mounted on
udev                                          235976          0     235976   0% /dev
tmpfs                                          49392       2032      47360   5% /run
192.168.1.9:/volume1/NanoPi-NEO2/20171208 5804826496 2731295360 3073412352  48% /
tmpfs                                         246952          0     246952   0% /dev/shm
tmpfs                                           5120          4       5116   1% /run/lock
tmpfs                                         246952          0     246952   0% /sys/fs/cgroup
tmpfs                                          49392          0      49392   0% /run/user/0

root@NanoPi-NEO2:~# dd if=/dev/zero of=write_bench bs=1M count=1024
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 16.9389 s, 63.4 MB/s

root@NanoPi-NEO2:~# dd if=write_bench of=/dev/null bs=1M
1024+0 records in
1024+0 records out
1073741824 bytes (1.1 GB, 1.0 GiB) copied, 19.3773 s, 55.4 MB/s
```

MicroSDとは比較にならない ディスク容量と、FileI/O性能を手に入れた!

## 既知の問題点

### 外部からNanoPi-NEO2に対し、sshが繋げられない。

journalctl | grep sshd
パーミッション緩すぎエラー出てくるので、アクセス権を狭めて上げればOKだった。

chmod 600 /etc/ssh/ssh_host_rsa_key
chmod 600 /etc/ssh/ssh_host_dsa_key
chmod 600 /etc/ssh/ssh_host_ecdsa_key
chmod 600 /etc/ssh/ssh_host_ed25519_key