That's Done!

thatsdone's (mostly technical) memorandum

[ja] Linux Kernel Build TIPs


ある意味、先月のこの記事の続き。

6.12がリリースされたので、PREEMPT_RTとsched_extを試そうとしていて、必要なCONFIGを有効にするのに 少し見落としがあったのでメモ。

※'25/04/06: この記事を書いた当時に6.12で遊び、その後6.13、6.14ときて、RUSTでも気づいたことがあったので追記。

前提

  • ビルド環境: Ubuntu 24.04.1(amd64)
  • ツール類: 基本的にUbuntu bundle版
    • ただし、後述のRust関連だけ、upstreamから持ってきている

PREEMPT_RTの有効化

長らく開発が続いてきて、とうとう6.12でmergeされて話題になっていたReal-Time機能のPREEMPT_RTを使ってみたいと思ったのが発端。

ビルドにあたって、make menuconfigでは、冒頭の"General Setup"の中で、 "BPF Subsystem"の下に出てくる"Preemption Model"...ではなく、 "Fully Preemptive Kernel (Real-Time)" を選択する。(6.14の場合)

選べる詳細条件の確認は kernel/Kconfig.preempt を参照。

PREEMPT_RTで遊ぶには

realtime taskを動かせばよいのだが、 例えばrt-testsに含まれるcyclictestとかがよくつかわれるようだ。

sched_ext(CONFIG_SCHED_CLASS_EXT)の有効化

sched_extを使うと、eBPFでオレスケジューラを書いたりすることができる。

ビルドにあたって、make menuconfigでは、PREEMPT_RTと同じく "General setup"の中で、"Preemption Model"の2つ下に出てくる"Extensible Scheduling Class"が該当する。

ハマりポイントとして、上記の項目がでてこないことがあるのだが、私の場合はpaholeがインストールされていなかったのが原因だった。sudo apt install pahole した後でmake menuconfigすると選べるようになる。

同じく選べるための詳細条件の確認は kernel/Kconfig.preempt を参照。

sched_extで遊ぶには

Linux kernelの tools/sched_ext にサンプルが一式ついている。README.mdに書いてある通りの使い方で素直に動く。

ビルドして起動したkernelで、無事にsched_extが有効になっているかどうかは sysfs 経由で確認できる。 /sys/kernel/sched_ext が存在し、stateの中身で enabled/disabledがわかる。 以下は初期状態(=disabled)で、これから設定して使う。

$ ls -al /sys/kernel/sched_ext
total 0
drwxr-xr-x  2 root root    0 Mar  2 08:43 .
drwxr-xr-x 18 root root    0 Mar  2 08:10 ..
-r--r--r--  1 root root 4096 Mar  2 08:25 enable_seq
-r--r--r--  1 root root 4096 Mar  2 08:25 hotplug_seq
-r--r--r--  1 root root 4096 Mar  2 08:25 nr_rejected
-r--r--r--  1 root root 4096 Mar  2 08:25 state
-r--r--r--  1 root root 4096 Mar  2 08:25 switch_all
$ cat   /sys/kernel/sched_ext/state
disabled
$

以下、参考リンク

Rustで遊ぶには

私は仕事で機能安全が求められるような組み込みとセンタ側の両方に足を突っ込んでいるのだが、機能安全界隈でもRustが話題になっている関係もあって、遅ればせながら(kernelでも)Rustで遊んでみることにした。

以下、.configに必要な設定を入れるまでの道のり。

  • ツールチェーン関連
  • rustコンパイラ/LLVM
    • もちろんツールチェーンが必要になる。以下で配っているstable用のものを使うのが安全だと思う。
    • https://mirrors.edge.kernel.org/pub/tools/llvm/rust/
  • bindgen
    • x86_64では、当時利用していた llvm-19.1.7-rust-1.85.0-x86_64 付属の bindgenでは不具合があって必要な項目が出てこず選択できなかったため、下記のbindgenのreleaseから 0.71.1 を持ってきて入れ替えて使った
      • https://github.com/rust-lang/rust-bindgen/wreleases
    • arm64では、llvm-19.1.7-rust-1.86.0-aarch64 (rustのversionが0.01違うのに注意)にはそもそもbindgenが含まれていなかった。Ubuntu 24.04付属の bindgen は0.66系で古く、同じく不具合を起こすため、上記repositoryをcloneの上 cargo install bindgen-cli して 0.71.1 (aarch64)を入れた。(PATHの更新に注意)
  • CONFIG_MODVERSIONS
    • 少なくとも6.14の時点では、Rustによるkernel moduleを使いたい場合はloadable kernelのバージョニングを無効にする必要がある
    • "Enable loadable module support" -> "Module versioning Support" のチェックをはずす
  • CONFIG_RUST
    • "General setup" -> "Rust support" (6.14時点では一番下から2番目)をチェック
    • "Rust support"が出てこない場合、前述のツールチェーンが要件を満たしてない場合か、CONFIG_MODVERSIONS等の依存config設定に不整合がある場合がある。その他の条件を確認するには init/Kconfig の "config RUST" のところを参照のこと。
  • CONFIG_SAMPLES_RUST
    • "General setup" -> "Kernel hacking" -> "Sample kernel code" -> "Rust samples" にチェックをつけると samples/rust 以下のサンプルがビルドされる。

Ubuntuの /boot/config-* を流用する場合の注意

私は普段はUbuntuの上で生活している。この関係で新しいkernelを試す時もUbuntuの上になる。

そうすると、.config もあまりベースと違うと動くはずのものが動かなくなったりするため、/boot/config-* を流用 することが多い。

この場合の注意として、以下の2つのキーを無効にする(""を設定)必要がある。

  • SYSTEM_TRUSTED_KEYS
  • CONFIG_SYSTEM_REVOCATION_KEYS

参考記事

なお、上記の参考記事によると make menuconfig してできあがった .config を書き換えればよいようなコメントがついているのだが、少なくとも6.14の場合はもういちど make menuconfig する必要があった。(設定はなにもいじらないがとにかく保存して終了)

kernelビルドに必要なパッケージ

私は、開発環境用にUbuntuでサーバを作る場合、とりあえず build-essentialとdevscriptsを入れる。 kernelをビルドする際にこれでも足りないものを列挙しておく。

  • libncurses-dev
  • flex
  • bison
  • libelf-dev
  • libssl-dev
  • pahole (前述の通り)
  • Rust/LLVMのツールチェーン (前述の通り)

そのほか

もっとあったような気がするので別途追記/更新予定。

eBPFで気持ちよく遊ぶ都合でCONFIG_DEBUG_INFO_BTFも有効にしたのだが、これはSCXで求められるんだっけな...(To be updated)

HISTORY

  • '24/11/20 初出
  • '25/04/06 Rust関連の記述を追記
  • '25/04/13 Ubuntuの config-* を流用する場合の注意と必要パッケージを追記