はじめに (対象読者・この記事でわかること)

この記事は、LinuxカーネルのeBPF技術に興味があり、特にラズベリーパイ環境でlibbpfを利用したい方を対象としています。プログラミングの初学者ではなく、LinuxシステムやC言語の基本的な知識があることを前提としています。

本記事を読むことで、ラズベリーパイでlibbpfを利用する際に発生する「libbpf: failed to find valid kernel BTF」というエラーの原因を理解し、具体的な解決方法を実践できるようになります。また、eBPFとlibbpfの基本的な概念についても理解を深めることができます。

この記事を書いた背景として、私自身がラズベリーパイでeBPFプログラミングを試みた際にこのエラーに遭遇し、解決に時間を要した経験があります。同じ問題で悩んでいる方の助けになれば幸いです。

前提知識

この記事を読み進める上で、以下の知識があるとスムーズです。

  • Linuxカーネルの基本的な知識
  • C言語の基本的なプログラミング能力
  • ラズベリーパイの基本的な操作知識
  • コマンドラインの基本的な操作
  • Makefileの基本的な理解

libbpfとkernel BTFの概要

libbpfは、LinuxカーネルのeBPF (Extended Berkeley Packet Filter) 技術を利用するためのライブラリ群です。eBPFは、Linuxカーネル内で安全に実行可能な仮想マシンであり、ネットワークパケット処理、システムトレース、セキュリティ監視などに広く利用されています。

BTF (BPF Type Format) は、eBPFプログラムがカーネル内のデータ構造にアクセスするための型情報を提供するフォーマットです。libbpfは、このBTF情報を利用してカーネルオブジェクトを正しく解釈します。

ラズパイでlibbpfを利用しようとすると、「libbpf: failed to find valid kernel BTF」というエラーが発生することがあります。これは、ラズベリーパイのカーネルにBTF情報が含まれていないか、libbpfが正しくBTF情報にアクセスできない場合に発生します。特に、Raspberry Pi OSの標準カーネルでは、BTFサポートがデフォルトで有効になっていないことが原因です。

kernel BTFエラーの解決方法

ここでは、ラズベリーパイでlibbpfを利用する際に発生するkernel BTFエラーを解決する具体的な手順を説明します。

ステップ1: ラズパイのカーネルバージョンの確認

まず、現在のラズベリーパイで使用しているカーネルバージョンを確認します。ターミナルで以下のコマンドを実行します。

Bash
uname -r

出力されるカーネルバージョンをメモしておきます。一般的に、カーネルバージョンが5.4以上であればBTFサポートが利用可能ですが、ラズベリーパイの場合は追加の設定が必要です。

ステップ2: 必要なパッケージのインストール

BTF情報を生成するために、いくつかのパッケージをインストールする必要があります。以下のコマンドを実行します。

Bash
sudo apt update sudo apt install -y build-essential libelf-dev llvm clang

これにより、カーネルのビルドに必要なツールと、BPFコンパイラであるclangがインストールされます。

ステップ3: カーネルのBTF情報の生成

ラズベリーパイのカーネルにBTF情報を追加するには、カーネルを再ビルドするか、BTF情報を別途生成する必要があります。ここでは、既存のカーネルにBTF情報を追加する方法を説明します。

まず、カーネルのソースコードをダウンロードします。使用しているカーネルバージョンと一致するソースコードをダウンロードします。

Bash
KERNEL_VERSION=$(uname -r | cut -d'-' -f1) wget https://github.com/raspberrypi/linux/archive/raspberrypi-kernel_${KERNEL_VERSION}.tar.gz tar -xvf raspberrypi-kernel_${KERNEL_VERSION}.tar.gz cd linux-raspberrypi-kernel_${KERNEL_VERSION}

次に、カーネルの.configファイルを現在のカーネル設定からコピーします。

Bash
cp /boot/config-$(uname -r) .config

カーネル設定を編集し、BTFサポートを有効にします。

Bash
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- olddefconfig

BTFサポートを有効にするために、以下の設定を変更します。

Bash
echo "CONFIG_DEBUG_INFO_BTF=y" >> .config echo "CONFIG_DEBUG_INFO_BTF_MODULES=y" >> .config

カーネルをビルドします。このプロセには数時間かかることがあります。

Bash
make ARCH=arm64 CROSS_COMPILE=aarch64-linux-gnu- -j$(nproc)

ビルドが完了したら、BTF情報を生成します。

Bash
pahole -J vmlinux | gzip -c > /boot/vmlinux-${KERNEL_VERSION}.btf.gz

生成したBTF情報をシステムにコピーします。

Bash
sudo cp /boot/vmlinux-${KERNEL_VERSION}.btf.gz /boot/

ステップ4: libbpfのビルドとインストール

libbpfをビルドしてインストールします。まず、libbpfのソースコードをダウンロードします。

Bash
git clone https://github.com/libbpf/libbpf.git cd libbpf git checkout $(git describe --tags --abbrev=0)

libbpfをビルドしてインストールします。

Bash
make sudo make install sudo ldconfig

ハマった点やエラー解決

実装中に遭遇する問題や、エラーの解決方法について記載します。

エラー1: paholeコマンドが見つからない

BTF情報を生成するためにpaholeコマンドを使用しますが、このコマンドがインストールされていない場合があります。

Bash
pahole: command not found

解決策:

dwarvesパッケージをインストールします。

Bash
sudo apt install dwarves

エラー2: カーネルビルド中にエラーが発生する

カーネルのビルド中に、以下のようなエラーが発生することがあります。

Bash
error: unknown type name 'struct bpf_map'

解決策:

カーネルのソースコードが正しくダウンロードされていない可能性があります。カーネルバージョンを確認し、正しいソースコードをダウンロードしてください。

エラー3: libbpfのビルド中にエラーが発生する

libbpfのビルド中に、以下のようなエラーが発生することがあります。

Bash
error: BPF skeleton generation failed

解決策:

BTF情報が正しく生成されていない可能性があります。ステップ3でBTF情報を生成し、正しい場所に配置されているか確認してください。

解決策

上記の手順を実行することで、「libbpf: failed to find valid kernel BTF」というエラーを解決できます。特に重要なのは、カーネルにBTF情報を追加するステップです。

また、ラズベリーパイのカーネルをカスタマイズする代わりに、BTF情報を含む事前ビルドされたカーネルを使用する方法もあります。この方法は、より簡単ですが、カーネルのアップデート時に再度設定が必要になる可能性があります。

動作確認として、以下のような簡単なeBPFプログラムを実行してみてください。

C
#include <linux/bpf.h> #include <bpf/bpf_helpers.h> SEC("tracepoint/syscalls/sys_enter_openat") int trace_openat(void *ctx) { return 0; } char _license[] SEC("license") = "GPL";

このプログラムをコンパイルして実行し、エラーが発生しなければ成功です。

まとめ

本記事では、ラズベリーパイでlibbpfを利用する際に発生する「libbpf: failed to find valid kernel BTF」というエラーの原因と解決方法について解説しました。

  • 要点1: ラズベリーパイのカーネルにはBTF情報がデフォルトで含まれていない
  • 要点2: カーネルの再ビルドとBTF情報の生成が必要
  • 要点3: libbpfのビルドとインストールを正しく実行することでエラーを解決できる

この記事を通して、ラズベリーパイ環境でeBPFプログラミングを行うための基礎知識を得られたと思います。今後は、より高度なeBPFプログラムの作成方法や、ラズベリーパイでの応用例についても記事にする予定です。

参考資料