Raspbianのカーネルを64bitにする

# カーネルのみを差し替える

カーネルのみなので他はそのまま32bitです。
64bitカーネルの機能を使いたい、64bitバイナリを実行したいとき用です。
対応機種はもちろんRaspberry Pi 3以降のみです。

# クロスコンパイル

64bitカーネルを用意するのにカーネルをソースコードからビルドするので、そのためのLinuxマシンが必要になります。
（WindowsやMacでもビルドできるかもしれないけど、面倒なので確認してない）
僕はx86_64のFedora28を使いました。

# 64bitカーネルの用意

[Kernel Building - Raspberry Pi Documentation](https://www.raspberrypi.org/documentation/linux/kernel/building.md)
基本的にはここに従いますが、これは32bitカーネルのビルド方法なので少々変えます。

## 必要なパッケージのインストール

まず、公式ドキュメントの通りに必要なものを入れましょう

```sh
sudo yum install git bc
```

また、クロスコンパイル用にaarch64のバイナリを吐くgccが必要です。Fedoraでは

```sh
sudo yum install gcc-aarch64-linux-gnu
```

でいけました。パッケージマネージャーでaarch64を検索して出てきたgcc入れればいいかと。


## カーネルの取得

公式ドキュメントの通りです。クローンが終わったら出来たディレクトリ内に移動しましょう。

```sh
git clone --depth=1 https://github.com/raspberrypi/linux
cd linux
```

## カーネルのconfig

arm64のconfigsにbcmrpi3_defconfigがあるので、こいつを使います

```sh
KERNEL=kernel7
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcmrpi3_defconfig
```

## カーネルのビルド

あとはビルドしてカーネルイメージ、モジュール、デバイスツリーのバイナリファイルを生成します
公式ドキュメントでは、カーネルイメージを生成するのはzImageですが、
`make ARCHH=arm64 help`で見るとarm64ではImageであることがわかります。なので、ビルドするコマンドは

```sh
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- Image modules dtbs -j4
```

になります
-j4はビルドするパソコンのコア数で適宜変えてください。

# カーネルのインストール

ビルドして出来たカーネルをインストールします。
ここでは、Raspberry Pi公式からダウンロードできるRaspbianのディスクイメージを直接書き換え、それをSDカードに書き込んでいます。
（僕の場合Linuxマシンは基本的に遠隔操作で使っていて、直接SDをマウント出来ないから）
直接Raspbianの入ったSDにインストールすることもできるので、その時はディスクイメージのマウント・ファイル操作は適宜SDの操作に読み替えてください。
ただし、失敗する可能性も大きいので、使ってないSDとかで試してください。
（何が起きても一切の責任は負えません）

## ディスクイメージの用意

[Download Raspbian for Raspberry Pi](https://www.raspberrypi.org/downloads/raspbian/)

ここから普通にダウンロードします。
で、そのまま解凍。
この記事で使ってるのは、バージョンがJune 2018のイメージだから、イメージのファイル名は
"2018-06-27-raspbian-stretch.img"
になってる。
バージョン違っても多分できると思う。
バージョン違った時のファイル名とかは適宜読み替えとくれ。

## ディスクイメージのマウント

Raspberry Piのディスクイメージには2つパーティションがある。両方をいじくるのでどちらともマウントしなきゃいけない。
今回は参考にあるサイトの通りにして、ループデバイスでパーティションを扱えるようにしてマウントした。

"/etc/modprobe.d/loop.conf"に
```options loop max_part=63 max_loop=8```
を追加して、

```sh
sudo rmmod loop
sudo modprobe loop
```
でloopモジュールを再読み込みしてやればOK
あとは、

```sh
sudo losetup /dev/loop0 (Raspbianイメージのあるディレクトリ)/2018-06-27-raspbian-stretch.img
mkdir mnt
mkdir mnt/fat32
sudo mount -t vfat /dev/loop0p1 mnt/fat32/
mkdir mnt/ext4
sudo mount -t ext4 /dev/loop0p2 mnt/ext4/
```
でマウント。

もちろんfdiskでオフセット調べてマウントでもいい。
ただ、その場合両方のパーティションを同時にマウントできないのでコマンドの順番は変わる。
（別に両方同時にマウントしなきゃいけない訳ではない）

## モジュールのインストール

公式ドキュメントとほとんど変わらず。64bitになってるだけ

```sh
sudo make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- INSTALL_MOD_PATH=mnt/ext4 modules_install
```

## カーネルとデバイスツリーのコピー

公式ドキュメントとはパスとかファイル名がちょっと違ってるだけ。

```sh
sudo cp arch/arm64/boot/Image mnt/fat32/
sudo cp arch/arm64/boot/dts/broadcom/*.dtb mnt/fat32/
sudo cp arch/arm64/boot/dts/overlays/*.dtb* mnt/fat32/overlays/
```

## ブートローダー設定の変更

fat32の中にあるconfig.txtがブートローダーの設定ファイルになります。
このままでは新しいカーネルイメージを読み込んでくれないのでここで設定してやります。

```sh
sudo vi mnt/fat32/config.txt
```
で開いて末尾に

```
kernel=Image
arm_control=0x200
```
を追加して保存して終了。
ちなみにここではviだが、sudoで実行できればテキストエディタは何でもOK。

## ディスクイメージのアンマウント

```sh
sudo umount mnt/*
sudo losetup -d /dev/loop0
```

# SDに書き込んで起動

あとは公式のインストールガイドに従ってディスクイメージをSDに書き込み、Raspberry Piで起動するだけです。
起動ができたら"uname -a"で確認してみましょう。

![SS.png](https://qiita-image-store.s3.amazonaws.com/0/242402/b2aa37ac-2e29-0f9b-8f49-cb62ba268514.png)

輝くaarch64の文字が見えれば成功です。

よきラズパイライフを

# 参考

[[メモ] Raspberry Pi 3向けの 64bitカーネルをビルドして、使用する](https://qiita.com/mt08/items/ebf5fcef4aebe03ca210)
[パーティションを含むディスクイメージをloopデバイスにマウントする。](http://takuya-1st.hatenablog.jp/entry/2016/07/15/135326)