2012/07/27

Linux カーネル再構築のコツ

(DANGEROUS) パソコンに詳しい人以外はしないこと 仕事で使うコンピュータでしないこと 今ではパソコンでは本当はあまり必要が無い

カーネルの再構築というのは、万人向けのディストリビューションが用意したカーネルでなく、
自分でカーネルの機能を選択してコンパイルして置き換えることをさします。
かつては自分のパソコンのCPUに最適化コンパイルすることもやりましたが、新しいCPUは充分に速いので動画とCGのプログラム以外では余り必要ないです。

自分がたまにしていた、カーネルの再構築のコツです。
基本的な流れは
$ make menuconfig
$ make
# make modules_install
# make firmware_install
# make install
さらに大抵のディストリビューションは
起動時に必要なモジュールを/のマウント前にinitrdから読み込む為の作業がひつよう
さらに
$ make headers_install
# cp -R usr/include/*/ /usr/include
これをしないと、C言語のヘッダファイルが入らず新しいカーネルのシステムコールを自分でコンパイルするプログラムから使えません。

/usr/srcにカーネルソースコードがあり、rootでなしに再構築したいなら、O=<ビルドディレクトリ> オプションを、
makeの呼出しのときにいつも付けなくてはなりません。

カーネルの部品は、だいたい
/boot以下にvmlinuzという本体、initrd(initrd.gzであることもある)、
/lib/modules/<バージョン番号>以下にカーネルモジュール、
/lib/firmwareにデバイスのファームウェア、
/usr/include以下のいろいろなところにC言語のヘッダファイルが入ります。

こんな感じです。 カーネルの再構築は、SlackwareかLinux from scratch、Gentooがうまく出来ます。
Debianや最近の有名ディストリははまた違うらしいです。
自動化がだいぶ進んでおりパッケージを作ってインストールします。
更に言うと最適化コンパイルをしなくても特定のCPUむけに最適化されたカーネルのパッケージが
公式のリポジトリにあったりするのです。
更に言うとRHELなど有償サポートの付いたLinuxはカーネルの再構築でサポート契約が無効になってしまいます。

で、一番大事なのはカーネルのコンフィグなんです!

Linuxの特徴的な機能にカーネルモジュールが有って、
起動時に必要な機能だけ呼び出せます。
デバイスドライバはモジュールにするのが主流です。
カーネルに組み込んじゃうことも出来ます。起動が速くなります。
カーネルコンフィグでMを選ぶとモジュールになります。
ブートローダーに一部のモジュールを圧縮アーカイブにしたinitrdもロードしてもらうと、
そこから必要なモジュール、たとえばルートファイルシステムをマウントするのに必要なドライバーすべてをカーネルが取り出してつかえます。
initrdはごく小規模な環境も持っており、ルートファイルシステムが使えないなどの重大事態で
busyboxというシェル+コマンド群がひとつの変なのを呼び出して管理者がなんとかすることも実現できます。
initrdはカーネルを再構築するなら専用のコマンドを使い基本自分で作ります。いれるカーネルモジュールを選択することになります。Arch Linuxではある程度大雑把に選べるようです。
バージョンの違うカーネルのinitrdを使うと盛大にカーネルパニックになります。ファイルシステムを荒すかも知れません。

再構築のときの コンフィグ作業は
make menuconfigがバグがなくてやりやすいです。
これ結構項目有ります。
英語が少しでも読めないと恐ろしい事になりそう。
プログラムによってはカーネルの変な機能を使うものが有って、
特に起動時に大事なudevやsystemdの要求する設定をしなくては。
/usr/doc/udev-*/README
にかいてあります。
パソコンを組み立てた人より更に高度な知識を要求します。
組み立てるだけではわからない細々としたハードウェア機能が項目に表れます。
自分のパソコンの仕組みをよく知った方がいいです。
昔のパソコンユーザーが必要だったx86、PC/ATやDOSの知識が今でも必要なのがこの作業。
しかし、高速化するMTRRやMSI、NUMA、ACPIや仮想化サポートなどの新機能も有効に。マルチコアはSMPを有効にしないと使えない。HTもenable。
相当なマニアックでないとわからない項目もあります。
ハッカーならではのアイデアが実装されており、
アマチュア無線機でネットをするAX25、ゲーム機のコントローラーを(古い有線のものでも)Linuxで使える様にするドライバ、なんかしらないがPT1も使えます。
OSの仕組みももちろん知った方がいいです。だいたいのOSには標準的な機能と言うのが有ります。
なるべく機能をたくさん入れた方が安全です。機能を削る項目も有ります。ご注意。
無闇に軽くしようとすると肝心なあんなこんなプログラムが使えなくなり、非常に動きが遅くなります!
但し、特定の用途、ハードウェア向けの機能など不用意にいれても機能しないもの、セキュリティが危うくなりそうなものがあります。エラーインジェクションなんてわざとエラーを起こす機能があったりストレステストモードとか。
<Help>で確認しましょう。英語だけれど。
ここには何もしらなければこれをいれておこうとかいれるなとかと書いて有る事が有ります。
さらに(DANGEROUS)とか書いて有るのは滅多に使わないこと。

選択肢が固定される場合があります。他の機能が必要とする機能は自動で有効になります。

-----単語理解(ただしこれだけではスーパースリルな事に 英語が読めるのが一番大事)-----
Y = yes
M = モジュール化
N = no
enable = 有効
disable = 無効
EXPERIMENTAL = 実験的(まあ個人向けでは使えたりする)
DEPRECATED = この機能はいらないと思われている
obsolete = もう古いからいらない機能
ancient = 古代 コンピューターの世界では20年前の機能、ドライバは古代のもの
recommended = 推薦されてる
embedded = 限定的な機能しか持たない(パソコンより更に小さいデバイス)
verbose = 表示がたくさん出る
scheduler = パソコンの作業をスケジュールする 例:IO schedulerは入出力(HDDなど)の手順をスケジュール
force = 無理矢理でも実行、壊れてもかまわない
hotplug = いきなりパソコンに他の機器や部品を付けても認識し使える様にする、
 当たり前のようでコンピューターの大進化のひとつであり、ぜひ有効化を メモリだってホットプラグ!
evdev = 手で触る周辺機器の機能 マウスやキーボードの項目も有るが これが無いとXが...
Staging drivers= 気の速い人へテスト中のデバイスドライバが入っているカテゴリ
ALSA = Advance Linux Sound Archetecture Linuxのサウンド機能 絶対入れようね?
OSS = UNIX系で標準のOpen Sound System  LinuxではALSAがオプションで代わりを出来る
*HCI = 通信ケーブルやBluetoothの規格でドライバひとつでいろいろ使えるときにこれが出ることが多い ただ規格にもいくつかあってだな
DRM DRI = カーネルとハードウェアによるグラフィック機能 回りくどい歴史があるので詳しくはググって
modeset = カーネルがCGやビデオ機能の準備を全部やる。コンソールからもうフル機能が使える プロプラドライバは対応できない
V4L = Video for Linux 映像の取り込み機能
cgroup = control group カーネルの再構築、再起動なしにカーネルをチューニングできる機能
 サーバーで使うがなぜかDesktop版のディストリでも入っている
sysfs = 仮想ファイルシステム。/sys以下のファイルを読み書きすることでカーネルの設定を細かくみられる。変えられる。procfsというにたようなものもまだある。
Virturlization=仮想化 ひとつのコンピューターのなかでいくつものコンピューターを走らせることが出来る
 定番の機能だがカーネルで有効に、さらに仮想化用のCPU命令も有効にしないとものすごく遅くなるらしい
LILO = LInux LOader 起動時にカーネルを呼び出すブートローダー 今はあまり使われない
 ハードディスクのセクタにアクセスする単純なもの 設定が簡単だがカーネルを更新するたび再インストール
grub2 = 主流のブートローダー 
 ファイルシステムを理解するのでカーネルの再構築をやっても
 大体grub2自体は再インストールがいらない
 設定が面倒だが今のディストリビューションのスタッフはこれをこなす
if unsure = もし理解できなければ、同意できなければ じつはここでYを選べと書いてある機能もあり、重要
what you are doing = あなたが何をしているか 
 これは英語の警句で有り、自分がしていることが本当は何なのかしらなくてはいけないということ
 そうでなければ N を選べとか書いて有る

ところが、最近の機能に驚くべきものが有って
make localyesconfig
make localmodconfig
と言うのが有って、これを使うと今のカーネルの設定を読んで
今使っているモジュール、機能だけつぎも使える様にできます。
localyesconfigがカーネル組み込み、localmodconfigがモジュール化です。
でもUSBデバイスのドライバなんかはこの後全部モジュールにすると他人のや新品が使える。
たぶんUSBやFirewire、SDでつかうデバイスのドライバーは絶対使わないと思っているのを除いて全部いれておいたほうがいいです。

前のカーネルのコンフィグを継承するには
カーネルソースの.configを新しいのに写して
$ make oldconfig
新しい機能をどうするか質問が出ます。C言語の入門プログラムみたいに一々質問してきます。

カーネルを再構築するならブートローダーの設定も重要です。
古いカーネルは残しておけるので、いざと言うときに役に立つのですが、
古いvmlinuzとinitrdは上書きされる前に名前を変更して(だいたいバージョン番号を後ろに付ける)ブートローダーに登録。
root=/dev/sda1というような呼び出しはもうobsolete。
root=UUID=という呼び出し方ならディスクドライブの固有IDを指定できるので、
何かの拍子にsda1がsdb1になるような心配はいりません。

怖いけどやってみたい人、自己責任ならいいですよ。
そうして再起動しなくなったり基本的な機能が駄目になったりして
また再構築して理解が広まります。
Linuxの命が何なのか分かります。パソコンに関する広範な知識が得られます。
でも普通にLinuxが動いてくれないパソコンで再構築はおすすめしません。
予備のカーネルまで起動しなくなったら、KNOPPIXなんかのCDのlinuxからchrootとか使ってまた修復か再構築。大変です。