[メモ] Raspberry Pi 3向けの 64bitカーネルをビルドして、使用する

## `aarch64`

```shell-session
pi@raspberrypi:~ $ uname -a
Linux raspberrypi 4.8.16-v8+ #1 SMP Mon Jan 9 20:57:18 UTC 2017 aarch64 GNU/Linux
pi@raspberrypi:~ $ file ./HelloWorld 
./HelloWorld: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, for GNU/Linux 3.7.0, BuildID[sha1]=cb2cbdf1627b656a29c5acf3edda2dcdf0afbc7b, not stripped
pi@raspberrypi:~ $ ./HelloWorld 
Hello World!
```

## 概要
- 参考: [Build a 64-bit Kernel for your Raspberry Pi 3](https://devsidestory.com/build-a-64-bit-kernel-for-your-raspberry-pi-3/)
- RPi3用の64bitカーネルをクロスビルドして、Raspbian(**<font color='red'>32bit!</font>**)で使用する.
- 利点? 64bit **キブン** を味わえる??


## 環境
- Windows 10
    - Vagrant + VirtualBox<br>=>参考: [[メモ] Windowsで、Virtualbox+Vagrant(ヴェイグラント)環境](http://qiita.com/mt08/items/0ffa4059c112379c0c07)
- Raspberry Pi 3 model B
    - `2016-11-25-raspbian.img`
- 何度もチャレンジしそうな場合は、aptキャッシュサーバを導入しておくと良い、かと。<br>=>[[メモ] aptのキャッシュサーバ(apt-cacher-ng)](http://qiita.com/mt08/items/c8b8187b1000382d77ae)

## 手順
### 64bitカーネルのビルド
1. Vagrantfile

    ```rb:Vagrantfile
	# Vagrantfile
	# 

	VM_MEMORY=1024
	VM_CORES=2

	Vagrant.configure("2") do |config|
		config.vm.box = "ubuntu/xenial64"
		config.vm.network "forwarded_port", guest: 22, host: 22
		# config.vm.network "public_network", bridge: 'Intel(R) Ethernet Connection I217-LM'

		config.vm.provider "virtualbox" do |vb|
			#   vb.gui = true
			vb.name = "Build aarch64 kernel for RPi3"
			vb.memory = VM_MEMORY
			vb.cpus = VM_CORES
		end

		config.vm.provision "shell", inline: <<-SHELL
			echo `cat /proc/uptime | cut -f 1 -d ' '`  apt update
			# # apt cache server 
			# echo 'Acquire::http::Proxy "http://apt-cache-server:3142";' | sudo tee /etc/apt/apt.conf.d/02proxy
			apt-get -q update -q
			echo `cat /proc/uptime | cut -f 1 -d ' '` apt install
			apt-get -q install -q -y bc build-essential gcc-aarch64-linux-gnu git unzip libncurses5-dev 
			apt-get -q -y autoremove -q
			apt-get -q -y clean -q
			cd /home/ubuntu/
			echo `cat /proc/uptime | cut -f 1 -d ' '` Preparing: raspberrypi/linux
			if [ -d linux/kernel ] ; then cd linux ; git pull ; cd .. ; else git clone --depth=1 -b rpi-4.8.y https://github.com/raspberrypi/linux.git ; fi
			chown ubuntu.ubuntu -R linux
			echo `cat /proc/uptime | cut -f 1 -d ' '` Done
		SHELL
	end
```

2. `vagrant up`
3. `vagrant ssh`
4. Build

    ```bash:↓こぴぺ
cd $HOME/linux
#
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcmrpi3_defconfig
time make -j 4 ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu-
#
WORK_DIR=$HOME/work
DEST_DIST=/vagrant
cd $HOME/linux
mkdir -p ${WORK_DIR}/boot
cp arch/arm64/boot/Image ${WORK_DIR}/boot/kernel8.img 
cp arch/arm64/boot/dts/broadcom/bcm2710-rpi-3-b.dtb ${WORK_DIR}/boot/
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu INSTALL_MOD_PATH=${WORK_DIR} modules_install
#
cd ${WORK_DIR}
rm -fv ${DEST_DIST}/RPi_aarch64.tbz
tar jcvf ${DEST_DIST}/RPi_aarch64.tbz *
#
cd ..
rm -rf ${WORK_DIR}
ls -l ${DEST_DIST}/RPi_aarch64.tbz
#
```
=> `RPi_aarch64.tbz`ができる。

### RPi3実機にて
1. Raspbianを焼く
    - **ssh**: bootパーティションに `ssh`というファイルを作成
    - `RPi_aarch64.tbz` をbootパーティションにコピー (42MBくらいフリーで、tbzは17.2MBくらいだから大丈夫かと)
2. Raspbianで、起動.
3. 解凍、コピー、`config.txt`編集

    ```bash:↓コピペ
uname -a ; mkdir work ; cd work ; tar xf /boot/RPi_aarch64.tbz ; sudo cp -rv * / ; echo "kernel=kernel8.img" | sudo tee -a /boot/config.txt ; sync
#
```

4. 再起動<br>`sudo reboot`
   
## その他

### 64bit版 Hello World!実行.

```shell-session:カーネルをビルドしたPCにて
ubuntu@ubuntu-xenial:~$ cat HelloWorld.c
#include <stdio.h>

int main(int ac, char *av[])
{
    printf("Hello World!\n");
    return 0;
}

ubuntu@ubuntu-xenial:~$ # aarch64のgccにてビルド.
ubuntu@ubuntu-xenial:~$ aarch64-linux-gnu-gcc HelloWorld.c -o HelloWorld -static
ubuntu@ubuntu-xenial:~$ # scpにて転送
ubuntu@ubuntu-xenial:~$ scp HelloWorld pi@10.10.6.175:/home/pi
pi@10.10.6.175's password:
HelloWorld                                    100%  605KB 604.9KB/s   00:00
ubuntu@ubuntu-xenial:~$
```

```shell-session:RPi3にて.
pi@raspberrypi:~ $ file ./HelloWorld 
./HelloWorld: ELF 64-bit LSB executable, ARM aarch64, version 1 (SYSV), statically linked, for GNU/Linux 3.7.0, BuildID[sha1]=cb2cbdf1627b656a29c5acf3edda2dcdf0afbc7b, not stripped
pi@raspberrypi:~ $ ./HelloWorld 
Hello World!
```