🐧 Linux 総合学習プラットフォーム
OS内部/起動の仕組み ・ 上級

カーネルモジュールの管理(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 Module Size Used by nf_tables 172032 3 nft_chain_nat,nft_counter,nft_ct nft_chain_nat 28672 1 nf_tables Used by の列を見ると、nf_tables が他の複数モジュールから使われていることが分かる。この依存の向きを正しく読めるかどうかが、後で説明する modprobe の挙動を理解するカギになる。
ModuleSizeUsed bynf_tables1720323 nft_chain_natnft_chain_nat286721 nf_tablesUsed by が他モジュールへの依存を示す

lsmod は「今なにが載っているか」を教えてくれるが、各モジュールが何者で、どんな設定が可能かまでは分からない。そこで使うのが modinfo だ。lsmod で気になる名前を見つけたら、次に modinfo で素性を掘り下げる、という2段構えで調べる癖をつけておくと調査が速くなる。

modinfo モジュール名 を実行すると、バージョン・説明・ライセンス・依存モジュール(depends)・設定可能なパラメータ(parm)などがまとめて表示される。トラブル対応でまず読むべき素性書だと考えるとよい。

$ modinfo nf_tables filename: /lib/modules/6.8.0-generic/kernel/net/netfilter/nf_tables.ko license: GPL depends: nfnetlink depends の行は、このモジュールを読み込む前に何が必要かを示している。この依存関係を手作業で追いかけずに済ませてくれるのが、次に説明する modprobe だ。
コツmodinfo -p モジュール名 と打てば、そのモジュールに渡せるパラメータだけを絞り込んで確認できる。ドライバの動作を細かく調整したいときに役立つ。

⚙️ modprobe で安全に出し入れする

モジュールを読み込む・外す操作には、実は2段階のコマンドがある。ひとつは依存関係を自動で解決してくれる modprobe、もうひとつは単体のモジュールだけを素朴に扱う insmod・rmmod だ。どちらも最終的にはモジュールを出し入れするという点では同じだが、依存を追いかけてくれるかどうかで手間がまったく違う。

$ sudo modprobe nf_tables $ sudo modprobe -r nf_tables 前者のように modprobe に名前だけを渡せば、依存先の nfnetlink が未ロードの場合は先にそれを読み込んでから nf_tables を載せてくれる。読み込む順番を人が気にする必要がない。後者のように -r を付けると取り外しになるが、他のモジュールから使われている、つまり Used by が1以上の状態では、依存関係を壊さないようエラーになって外れない。
つまずきinsmod は指定した .ko ファイルをそのまま読み込むだけで、依存モジュールが足りなくてもエラーを返すだけで自動補完はしない。rmmod も同様に単体のアンロードしかできない。依存関係を意識するなら modprobe を使うのが基本、と覚えておくとよい。
modprobe依存を自動解決依存モジュールも順に読み込みnfnetlink → nf_tablesinsmod / rmmod依存は解決しない指定した1個だけを素朴に処理不足時はエラーで停止日常運用は modprobe、単体テストは insmod/rmmod

実務では insmod・rmmod は、自分でビルドしたばかりの単一モジュールをその場で試したいときなど、限られた場面で直接使うことが多い。日常の運用では依存解決してくれる modprobe に軍配が上がる。両者の使い分けを整理すると、開発中の一時的な検証はinsmod・rmmod、普段の運用はmodprobe、というのが実務での基本的な線引きになる。

🚀 起動時に自動で読み込ませる仕組み

毎回手でロードしなくても、起動時に必要なモジュールが自動で読み込まれる仕組みが2つ用意されている。ひとつは明示的なリスト指定、もうひとつはハードウェア接続をきっかけにした自動検出だ。組込み機器の開発では、この2つを正しく使い分けられるかどうかで初期化の安定性が大きく変わる。

/etc/modules-load.d/ 以下に .conf ファイルを置き、1行に1つずつモジュール名を書いておくと、起動時にその一覧がまとめて読み込まれる。明示的に「必ず載せたいモジュール」を指定する方法で、I2CやSPIのように、基板に直結していて着脱の概念がないデバイス向けの指定によく使われる。

$ cat /etc/modules-load.d/i2c.conf i2c-dev この1行を用意しておくだけで、起動のたびに i2c-dev モジュールが自動的に読み込まれるようになる。ファイル名自体は用途を示す任意の名前でよく、拡張子が .conf であることだけが要件だ。

一方、USBメモリやWi-Fiアダプタのように後から挿すハードウェアは、udev がデバイスの接続を検知し、対応するモジュールを動的に modprobe する。利用者が意識しなくても適切なドライバが自然と載る仕組みで、挿した瞬間にデバイスファイルが現れるあの体験を裏側で支えている。

🚫 ブラックリストで読み込ませない

逆に「このモジュールは自動で読み込ませたくない」場面もある。特定のドライバが不具合を起こす、意図しないハードウェアが誤検出される、複数のドライバ候補のうち片方だけを使いたい、といった状況だ。この指定をブラックリスト化と呼ぶ。

$ cat /etc/modprobe.d/blacklist-pcspkr.conf blacklist pcspkr blacklist に続けてモジュール名を書くと、自動ロードの対象から外れる。ただし他のモジュールから明示的に modprobe された場合や、依存として必要になった場合は、それでも読み込まれる点に注意する。ブラックリストはあくまで「自動では読ませない」指定であり、強制的な禁止ではない。
起動 orデバイス接続modules-load.dまたは udev 検出blacklist に載っているか判定載っていない→読込載っている→自動読込skip
つまずき設定ファイルの正確な置き場所や書式の細部はディストリビューションやバージョンによって差がある。実機で設定する際は、使用中のディストリビューションの公式ドキュメントで最新の作法を確認してほしい。

ここまでの内容は、あくまで「すでにあるモジュールを観察し、出し入れする」という利用者側の視点だった。lsmod・modinfo・modprobe を使いこなせるようになると、起動ログでモジュール絡みのエラーが出たときも、どの段階でつまずいているかを落ち着いて切り分けられるようになる。

モジュールの出し入れという操作そのものは、この先デバイスドライバのトラックで学ぶ「自分でドライバを書いて .ko を作る」という話に地続きでつながっていく。lsmod・modinfo・modprobe で既存モジュールを観察できるようになったら、次は中身を書く番だ。

この項目に出てくる用語

カーネルオブジェクトかーねるおぶじぇくと
拡張子 .ko を持つ、カーネルモジュールの実体となるバイナリファイル。
モジュール自動読み込みもじゅーるじどうよみこみ
起動時やデバイス接続時に、必要なカーネルモジュールを人手を介さず読み込む仕組み。
モジュールブラックリストもじゅーるぶらっくりすと
特定のカーネルモジュールを自動読み込みの対象から外す設定。
カーネルモジュールかーねるもじゅーる
あとからカーネルに着脱できる拡張機能。多くのドライバはこの形。

関連コマンド

lsmodmodinfomodprobeinsmodrmmod

▶ 学習アプリでこの続きを学ぶ・演習する