カーネルモジュールの管理(lsmod・modprobe)
カーネルはすべての機能を最初から一枚岩で抱え込んでいるわけではなく、ドライバなどの部品を後から差し込める仕組みを持っています。この部品をカーネルモジュールと呼び、lsmod で読み込み済みの一覧を、modinfo で個々の素性を確認できます。読み込み・取り外しには modprobe を使うのが基本で、依存関係を自動で解決してくれる点が insmod・rmmod との大きな違いです。起動時の自動読み込みやブラックリスト化の仕組みまで押さえると、ドライバ周りのトラブルにも落ち着いて対処できるようになります。
カーネルは起動時にすべての機能を一枚岩として詰め込んでいるわけではない。ネットワークカードやファイルシステムへの対応など、必要な部品を後から差し込める仕組みを持っており、これをカーネルモジュールと呼ぶ。
この仕組みのおかげで、新しいUSB機器を挿すたびにカーネル全体を組み直したり、使わない機能を常時メモリに載せ続けたりせずに済む。必要なときだけ読み込み、不要になれば外せる柔軟さがモジュールの価値だ。組込み機器のように再起動を気軽にできない環境では、この柔軟さがそのまま運用のしやすさに直結する。
たとえば産業用の制御ボードで新しいセンサーを追加するとき、対応モジュールを1つ差し込むだけで済むなら、稼働中の他の処理を止めずに拡張できる。カーネル全体を作り直して再起動する運用と比べると、現場への影響の小ささは歴然としている。
🔌 モジュールという差し込み部品
モジュールの実体は拡張子 .ko(kernel object)のファイルで、多くのディストリビューションでは /lib/modules/カーネルバージョン/ 以下に格納されている。カーネルのバージョンごとにフォルダが分かれているのは、モジュールがそのカーネルに合わせてビルドされたバイナリだからだ。
この対応関係は意外と厳密で、あるバージョン用にビルドされたモジュールを別バージョンのカーネルへそのまま読み込ませようとすると、多くの場合は拒否される。カーネルを更新したときにドライバが読み込めなくなる現象は、たいていこの対応の食い違いが原因だ。
現在読み込まれているモジュールは、メモリ上に展開された一覧としてカーネルが管理している。この一覧を覗く窓口が /proc/modules であり、これから紹介する lsmod は、この中身を人が読みやすく整形して表示しているだけのコマンドにすぎない。
🔍 lsmod と modinfo で素性を知る
モジュール周りのトラブルシュートは、まず「今なにが載っているか」を確認するところから始まる。lsmod を実行すると、Module・Size・Used by の3列が並ぶ。Module は名前、Size はメモリ上の大きさ、Used by はそのモジュールに依存している他モジュールの数と名前を示す。
lsmod は「今なにが載っているか」を教えてくれるが、各モジュールが何者で、どんな設定が可能かまでは分からない。そこで使うのが modinfo だ。lsmod で気になる名前を見つけたら、次に modinfo で素性を掘り下げる、という2段構えで調べる癖をつけておくと調査が速くなる。
modinfo モジュール名 を実行すると、バージョン・説明・ライセンス・依存モジュール(depends)・設定可能なパラメータ(parm)などがまとめて表示される。トラブル対応でまず読むべき素性書だと考えるとよい。
⚙️ modprobe で安全に出し入れする
モジュールを読み込む・外す操作には、実は2段階のコマンドがある。ひとつは依存関係を自動で解決してくれる modprobe、もうひとつは単体のモジュールだけを素朴に扱う insmod・rmmod だ。どちらも最終的にはモジュールを出し入れするという点では同じだが、依存を追いかけてくれるかどうかで手間がまったく違う。
実務では insmod・rmmod は、自分でビルドしたばかりの単一モジュールをその場で試したいときなど、限られた場面で直接使うことが多い。日常の運用では依存解決してくれる modprobe に軍配が上がる。両者の使い分けを整理すると、開発中の一時的な検証はinsmod・rmmod、普段の運用はmodprobe、というのが実務での基本的な線引きになる。
🚀 起動時に自動で読み込ませる仕組み
毎回手でロードしなくても、起動時に必要なモジュールが自動で読み込まれる仕組みが2つ用意されている。ひとつは明示的なリスト指定、もうひとつはハードウェア接続をきっかけにした自動検出だ。組込み機器の開発では、この2つを正しく使い分けられるかどうかで初期化の安定性が大きく変わる。
/etc/modules-load.d/ 以下に .conf ファイルを置き、1行に1つずつモジュール名を書いておくと、起動時にその一覧がまとめて読み込まれる。明示的に「必ず載せたいモジュール」を指定する方法で、I2CやSPIのように、基板に直結していて着脱の概念がないデバイス向けの指定によく使われる。
一方、USBメモリやWi-Fiアダプタのように後から挿すハードウェアは、udev がデバイスの接続を検知し、対応するモジュールを動的に modprobe する。利用者が意識しなくても適切なドライバが自然と載る仕組みで、挿した瞬間にデバイスファイルが現れるあの体験を裏側で支えている。
🚫 ブラックリストで読み込ませない
逆に「このモジュールは自動で読み込ませたくない」場面もある。特定のドライバが不具合を起こす、意図しないハードウェアが誤検出される、複数のドライバ候補のうち片方だけを使いたい、といった状況だ。この指定をブラックリスト化と呼ぶ。
ここまでの内容は、あくまで「すでにあるモジュールを観察し、出し入れする」という利用者側の視点だった。lsmod・modinfo・modprobe を使いこなせるようになると、起動ログでモジュール絡みのエラーが出たときも、どの段階でつまずいているかを落ち着いて切り分けられるようになる。
モジュールの出し入れという操作そのものは、この先デバイスドライバのトラックで学ぶ「自分でドライバを書いて .ko を作る」という話に地続きでつながっていく。lsmod・modinfo・modprobe で既存モジュールを観察できるようになったら、次は中身を書く番だ。