1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 3 years have passed since last update.

【Raspberry Pi 4B】RAMディスク、CPUオーバークロックを併用してもカーネルローカルビルド時間は大して変わらなかったって話

Posted at

【前文】

公式 にもある通り、カーネルのビルド方法は大きく分けて以下の 2パターン。

  • Raspberry Pi本体でのローカルビルド
  • PC や 仮想環境(VirtualBox や VMWare)でのクロスビルド

前者は Raspberry Pi本体だけで済むし、ビルド、インストールをシームレスに行うことができて初学者向け。
しかし Pi4B でもビルドに 1時間強もかかるのが。膨大な量のソースをコンパイルするから、せめて RAMディスク上で作業すれば速くなるのかな?
という素朴な疑問が出発点。

しかし目を見張るほどの時間短縮はせず。何がボトルネック? やはり CPUパワー? ならばオーバークロックでしょ。
と試してみるも、やはりあまり変わらなかった。

残念な結果だったけど折角なので記録として残す。
ビルド時間は以下。

ケース ビルド時間
microSDカード上ビルド 61m42.817s
RAMディスク上ビルド 57m33.457s
RAMディスク上 + オーバークロックでビルド 56m42.724s

作業環境は以下。

Pi OS Kernel
Raspberry Pi4B 4G Raspberry Pi OS Lite / Raspbian GNU/Linux 10 (buster) 5.10.17-v7l+

と書いていて気が付いたけど、「Raspberry Pi OS」に名称が変更された筈なのに、内部的にはまだ「Raspbian」なんだね。

pi@raspberrypi:~ $  lsb_release -a
No LSB modules are available.
Distributor ID: Raspbian
Description:    Raspbian GNU/Linux 10 (buster)
Release:        10
Codename:       buster
pi@raspberrypi:~ $

CUI環境での作業になるので Raspberry Pi OS Lite を使用。
RAMディスク設定、CPUオーバークロック設定、カーネルビルド方法はぐぐれば沢山出てくるけど、ワンセットとなると見かけないので以下に手順を記す。

【RAMディスク設定】

microSDカードの寿命延命目的でRAMディスクの利用は Raspberry Pi で鉄板ネタ。
解説サイトは沢山あるけど、こちら がシンプルで分かりやすい。必要にして十分な内容。これを参考に設定した。

pi@raspberrypi:~ $ cat /etc/fstab
proc            /proc           proc    defaults          0       0
PARTUUID=b8f462a2-01  /boot           vfat    defaults          0       2
PARTUUID=b8f462a2-02  /               ext4    defaults,noatime  0       1
# a swapfile is not a swap partition, no line here
#   use  dphys-swapfile swap[on|off]  for that
tmpfs /mnt/ramdisk tmpfs defaults,noatime,mode=755,uid=pi,gid=pi,size=3g,nofail 0 0
pi@raspberrypi:~ $

但し、カーネルビルドに 2G では足りないので、3Gに設定している。
因みに sizeパラメータに小数指定は許可されていないようで、「3G じゃなくて 2.7G」とか思って設定するとコケるので注意。
更に fstab って記述にミスがあるとそれだけで起動に失敗する(Linuxあるある)。念の為、オプションに nofailを追加した。

4G中、3G も RAMディスクに割り当てるのはバランスが悪い気もするけど、ソースだけで 1Gを超えるしデバッグオプションを有効にしたビルドとなれば 3Gでも足りない。8G版で 4~5G を RAMディスクに割り当てての作業になると思う。
8G版なんて、そんなにメモリ必要ないでしょ、と個人的には思っていたけど、RAMディスクを活用しようとすると考え方も変わってくるね。

fstab に RAMディスクの設定を追記し再起動したら、dfコマンドで /mnt/ramdiskにマウントされていることを確認。

pi@raspberrypi:~ $ df -h
ファイルシス   サイズ  使用  残り 使用% マウント位置
/dev/root        3.9G  2.6G  1.1G   71% /
devtmpfs         1.8G     0  1.8G    0% /dev
tmpfs            1.9G     0  1.9G    0% /dev/shm
tmpfs            1.9G  8.5M  1.9G    1% /run
tmpfs            5.0M  4.0K  5.0M    1% /run/lock
tmpfs            1.9G     0  1.9G    0% /sys/fs/cgroup
tmpfs            3.0G     0  3.0G    0% /mnt/ramdisk
/dev/mmcblk0p1   253M   48M  205M   19% /boot
tmpfs            383M     0  383M    0% /run/user/1000
pi@raspberrypi:~ $

ついでに以下のコマンドでベンチマーク。

dd if=/dev/zero of=temp.txt bs=1M count=1024
sync; echo 3 > /proc/sys/vm/drop_caches
dd if=temp.txt of=/dev/null bs=1M count=1024

dd if=/dev/zero of=temp.txt bs=1G count=1
sync; echo 3 > /proc/sys/vm/drop_caches
dd if=temp.txt of=/dev/null bs=1G count=1

コマンドはやはり前述のサイトを参考にさせて頂いた。しかしキャッシュクリア処理が無かったので追加した。
これをやらないと microSDカード上の読込が RAMディスクと変わらないという結果になるので。(キャッシュの有用性が良く分かる事例ではあるけど)

結果は以下。

デバイス データ量 書込 読込
microSD 1.0GiB(1M×1024) 18.2 MB/s 45.4 MB/s
microSD 1.0GiB(1G×1) 16.0 MB/s 45.5 MB/s
RAMディスク 1.0GiB(1M×1024) 310 MB/s 583 MB/s
RAMディスク 1.0GiB(1G×1) 180 MB/s 265 MB/s

厳密には 5~10回計測しその平均、とかだろうから、上記は参考記録程度に。

【オーバークロック設定】

これも鉄板ネタなので解説サイトは沢山あるけど、こちら を参考にさせて頂いた。
/boot/config.txt の設定値は以下。

over_voltage=2
arm_freq=1750

CPUクロック数、温度、電圧確認コマンドは以下。

vcgencmd measure_clock arm && vcgencmd measure_temp && vcgencmd measure_volts

アイドル時の計測結果は以下。

frequency(48)=600169920
temp=45.7'C
volt=0.9125V

ビルド中の計測結果は以下。

frequency(48)=1750412160
temp=58.4'C
volt=0.9125V

CPU冷却ファンクーラ付きケース が早速役に立った。常時運用でも問題ないかな?
というかそもそも 1.75GHz ってのが弱いのかなぁ。2GHz はいけるって話もあるけどそこまでは未確認。

【RAMディスク上でのカーネルビルド】

1. ビルドツールインストール

公式 に従い、以下のコマンドでGitとビルドの依存関係をインストール。

sudo apt install git bc bison flex libssl-dev make -y

更に こちら によれば、以下も必要らしいので実行。

sudo apt-get install -y -qq --no-install-recommends make libncurses-dev kernel-package
sudo apt-get install -y -qq --no-install-recommends bison flex

2. バックアップ

必要があれば現在の microSDをイメージバックアップ。
カーネル関連のファイル単位でバックアップする手もあるけど、リカバリの際カーネルドライバはファイルだけ戻せば良いって話でもないし。
ここら辺を分かっていない場合はイメージバックアップの方が確実。

3. カーネルソース取得

明示的に取得パスを指定しない場合、/usr/src/配下にダウンロードされる。
今回は RAMディスク上での作業なので、以下のようにパスを指定し実行。

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

実行結果は以下。

pi@raspberrypi:~ $ sudo git clone --depth=1 https://github.com/raspberrypi/linux /mnt/ramdisk/linux
Cloning into '/mnt/ramdisk/linux'...
remote: Enumerating objects: 75497, done.
remote: Counting objects: 100% (75497/75497), done.
remote: Compressing objects: 100% (72055/72055), done.
remote: Total 75497 (delta 6055), reused 15825 (delta 2645), pack-reused 0
Receiving objects: 100% (75497/75497), 199.16 MiB | 3.25 MiB/s, done.
Resolving deltas: 100% (6055/6055), done.
Checking out files: 100% (71110/71110), done.
pi@raspberrypi:~ $

取得したソースディレクトリに移動し取得したブランチを確認。

cd /mnt/ramdisk/linux
git branch

実行結果は以下。

pi@raspberrypi:~ $ cd /mnt/ramdisk/linux
pi@raspberrypi:/mnt/ramdisk/linux $ git branch
* rpi-5.10.y
pi@raspberrypi:/mnt/ramdisk/linux $

rpi-5.10.y であることが分かる。
因みに明示的にブランチを指定し取得する場合は以下。

sudo git clone --depth=1 --branch rpi-5.10.y https://github.com/raspberrypi/linux /mnt/ramdisk/linux

リモート側のブランチの一覧を確認したい場合は、git ls-remoteコマンドで。

pi@raspberrypi:/mnt/ramdisk/linux $ git ls-remote | grep rpi-5.
From https://github.com/raspberrypi/linux
0222b82b2f1fcf1e0c477f77c50688c98f35e2bf        refs/heads/rpi-5.0.y
29ee73a82540e8b94c6bde0ad1acae65f73653ea        refs/heads/rpi-5.1.y
13c43880f2ee6db7d26949cb6a3e8db1a4b76736        refs/heads/rpi-5.10.y
2cbd302b1e200073ecf52b2f96e619c9561625a1        refs/heads/rpi-5.11.y
425ed5a960386760d811aee0ad7fd5b0a6e37b22        refs/heads/rpi-5.12.y
94dbfa7606fc2f3df44979ed9c2d1d3676f2c159        refs/heads/rpi-5.2.y
32ba05a62a8071d091d7582cc37b4bac2962b1dd        refs/heads/rpi-5.3.y
93349cdffc3fbb446c7c1fc7354215a5b8e30b97        refs/heads/rpi-5.4.y
96a3278497cc6540d32dc4a7dba9100da6df16f0        refs/heads/rpi-5.5.y
ff0aa78166a59d44bc8d472386699624c8db6da5        refs/heads/rpi-5.6.y
fe872d026d3a280a5151af08eb949eddf586fa1b        refs/heads/rpi-5.7.y
9b3199ca416d89b1f810fc65d8ffe1ad2a03ac0e        refs/heads/rpi-5.8.y
104137d44c6365fafc36ec1ea59db06f58ef5dfc        refs/heads/rpi-5.9.y
e850ab437a2d0fa607d410b7bae62f90fb941430        refs/tags/rpi-5.10.y_20201122
pi@raspberrypi:/mnt/ramdisk/linux $

rpi-5系は 12 まである模様。

取得したカーネルソースのバージョン確認。

pi@raspberrypi:/mnt/ramdisk/linux $ head Makefile -n 5
# SPDX-License-Identifier: GPL-2.0
VERSION = 5
PATCHLEVEL = 10
SUBLEVEL = 23
EXTRAVERSION =
pi@raspberrypi:/mnt/ramdisk/linux $

5.10.23 ってことになるだんけど、現在最新の安定バージョンは 5.10.17

pi@raspberrypi:/mnt/ramdisk/linux $ uname -r
5.10.17-v7l+
pi@raspberrypi:/mnt/ramdisk/linux $

最新の安定バージョンのソースを取得したい場合は? という疑問が湧いてくるけどそれは後述。

4. カーネルソースバックアップ

取得したカーネルソースは RAMディスク上なので電源を落とせば消えてしまう。後日再実行する場合など、再取得は面倒で時間がかかる。必要があればバックアップを取り、再実行時はそれを展開する。
/usr/src/linux.rpi-5.10.y.tar.gz として圧縮バックアップするコマンド例は以下。

sudo tar -C /mnt/ramdisk -zcf /usr/src/linux.rpi-5.10.y.tar.gz linux

それをリストアするコマンド例は以下。

sudo rm -rf /mnt/ramdisk/linux
sudo tar -zxf /usr/src/linux.rpi-5.10.y.tar.gz -C /mnt/ramdisk

と書いていて思ったんだけど、だったら最初っから圧縮形式でダウンロードした方が速くないかい? って話もあり、その場合は以下。

curl -L https://github.com/raspberrypi/linux/archive/refs/heads/rpi-5.10.y.zip > rpi-5.10.y.zip

5. カーネルビルド

ローカルビルドの場合、公式配布のカーネルと区別する為、MakefileEXTRAVERSION定義にそれとわかる文字列を設定しておくのがお約束。ログイン時や unameコマンド等でカーネルバージョンが表示される場合、この定義も表示される。
設定コマンド例は以下。

cd /mnt/ramdisk/linux
sudo sed -i 's/EXTRAVERSION =/EXTRAVERSION = -god/g' Makefile
grep 'EXTRAVERSION =' Makefile

実行結果は以下。

pi@raspberrypi:/mnt/ramdisk/linux $ cd /mnt/ramdisk/linux
pi@raspberrypi:/mnt/ramdisk/linux $ sudo sed -i 's/EXTRAVERSION =/EXTRAVERSION = -god/g' Makefile
grep 'EXTRAVERSION =' Makefilepi@raspberrypi:/mnt/ramdisk/linux $ grep 'EXTRAVERSION =' Makefile
EXTRAVERSION = -god
pi@raspberrypi:/mnt/ramdisk/linux $

以下コマンドでビルド。

KERNEL=kernel7l
sudo make bcm2711_defconfig
time sudo make -j4 zImage modules dtbs

ビルド時間が分かるよう timeコマンドで実行している。ここで 1時間前後かかる。不要であれば勿論単に sudo make -j4 zImage modules dtbs で構わない。

実行結果は以下。

pi@raspberrypi:/mnt/ramdisk/linux $ KERNEL=kernel7l
pi@raspberrypi:/mnt/ramdisk/linux $ sudo make bcm2711_defconfig
  HOSTCC  scripts/basic/fixdep
  HOSTCC  scripts/kconfig/conf.o
  HOSTCC  scripts/kconfig/confdata.o
  HOSTCC  scripts/kconfig/expr.o
  LEX     scripts/kconfig/lexer.lex.c
  YACC    scripts/kconfig/parser.tab.[ch]
  HOSTCC  scripts/kconfig/lexer.lex.o
  HOSTCC  scripts/kconfig/parser.tab.o
  HOSTCC  scripts/kconfig/preprocess.o
  HOSTCC  scripts/kconfig/symbol.o
  HOSTCC  scripts/kconfig/util.o
  HOSTLD  scripts/kconfig/conf
#
# configuration written to .config
#
pi@raspberrypi:/mnt/ramdisk/linux $ time sudo make -j4 zImage modules dtbs
(中略)
  LD [M]  sound/usb/hiface/snd-usb-hiface.ko
  LD [M]  sound/usb/misc/snd-ua101.ko
  LD [M]  sound/usb/snd-usb-audio.ko
  LD [M]  sound/usb/snd-usbmidi-lib.ko

real    56m42.724s
user    193m28.695s
sys     29m5.682s
pi@raspberrypi:/mnt/ramdisk/linux $

6. カーネル更新

カーネルビルドに成功したら、以下コマンドで自身のカーネルを上書き更新。

sudo make modules_install
sudo cp arch/arm/boot/dts/*.dtb /boot/
sudo cp arch/arm/boot/dts/overlays/*.dtb* /boot/overlays/
sudo cp arch/arm/boot/dts/overlays/README /boot/overlays/
sudo cp arch/arm/boot/zImage /boot/$KERNEL.img

因みに最初の 1行目はカーネルドライバの更新。
make modules_install

コンパイルされたモジュールが /lib/modules/<kernel version>-<config local version> にコピーされます

手動でインストールしていたドライバがあれば入れ直すこと。

sudo reboot で再起動。
再起動後、ログインしカーネルのバージョン確認。

Linux raspberrypi 5.10.23-god-v7l+ #1 SMP Sat Mar 20 23:10:25 JST 2021 armv7l
(中略)
pi@raspberrypi:~ $ uname -a
Linux raspberrypi 5.10.23-god-v7l+ #1 SMP Sat Mar 20 23:10:25 JST 2021 armv7l GNU/Linux
pi@raspberrypi:~ $ uname -r
5.10.23-god-v7l+
pi@raspberrypi:~ $

【任意のカーネルソースの取得】

ピンポイントでの任意のカーネルソースの取得方法が良く分からず悩んだ。
2021年3月現在、安定バージョンの最新は 5.10.17。これを取得したいとする。

最初は こちら を参考にさせて頂いたが上手くいかず。
糸口になったのが こちら。そしてやっと辿り着いたのが こちら
ハッシュ値 13b6016e96f628ac1cfb3c0b342911fd91c9c005 が分かれば以下のように取得できる。

pi@raspberrypi:/mnt/ramdisk $ curl -L https://github.com/raspberrypi/linux/archive/13b6016e96f628ac1cfb3c0b342911fd91c9c005.tar.gz > linux.rpi-5.10.17.tar.gz
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed
100   159  100   159    0     0    398      0 --:--:-- --:--:-- --:--:--   398
100  176M    0  176M    0     0  3522k      0 --:--:--  0:00:51 --:--:-- 3524k
pi@raspberrypi:/mnt/ramdisk $

更に確認すると、これって要するに リリース一覧 の最新である raspberrypi-kernel_1.20210303-1

リリース一覧の最新がつまり安定板の最新って当たり前か。
でもこの年月日系のタグからカーネルのバージョンはどうやって判断するの? 月一で SUBLEVEL が上がっているっぽいからそこから判断?
ここら辺は運用を知らないと分からないよね。慣れていくしかないのかな。

それと最後に。
速度面ではあまり真価を発揮できなかった RAMディスクだけど、microSDカードの消耗を抑える点では有用なので活用すべきでは。

1
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
1
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?