kernel config 生成(略記)のためのシェルスクリプト
この記事は、 Gentoo Advent Calendar 2016 の6日目の記事です。
昨日の記事は Gentoo on Windows 10 (Gentoo Advent Calender 2016 5日目)でした。
概要
そろそろ普段使いのラップトップが壊れそうなので、別マシンへの移行の準備をしておきたさが高まっています。
Windows 8.1 を gentoo で上書きして以来、これまで様々な設定をしてきましたが、 /etc にあるファイルの多くはコピーで済まされる設定ファイルなので、移行にあたってそこまで問題になりません。
問題なのは、カーネルの .config です。
ハードウェア由来の設定が多く項目も多いため、安直にコピーしてちょっと改変すれば使えるというものでもありません。
そこで、以下のようなスクリプトが欲しくなったため、簡単に書いてみたというお話です。
-
設定の理由がわかる(コメントが書ける)
-
値の無効化(
CONFIG_FOO=n
)ができる
-
興味のない項目は、何も書かずともよろしく設定しておいてほしい
-
記述した設定に無効なもの(あるいは上書きされたもの)があれば、警告してほしい
対象読者
大雑把には、既に gentoo を使っていたりカーネルをコンパイルしている人向けです。
-
gentoo を使っていて、カーネルの .config をそこそこの頻度で弄っている人
-
複数台のマシンで gentoo を使っている人
-
その他 distro でも、カーネルを野良でビルドしたい人
残念ながら gentoo の布教記事ではございません。
merge_config.sh
……と思って作ろうとしていましたが、よくよく調べてみると、 Linux カーネルのソース(gentoo であれば /usr/src/linux など)の scripts/kconfig/merge_config.sh に、かなり近い目的のものがありました。
中身を読んでみると、ファイル名のとおり、設定ファイルとして有効なファイル同士の merge 用途のものであり、コメントやインデント、省略記法などは使えないようです。
そこで方針を変えて、書きやすい設定を merge_config.sh
で使えるよう変換して吐き出すスクリプト(というか実質正規表現)を書くことにしました。
追加の要件は以下のような感じです。
-
インデントを使える
-
コメントを書いても無効/不正扱いされない
CONFIG_FOO=n
のように書いても警告されない
CONFIG_
のプレフィックスを省略できる
成果物
小さなコードなので、ライセンスは CC0 とします。
(要するにパブリックドメインです。)
というか実質 sed スクリプト。
つかいかた
-
スクリプトを保存して x フラグを立てる
-
スクリプトと同じディレクトリに config というファイルを作って設定を書く
-
sudo ./genconfig.sh
-
カーネルコンパイル。
私の場合:
sudo genkernel --makeopts="-j4" --splash --no-clean --oldconfig all
ソースコードのディレクトリはデフォルトで /usr/src/linux
ですが、 SRC_DIR=/path/to/linux/source ./genconfig.sh
のようにすれば別の場所を使うことができます。
そのディレクトリのパーミッションによっては、 sudo
は必要ないかもしれません。
config
ファイルの内容
文法はシンプルです。
-
空白文字によりインデント可能
#
で行コメント
-
ただし
^\s*# (CONFIG_[A-Za-z0-9_]+) is not set$
にマッチする行は # \1 is not set
に変換される
# CONFIG_FOO is not set
のような行を保存するためです
CONFIG_FOO=bar
や FOO=bar
は CONFIG_FOO=bar
に変換される
CONFIG_FOO=n
は # CONFIG_FOO is not set
に変換される
merge_config.sh
に「設定が反映されていない」という警告を出されるのを防ぐためです
で、たとえば実際に私が使っている設定(の抜粋)は以下のようになります。
CONFIG_COMPAT_VDSO
や CONFIG_I2C_CHARDEV
など、名前からは何故これを有効/無効にしたのかわからないような設定は結構ありますが、こうしてコメントとインデントで整理して書いてやることで、設定の意図や必要性がある程度明確にわかるようになります。
私は面倒だったので使いませんでしたが、 vim などであれば fold marker を使って折り畳みできるようにすれば、より読み易くなるかもしれません。
解説
merge_config.sh
先述の通りですが、大雑把に言うと、既に .config として使えるファイルを複数指定すると、それらを merge して、ついでに指定されなかった項目を自動でよろしく設定してくれるものです。
そして、私のスクリプトがあてにしている、自動でよろしく設定する部分は、シェルスクリプトではなく make
によって行われます。
$ALLTARGET
は、デフォルトでは alldefconfig
ですが、 -n
オプションを付けて merge_config.sh
を起動すると allnoconfig
となります。
make alldefconfig
名前そのままですが、 alldefconfig
は、与えられた config において未指定の項目に、デフォルト値を設定します。
同様に allnoconfig
は、与えられた config において未指定の項目のすべてに、 n
(no) を設定します。
他にも、 allyesconfig
とか randconfig
とかいろいろあります。
詳しくは make help
とかで見られます。
もし私のスクリプトで allnoconfig
を使いたい場合、 ./scripts/kconfig/merge_config.sh
の呼び出しで -n
を追加しましょう。
まとめ
-
カーネルコンフィグ管理を手助けする簡単なスクリプトを書いた
make oldconfig
や genkernel --menuconfig --oldconfigall
で積み重ねてきた秘伝のタレを棄てて、設定はレシピから作りましょう
-
gentoo でカーネルをコンパイルすると言うとビビる人がいますが、実際のところコンフィグ作って
make
すればおしまいなので、こわくないです
-
なんなら項目ぜんぶ
y
(yes) とか m
(module) とかにしとけば基本どうにかなりそう
(コンパイル時間延びるけど)
- gentoo と LFS の他にカーネルコンパイルが必要そうな distro を知りませんが、この記事の内容は gentoo でなくとも適用できます。
gentoo AdC なのにごめんなさい。
おまけ
portage のログ
/var/log/portage/elog/summary.log に、過去 portage で emerge されたパッケージのメッセージが記録されています。
これを見て検索をかければ、どのパッケージがどのような設定を要求しているか、ある程度わかるでしょう。
vim で見易いよう、簡単な syntax を用意しておきました。
ご活用ください。
次に欲しい機能
現状でそこそこ満足なので、今のところこれ以上リソースを注ぐつもりはありませんが、改良点があるとしたら以下の点です。
複数ファイルのマージ
先述のとおり merge_config.sh
は複数ファイルのマージ機能を持っているので、たとえば設定ファイルを基礎用、ハードウェア用、各パッケージ用、各マシン特有設定など、複数に分割して管理できるようにするのは難しくないでしょう。
私がそれをしなかったのは、単にファイルをスクリプトの引数でとれるようにすると、パスの解決がちょっと面倒かもと思ったからです。
でも今よく考えたら readlink
とかで絶対パス取得できそうなのでそのうち実装するかも。
依存性解析
たとえば CONFIG_FOO
が前提条件として CONFIG_BAR
を要求している場合、そっちも勝手に有効化してくれたら嬉しいです。
ですが実際には、 m
にするか y
にするか、或いは複数の OR 条件がある場合どれを満たすべきか、など自由度が高めなので、全自動にはできそうにありません。
あと、依存関係を取得するには Kconfig を読むことになるので、シェルスクリプトだと荷が重いかもしれません。
不可能ではないでしょうが、私なら別の言語を使います。
追記1 (2016/12/06 00:12): kernel-config-check.py
kernel config checkには kernel-config-check.py とか / “kernel config 生成(略記)のためのシェルスクリプト - 何とは言わない天然水飲みたさ”
https://blog.cardina1.red/2016/12/06/kernel-config-shellscript/
—
@naota344@twitter.com,
,
Twitter
kernel-config-check.py
というものを公開している方がいらっしゃるようで、これを使うと、インストール済のパッケージが要求するカーネルオプションを網羅できるようです。
すごい!
便利!
圧倒的感謝!!