コンピューター上でUbuntuを動かすために必要になるLinuxカーネルは、Ubuntuにおいてもっとも重要なコンポーネントです。今回はそんなLinuxカーネルとUbuntuの関係について説明します。
Ubuntuカーネルのことを知ろう
Ubuntuは「Linuxカーネル 」を使ったLinuxディストリビューションの1つです。どのようなマシンのうえでUbuntuが動作するか、どのようなデバイスをUbuntuで使えるかは、ひとえにカーネルに懸かっているために、Ubuntuではサポート期間やサポート対象、導入する新機能などを考慮したうえで、LinuxカーネルにUbuntu独自の変更を加えてリリースしています。
たとえば、現在Ubuntuで使われているカーネルのバージョンは、次のコマンドで確認できます。
$ uname -rv
3.8.0-25-generic #37-Ubuntu SMP Thu Jun 6 20:47:07 UTC 2013
カーネルとパッケージのバージョン
「半年ごと」というUbuntuのリリーススケジュールの関係で、Ubuntuの最新版で使われるカーネルのバージョンは「リリースの2ヵ月前ぐらいの最新版」になります。たとえば、2013年4月にリリースされたUbuntu 13.04で採用しているLinuxカーネルは、2013年2月にリリースされた3.8です[1] 。
unameコマンドの結果を見ると「3.8.0-25-generic」と表示されていることがわかります。さらに実際にインストールされているパッケージ名は次のコマンドで確認できます。
$ dpkg -l | grep linux-image
ii linux-image-3.8.0-19-generic 3.8.0-19.30 amd64 Linux kernel image for version 3.8.0 on 64 bit x86 SMP
ii linux-image-3.8.0-23-generic 3.8.0-23.34 amd64 Linux kernel image for version 3.8.0 on 64 bit x86 SMP
ii linux-image-3.8.0-25-generic 3.8.0-25.37 amd64 Linux kernel image for version 3.8.0 on 64 bit x86 SMP
ii linux-image-extra-3.8.0-19-generic 3.8.0-19.30 amd64 Linux kernel image for version 3.8.0 on 64 bit x86 SMP
ii linux-image-extra-3.8.0-23-generic 3.8.0-23.34 amd64 Linux kernel image for version 3.8.0 on 64 bit x86 SMP
ii linux-image-extra-3.8.0-25-generic 3.8.0-25.37 amd64 Linux kernel image for version 3.8.0 on 64 bit x86 SMP
ii linux-image-generic 3.8.0.25.43 amd64 Generic Linux kernel image
カーネルバージョン「3.8.0-25-generic」に該当するパッケージの名前は「linux-image-3.8.0-25-generic」で、パッケージ自体のバージョンは「3.8.0-25.37」です。ここからカーネルのバージョンが「3.8.0」であるように見えますが、実際に使われているカーネルのバージョンと一致するのは「3.8」の部分だけです。安定版のリリース番号に相当する数字はここにはあらわれません[2] 。
バージョンの「25.37」のうち、最初の数字は3.8ベースのカーネルパッケージをリリースしてから、「 ABI(Application Binary Interface)が変更された回数」をあらわします。また、後ろの数字は「アップロード回数」をあらわします。「 25.37」であれば、3.8ベースのカーネルパッケージを最初にリリースしてから、「 25回のABIの変更が発生し、37回アップロードされた」ことを意味します。アップロード後にビルドされたあと、テストの段階で問題が見つかり、結局リリースされずにさらにABIの変更が発生するというケースもありますので、リポジトリにあるパッケージの数字が連続になるとは限りません。
Ubuntuの場合、一度リリースされると基本的に同じバージョンのカーネルを使い続けます。たとえば13.04で使用しているLinux 3.8は「3.8.13」のリリースによって、End Of Lifeを迎えました 。しかし13.04は2014年1月までサポートを続ける必要があります[3] 。そこでUbuntuでは、リリース後の安定版のアップデートに追随するとともに、その後EOLを迎えたカーネルであっても、Ubuntuのサポート期間の間はメインラインカーネルのセキュリティパッチや変更を取り込む形で対応しています。
そのため、Ubuntuのカーネルパッケージの更新回数と安定版のリリース回数は一致しません。現在のカーネルが、どの安定版のリリースまでの変更を取り込んでいるかは、次のコマンドで確認できます。
$ cat /proc/version_signature
Ubuntu 3.8.0-25.37-generic 3.8.13
さらに特筆すべきは、ABI番号が「パッケージ名」に含まれているために、ABIの変更を伴うカーネルは「新しいバージョン」ではなく「別パッケージ」として提供されているということです。これにより、アップデート後であっても古いカーネルをローカルストレージに残しておくことができます。たとえば、ABIの変更によって起動できなくなったとしても、ブートローダーで古いカーネルを選択すればとりあえず起動させることができるのです。
[1] 6ヵ月にわたる開発の初期段階で、Linuxカーネルのリリース時期をある程度予想したうえで、どのバージョンを使うかが仮決定されます。開発期間中はそのバージョンのRC版(存在しなければその1つ前の版)を使いつつ、不具合を洗い出して対応していくことになりますので、だいたいUbuntuのリリースより数ヵ月前にリリースされたものを使うことになります。ただし新機能の内容や次がLTSかどうかによって、多少の差はあります。
[2] カーネル2.6の頃は「2.6.x」までがカーネルのバージョンで、その後ろに安定版のリリース番号がついて「2.6.x.y」という形になっており、Ubuntuは「2.6.x」ベースのカーネルを使っていることを示すために最初の3桁をパッケージ名とバージョンに含んでいました。「 3.x.y」という表記になっても、「 パッケージバージョンの場合はyの部分は常に0」という形でこの書式が残っているようです。
カーネルフレーバー
パッケージ名やカーネルバージョン「3.8.0-25-generic」にあらわれる「generic」をUbuntuでは「フレーバー(Flavour) 」と呼びます。
カーネルには多種多様なConfigオプションがあり、コンピュータの用途によってオプションを変えたほうが利便性が高くなります。そのため、Configオプションを含めた用途の違うカーネルを「フレーバー」としてUbuntuは提供しているのです。たとえば以前は用意されていたPAEカーネル も、フレーバーの一種です。
既存のフレーバー一覧はWikiで確認することができます 。ただし、Ubuntu 13.04の場合、x86 CPUでメインで使えるフレーバーは「generic」だけです。過去にはサーバ用の「server」や、仮想マシン上やクラウド環境上で使う「virtual」もありましたが、メンテナンスコストの問題から徐々に統合されていきました[4] 。
唯一残っているのが、Ubuntu Studioで使われている「lowlatency」フレーバーです。しかしながらこのカーネルはUniverseであり、genericと比べると更新は遅れがちです。日常的な用途には使えないでしょう。リアルタイム性も含めたlowlatencyフレーバーについての詳しいことは、Wikiを参照してください 。
ARMカーネルの場合は、SoCによってベースとすべきカーネルツリーが異なることから、SoCごとにフレーバーがある状態です。ただし、13.04になってhighbankフレーバーがgenericに統合されるなど、少しずつ状況は変わってきています。
Hardware Enablement(HWE)
Ubunutu 12.04 LTSは5年間のサポートが行われる長期サポート版です。より新しいハードウェアでもLTSを使えるように、もしくは既存のカーネルを使い続けられるように、HWEと後述のLBMという特殊な仕組みが用意されています。
HWE(Hardware Enablement)カーネルは、より新しいハードウェアでもLTSを使えるように用意されている「LTS Enablement Stacks 」のカーネルです。簡単に言うと、LTS以降にリリースされたUbuntuで使われるカーネルを、LTSでも使えるようにしたものです。たとえば、Ubuntu 12.04 LTS以降では、現時点でLinuxカーネル3.5を使っている12.10(quantal)とLinuxカーネル3.8を使っている13.04(raring)がリリースされています。これらのバージョンのカーネルをLTSでも使えるようにしたのがHWEカーネルです[5] 。
利用可能なHWEカーネルは次のコマンドで確認できます。
$ apt-cache search linux-generic-lts
linux-generic-lts-quantal - Generic Linux kernel image and headers
linux-generic-lts-quantal-eol-upgrade - Complete Generic Linux kernel and headers
linux-generic-lts-raring - Generic Linux kernel image and headers
linux-generic-lts-raring-eol-upgrade - Complete Generic Linux kernel and headers
ただし、HWEカーネルを使いたいだけであれば、上記をインストールするのではなく、「 linux-hwe-generic」パッケージをインストールしてください[6] 。このメタパッケージをインストールしておけば、適切なバージョンのパッケージを選択してインストールしてくれます。
LTSのポイントリリース[7] であるUbuntu 12.04.2がリリースされた時点での「linux-hwe-generic」は、12.10のカーネルをインストールします。将来的にUbuntu 12.04.3がリリースされるころには「linux-hwe-generic」は13.04のカーネルをインストールするようになる予定です[8] 。
HWEカーネルはUbuntu 12.04 LTSのポイントリリース時のインストールCDイメージの標準カーネルにもなります。Ubuntu 12.04リリース直後のCDイメージを使ってインストールした環境は、手動でHWEカーネルへの移行を行わなければポイントリリースを経たあともLinuxカーネル3.2を使い続けます。それに対して、12.10のHWEカーネルが用意された12.04.2のインストールCDを使った場合は「linux-hwe-generic」が指定する「linux-generic-lts-quantal」を標準のカーネルとして使うのです。
[6] linux-hwe-genericはカーネルイメージだけでなく、たとえば後述のDKMSなどで使用するカーネルヘッダーも一緒にインストールします。HWEカーネルのイメージだけインストールしたい場合は、「 linux-image-hwe-generic」を直接指定すると良いでしょう。
カーネルとの健全なお付き合い
Ubuntuが動いているということは、つまりカーネルが動いているということです。よってユーザはUbuntuと同じ時間、カーネルとも付き合うことになります。「 より良いお付き合い」をするためにも、日々の作業で何かあったときに役に立ちそうな情報を把握しておきましょう。
カーネルのアップグレード
カーネルに限らずパッケージのアップグレードは重要です。デスクトップユーザーであれば「ソフトウェアの更新」が表示されたら、できるだけ早い段階で更新を適用しましょう。カーネルがアップグレードされる場合も、同じ手順で問題ありません。カーネルが更新されたときは再起動も促されるので、その指示に従ってください[9] 。
図1 再起動が必要な場合は、更新後にこのようなダイアログが表示される
CUIからアップグレードするユーザの場合は注意が必要です。カーネルのABIが変更されたときは、よく使う「apt-get upgrade」ではカーネルのアップグレードをできないのです。これは「upgrade」コマンドがパッケージの更新を行うのに対して、ABIの変更時は前述のとおりパッケージ名が変わることから、「 新しいパッケージの追加」が必要になるためです。
コマンドラインからカーネルのABIの変更を伴うアップグレードを行う場合は、次のように「dist-upgrade」コマンドを実行します。
$ sudo apt-get update
$ sudo apt-get dist-upgrade
アップグレードが完了したら、やはり再起動を行ってください[10] 。
[9] アップグレードを実行する「前に」再起動が必要かどうかを通知してくれる手段は今のところ存在しません。再起動が必要なパッケージに対しては、パッケージのメタデータにその旨を記述して、「 ソフトウェアの更新」から再起動が必要かどうかを事前に判断する 仕組みを作る話は存在しますので、将来的には実装されるかもしれません。
[10] カーネルに限らずアップグレードすることで再起動が必要になるパッケージは、インストール後の処理によって、/var/run/reboot-requiredに「システムの再起動が必要です」というメッセージが、/var/run/reboot-required.pkgsに再起動を要求するパッケージのリストが追記されます。Ubuntuの場合は、MOTDに/var/run/reboot-requiredを出力しますし、byobuを使っているとステータスラインの右下に再起動要求アイコンが表示されます。
古いカーネルの削除
dist-upgradeで新しくカーネルパッケージを追加し、起動も問題なく行えることを確認できたら、古いカーネルパッケージは不要になります。個別にパッケージ名を指定してアンインストールすることも可能ですが、「 autoremove」コマンドを使うことで、不要になったカーネルパッケージを一括削除できます。
$ sudo apt-get autoremove
パッケージリストを読み込んでいます... 完了
依存関係ツリーを作成しています
状態情報を読み取っています... 完了
以下のパッケージは「削除」されます:
linux-headers-3.2.0-41 linux-headers-3.2.0-41-generic linux-image-3.2.0-41-generic
アップグレード: 0 個、新規インストール: 0 個、削除: 3 個、保留: 0 個。
この操作後に 217.2 MB のディスク容量が解放されます。
続行しますか [Y/n]?
autoremoveで削除されるのは、原則としてアップグレード時点で使用中ではなく、最新でもないカーネルです。少なくとも、2つのバージョンは削除せずにそのまま残すようになっています。autoremoveされないカーネルのバージョンは、/etc/apt/apt.conf.d/01autoremove-kernelsファイルで確認できます。このファイルはカーネルのインストールやアップグレードごとに、自動的に生成されます。
カーネルの削除は、とくにUbuntu ServerでLVMを使用する場合は注意が必要です。標準のパーティションレイアウトだと/bootが256Mバイト程度の別パーティションとして設定されます。カーネルはデータサイズが大きく、古いカーネルが残ったままだと10回ぐらいのアップグレードで/bootを使いきってしまいます。不要なカーネルを定期的に削除する習慣を付けておきましょう。
ちなみに、自動的なアップグレード(Unattended Upgrade )を有効にしている場合、自動的にアップグレードされたカーネルはautoremoveによる自動削除の対象にならない不具合 が存在します[11] 。自動的なアップグレードを使っている場合は、面倒ではありますが手動で不要になったカーネルパッケージを削除してください。
[11] autoremoveは、apt-getコマンドでインストールしたとき、依存関係に従って間接的にインストールされたパッケージ(autoマークが付いているパッケージ)のうち、依存関係上必要なくなったパッケージのみを削除します。インストールする対象に直接指定したパッケージ(manualマークが付いているパッケージ)は削除の対象としません。言い換えると、autoremoveで削除されたくないパッケージがあるなら、インストール後であっても明示的に「sudo apt-get install パッケージ名」を実行することで、autoからmanualへマークを変更することができます。今回の不具合は、自動的なアップグレードでインストールされたパッケージは、常にmanualマークが付いたままになるというものです。ちなみにautoマークが付いているパッケージ一覧は「apt-mark showauto」で、manualマークが付いているパッケージ一覧は「apt-mark showmanual」で確認できます。
カーネルモジュールの更新
ハードウェアの種類によっては、デバイスドライバとして別途カーネルモジュールを要求することがあります。Linuxカーネル付属のモジュールであればカーネルパッケージと一緒にインストールされますし、プロプライエタリなグラフィックスドライバのようなサードパーティのモジュールであれば別途パッケージが用意されるか、自分でビルドしてインストールする必要があります。
これらのカーネルモジュールは、カーネルの更新によってABIが変更されたときは、その変更に追随するようリビルドする必要があります。Linuxカーネル付属のモジュールなら、カーネルの更新に合わせて、ビルド済みモジュール一式も提供されるので注意する必要はないでしょう。
サードパーティのモジュールについてはカーネルの更新後にリビルドを行う必要があります。といっても、アップグレードがあるたびに逐一「make; sudo make install」とするのは不便ですし、数が増えると作業漏れも発生するかもしれません。そこでこの作業を自動化するために「DKMS(Dynamic Kernel Module Support) 」システム用意されています。DKMSに対応すると、カーネルパッケージが更新されるたび、その直後にDKMS対応のモジュールを一通りリビルドしてくれます。
リポジトリにあるグラフィックスドライバパッケージなどはDKMSに対応済みです。パッケージがDKMSに対応しているかどうかは、dkmsパッケージに依存しているかどうかで判断すると良いでしょう。もし自分が使っているカーネルモジュールをDKMSに対応させたい場合は、DKMSのドキュメント を参照してください。
無線LANデバイスのような、入れ替わりの激しいデバイスについては、「 新しいLinuxカーネルのソースツリーに含まれるモジュール」をより古いカーネルでもビルドして使いたい場合があるでしょう。そのような要望のために、LTSにはLBM(Linux Backports Modules)と呼ばれるモジュールパッケージが存在します[12] 。
Ubuntu 12.04 LTS上で「apt-cache search linux-backports-modules」で検索すると大量のパッケージが引っかかるかと思います。おもな命名規則は次のとおりです。
linux-backports-modules-(モジュール名)-(ベースカーネル)-(LTSカーネル)-(フレーバー)
モジュール名は「cw(compat-wireless、無線LAN) 」や「net(Ethernetカード) 」などが存在します。ベースカーネルが新しいカーネル側のバージョンで、LTSカーネルとフレーバーが現在使っているカーネルのバージョンとフレーバーになります。ベースカーネルについては、モジュールによっては省略されます。たとえば、「 linux-backports-modules-cw-3.8-3.2.0-43-generic」は「3.8カーネルの無線LANモジュールを、3.2.0-43パッケージのgenericフレーバー用にビルドしたもの」と解釈できます。
ただし、LTSカーネル部分はカーネルの更新によって値が変わるので、LBMを使う場合は上記のパッケージではなく、最新のLTSカーネルを指している「linux-backports-modules-cw-3.8-precise-generic」などをインストールするようにしてください。
カーネルのサポート期間
Ubuntuのmainコンポーネントに含まれるパッケージは、LTSで5年、LTSでないものだと9ヵ月サポートされます。Ubuntuカーネルは基本的にmainコンポーネントに属することになるので、上記と同じサポート期間となるのですが、LTSについては一部例外が存在します。
まずGAカーネルについては、「 最新のバージョンのみ5年サポート」です。「 カーネルとパッケージのバージョン」で説明したように、カーネルのABIが変更されるとカーネルのパッケージ名が変更されます。このとき、5年サポートの対象になるのは、ABIが更新された後のパッケージのみとなります。
たとえば、Ubuntu 12.04 LTSの現在の最新版は、2013年6月6日にリリースされた「3.2.0-48」で、その前のバージョンは2013年5月29日にリリースされた「3.2.0-45」になります。この2つのパッケージのサポート期間を、apt-cacheコマンドで確認してみましょう。
$ apt-cache show linux-image-3.2.0-48-generic | grep Supported
Supported: 5y
$ apt-cache show linux-image-3.2.0-45-generic | grep Supported
Supported: 18m
次にHWEカーネルについては、「 元になったリリースのサポート期間に準じる」ことになります。12.10のカーネルである、linux-image-generic-lts-quantalはLTSであっても18ヵ月のサポートです[13] 。最新のHWEカーネルを指定するlinux-image-hwe-genericは5年サポート表示になっていますが、これは将来的に指定する先がlinux-image-generic-lts-quantalからより新しいカーネルへと切り替わることが見込まれているためです。
$ apt-cache show linux-image-generic-lts-quantal | grep Supported
Supported: 18m
$ apt-cache show linux-image-hwe-generic | grep Supported
Supported: 5y
このように古くなったカーネルはたとえLTSのリポジトリに存在していても、サポート期間がLTSではないパッケージと同じになります。また、原則としてセキュリティパッチは新しいカーネルのみに適用されるので、古いカーネルを使い続けることは避けるようにしましょう。
[13] HWEカーネルはポイントリリースの標準カーネルになる都合上、実際は次のLTSである14.04のリリースまでサポート対象になるかもしれません。また、14.04以降のLTSではGAカーネルのサポート期間を短くして、自動的にHWEに切り替えるという話もあります。
メインラインカーネルとの違い
Ubuntuカーネルは、上流であるLinuxのメインラインカーネルにUbuntu独自のパッチを適用したり、Ubuntuで必要となるようなconfigオプションを変更したものです。では、メインラインカーネルとはどのように異なっているのでしょうか。カーネルチームのドキュメントには、リリースごとのUbuntu独自の変更点(Ubuntu Delta) が一覧としてまとまっています。
たとえば13.04の場合 、リリース直前の状態だと全体で521個のパッチがあたっており、そのうちカーネルのソースコードを変更するパッチ(SAUCEパッチ)は290個でした[14] 。カーネルコンフィグも、リリースごとにレビューを行なっています 。
[14] 「SAUCE」はカーネルに対する変更、「 no-up」はアップストリームで却下された変更、などUbuntuカーネルのコミットログには、いくつかの書式が存在します。リリースごとの変更点を読むうえでも参考になりますので、Ubuntu Deltaのページ にあるパッチの種類一覧には一通り目を通しておいたほうが良いでしょう。
問題に遭遇したら
Ubuntuを使っていると、Ubuntuカーネルに起因する問題に遭遇することがあるかもしれません。現象や要因がある程度絞りこめているのであれば、不具合として報告しましょう。
$ ubuntu-bug linux
いくつかの質問に答えると、現在の環境の情報が収集され、Webブラウザが立ち上がり[15] 、Webフォームからタイトルと概要を入力することで報告完了です[16] 。
Webフォームでは似たようなタイトルの不具合がリストアップされるので、報告済みかどうか確認しましょう。また、あらかじめGoogleを使って、「 キーワード site:bugs.launchpad.net」と検索しておくと、報告済みの内容や運が良ければ解決策も含めて見つかるかもしれません。
不具合の概要は、「 再現手順(How to reproduce) 」 「 期待される動作(Expected result) 」 「 実際に起こった動作(Actual result) 」などを明示するようにしましょう。
もしカーネルがクラッシュした場合は、/var/crashにクラッシュダンプが残っていることがあります。それも併せて送信すると、より解決が近くなります。
$ apport-collect -p linux (チケット番号)
最後の「チケット番号」は、ubuntu-bugコマンドで登録したチケット番号を指定します。
もし、自力で問題を解決したい場合は、クラッシュダンプの解析方法 や、ケースごとの参考文献のリスト 、カーネルのバージョンを切り替えつつ問題を絞り込む手順 などが参考になるでしょう。
[16] ubuntu-bugもapport-collectも、ハードウェア情報や各種ログ、クラッシュダンプの場合はダンプファイルなどの情報をサーバに送信します。それが本当に送信して良い情報かどうかは各自で判断するようにしてください。どちらのコマンドも送信する前に送信データをローカルにapportの形式で保存できます。apport-unpackコマンドを使えば中身を確認できるので、まずはどんなデータが送られるか見ておくと良いでしょう。
カーネルに関する情報
今回説明した内容のほとんどは、Kernel情報のページ もしくはKernelチームのページ に掲載されています。Ubuntuカーネルについて調べたいことがあれば、まずはこれらのページを訪れると良いでしょう。さらに、カーネルチームは定期的にミーティングを行い、その結果をKernelチームのML(流量多め) やブログ に報告しています。
Ubuntuカーネルのソースコードは、他のUbuntuプロジェクトと異なり、アップストリームに合わせてgitで管理されています 。数多くのプロジェクトが表示されますが、公式のUbuntuカーネルは「ubuntu/ubuntu-コードネーム.git」なので、すぐに見つかるでしょう。もし、自分でカーネルをビルドしたい場合は、このリポジトリとドキュメントを参考に チャレンジしてみてください。