Raspberry PiのLinux カーネルビルド - Ubuntuで64bit版をクロスコンパイル編

さて次はRaspberry Piカーネルのビルドだ。
基本的なステップは

Raspberry Piは生態系がよく整備されているので、全てのことはこちらに書かれている。
www.raspberrypi.com
ツールやビルドの方法も年々変わっているようなので、常に最新の記事を参照するとよい。
ちなみに筆者がこれをやったのは2023年の8月だ。

ビルド環境の作成

カーネルのビルドはRaspberry Pi本体でも可能だ。
しかしべらぼうに時間がかかる。
X64なLinuxを使ってクロスコンパイルした方が断然早い、それでも(環境によるが)1時間ほどはかかる。
今回はたまたま空いていたSurface Pro 7+上にUbuntuをインストールして、そいつをクロスコンパイル環境にすることにした。
Ubuntuのターミナル上で必要なビルドツールをインストールする

sudo apt install git bc bison flex libssl-dev make libc6-dev libncurses5-dev

これにARM 32bitのクロスコンパイル環境なら

sudo apt install crossbuild-essential-armhf

ARM 64bitのクロスコンパイル環境なら

sudo apt install crossbuild-essential-arm64

面倒なので最初から両方入れておくとよい。

ソースコードのクローン

githubからクローンすればよい。
github.com

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

ビルド

実はここから先で2週間ほどひっかかった。
ビルドは成功するのだが、カーネルカーネルモジュールを上書きすると起動時にビープがなり、更新したはずのカーネルがロードされていないのだ。
あれこれと試行錯誤の上で、見つけた記事がこれ。
akkiesoft.hatenablog.jp
この(2023年)4月からRaspberry Pi 4シリーズのデフォルトカーネルが64bitになったのだそうだ。
筆者は32bitイメージでRaspberry PiのブートSDカードを作成していたので、てっきりカーネルも32bitだと思い込んでいたのだ。
OMG、orz...
なので、以下64bitのカーネルビルドの方法を記載していく。
gitでcloneしたディレクトリー(linux)に移動して、

cd linux

シェル変数"KERNEL"を定義、

KERNEL=kernel8

ビルド用のコンフィグファイル".config"を64bit、クロスコンパイル指定で作成

make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- bcm2711_defconfig

あとで自分で作成したカーネルだと分かるように".config"内の以下の行を自分で編集しておくとよい。

CONFIG_LOCALVERSION="-v8-(自製と分かるような文字列を追加)"

いよいよビルドだ。

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

時間がかかるので、ちゃーでも飲みながら気長に待とう。

既存のイメージのカーネルカーネルモジュールを上書き

ビルドが終わったらRaspberry PiのブートSDカードのカーネルカーネルモジュールを上書きする。
Raspberry PiからSDカードを外し、Ubuntuの走っている方のPCに挿して"lsblk"と唱えると、こんな感じの奴がいるはずだ。

このsda1とsda2がRasperry PiのOSの収納されているファイルシステムだ、名前は環境によって異なるので注意。
sda1がfat32Raspberry Pi上でマウントポイントが/boot、sda2がext4でマウントポイントが/になっているファイルシステムだ。
まずそれぞれをUbuntu PC上にマウントする(現在の作業ディレクトリーはcloneしたlinuxディレクトリーなので、注意)。

mkdir mnt
mkdir mnt/fat32
mkdir mnt/ext4
sudo mount /dev/sda1 mnt/fat32
sudo mount /dev/sda2 mnt/ext4

ビルドしたカーネルモジュールをインストールする

sudo env PATH=$PATH make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- INSTALL_MOD_PATH=mnt/ext4 modules_install

カーネルとDevice Tree Blob (DTB)を上書きする、ここでは一番最初に現在のカーネルを$KERNEL-backup.imgとリネームして保管してある。

sudo cp mnt/fat32/$KERNEL.img mnt/fat32/$KERNEL-backup.img
sudo cp arch/arm64/boot/Image mnt/fat32/$KERNEL.img
sudo cp arch/arm64/boot/dts/broadcom/*.dtb mnt/fat32/
sudo cp arch/arm64/boot/dts/overlays/*.dtb* mnt/fat32/overlays/
sudo cp arch/arm64/boot/dts/overlays/README mnt/fat32/overlays/

最後にSDカードのファイルシステムをアンマウントする。

sudo umount mnt/fat32
sudo umount mnt/ext4

これで完了だ。

あとはSDカードをつっ挿して、Raspberry Piを起動すれば、自分でビルドしたカーネルからブートする。

筆者のようにCLIでログインしていない場合には、ターミナルを開いて

uname -r

と叩けばカーネルバージョンが表示される。