環境構築: Linux Kernelモジュールの作成準備

前書き

本記事は、「Linux Kernel Device Driverの雛形作成」や「Linux Kernel内APIを試すためのモジュール作成」を目的として、最低限必要な環境構築手順を記載しています。

          

開発環境

              

Linux Kenelモジュールとは

Linux Kernelモジュールとは、Linux Kenelの機能を拡張するためのオブジェクトファイル(*.koファイル)です。特徴として、Linuxの起動後に、動的にLoad/Unloadできます。イメージとしては、アプリケーションのPluginと同等です。

Linux Kernelは、機能拡張方法が2つあります。

拡張方法
  • Kernelのビルド時に機能を組み込む方法
  • Kernel起動後に*.koファイルを動的に読み込む方法

前者では、Linux Kernelのビルド前に.configファイル(ビルド設定ファイル)を編集し、必要な機能を予め取捨選択します。利点は実行時のオーバヘッドが少ない事で、欠点は組み込んだ機能を未使用でもその機能分のメモリを消費してしまう事です。この方法は、Kernelに必須な機能(メモリマネージメント等)に用いられる事が多いです。

後者も、.configファイルを編集する点では、同様です。ただし、機能の必要・不要の設定ではなく、モジュール化フラグを設定します。利点は、機能が必要になったタイミングで*.koファイルをloadできる事で、欠点はload時にオーバヘッドがある事です。この方法は、デバイスドライバで用いられる事が多いです。

          

Linux Kernel開発に必須パッケージのinstall

Linux Kernelの開発(主にビルド)で必須なパッケージをinstallします。導入順番は、Linux Kernelヘッダ、ビルド時の依存パッケージです。今回は、ディストリビューション(Debian)が提供しているパッケージを用います。

          

Linux Kernelソースコードの取得

前述の手順で入手したLinux Kernelヘッダと同じバージョンのLinux Kernelソースコードを取得します。取得したソースコードは、/usr/src以下にtarballで格納されます。具体的には、linux-source-<Version>.tar.xzが一時開発元オリジナルソースコード、その他のファイルがDebian独自のパッチです。詳細は、Debian公式サイトに記載されています。

          

Linux Kernelのビルド確認

Debian標準のLinux Kernelコンフィグ(.configファイル)を用いて、ビルド確認を行います。

手順
  1. Linux Kernelソースコードのtarballを展開
  2. 既存のLinux Kernelコンフィグファイル(.configファイル)をコピー
  3. Kernelに追加された新機能の有効・無効・モジュール化を設定
  4. ビルド

まず、Linux Kernelのソースコードが”/usr/src/linux-source-4.9.tar.xz”に存在するため、展開をします。展開先のディレクトリは任意です。今回はホームディレクトリ以下にKERNELディレクトリを作成し、その下にLinux Kernelソースコードを展開します。

既存のLinux Kernelコンフィグファイル(.configファイル)をコピーします。既存ファイルは、”/boot”以下に存在します。環境を複数回UPGRADE(“apt upgrade”)している場合、複数のコンフィグファイルが存在する事があります。その場合は、最新バージョンをコピーしてください。

Linux Kernelのビルド対象機能およびモジュール化対象機能を設定します。新機能以外は既存設定(Debian設定)と同じ、新機能はデフォルト(無効)とします。この設定には、”make oldconfig”コマンドで設定します(有効=Y/y、無効=N/n、モジュール化=m)。”make oldconfig”コマンド中の選択肢は、全てEnter(デフォルト)を押してください。

最後に、ビルドをします。ここでエラーが発生する場合は、パッケージなどが不足している可能性があります。

               

           

Linux Kernelモジュール(雛形)を作成・ビルド

Linux Kernelモジュールの雛形を作成します。作成するファイルは、ソースファイル(今回はtest_module.c)とMakefileです。ソース内容は、後ほど説明します。なお、Linux Kernelのコーディング規約の一つに、「Tabを使う事(size=8)」があります。基本的に私は、commitするわけではないため、この規約に従っていない場合があります。

ビルドするには、makeコマンドを叩くだけで、ビルド後の生成物の”test_module.ko”がKernelオブジェクトです。

                        

debimate_module.cの内容説明

まず、以下のMODULE_*の部分を説明します。

MODULE_LICENSEは、Kernelモジュールのライセンスを記載します。Kernelモジュールで使用できるライセンスは以下の通りで、Linux Kenerlソースコードの<KernelソースのTop Directory>/include/linux/module.hに記載があります 。

ライセンスに使用できる文字列 説明
GPL GNU Public License Version2(以下、GPLv2)か、それ以降のライセンス(GPLv3)
GPL v2 GPLv2
GPL and additional rights GPLv2およびその他の権利
Dual BSD/GPL BSDライセンスか、GPLv2
Dual MIT/GPL MITライセンスか、GPLv2
Dual MPL/GPL Mozillaライセンスか、GPLv2
Proprietary Freeではない(制約のある)製品向けのライセンス

ライセンスの必要性に関しては、以下のようにmodule.hに記載があります。2.と3.は、Linux Kernel Developerとベンダー企業の意見に対する折衷案のようですね。

1. So modinfo can show license info for users wanting to vet their setup is free
2. So the community can ignore bug reports including proprietary modules
3. So vendors can do likewise based on their own policies

[和訳]
1. modinfoコマンドは、ユーザの環境がFree(自由、無料)である事を確認したいユーザーのために、ライセンス情報を表示できます
2. コミュニティは、(修正範囲に)プロプラエタリモジュールを含むバグ報告を無視できます
3. ベンダーも同様に、自分の方針に基づいて活動できます

ちなみに、ライセンスを指定していないモジュールは、ビルドが通りません。以下に、ライセンス情報をコメントアウトした場合の、ビルド結果を示します。Warningとして、”missing MODULE_LICENSE()〜”が出ます。

MODULE_AUTHOR、MODULE_DESCRIPTIONは、見たままの内容です。前者には”モジュール作成者<メールアドレス>”を記載し、後者にはモジュールの機能説明を記載します。MODULE_INFOは、少し特殊です。第一引数に任意のラベルをつけ、第二引数にラベルに応じた内容(文字列)を記載します。

今回のソースコードでは、以下のようにモジュール情報が表示されます。

                                         

続いて、残りのコード(以下)を説明します。

debimate_init()、debimate_exit()は、KernelモジュールをLoad/Unload時に行う初期化・終了処理です。printk()はLinux Kernel内部用の出力関数です。printk()には出力レベルが存在します。出力レベル関しては、以下の記事を参照ください。

Linux Kernel: prink(print kernel)によるメッセージ出力

また、初期化関数に付与された__initマクロ、終了化関数に付与された__exitマクロは、メモリを効率使用するためのものです。初期化関数・終了関数が実行後、これらの関数はメモリから解放されます。細かい仕様は、以下の記事を参照ください。

Linux Kernel: __initマクロ、__exitマクロの役割(メモリの有効利用)

module_init()、module_exit()は、モジュールの初期化関数および終了関数を定義します。初期化関数を呼び出す仕組みはinitcallと呼ばれ、機能毎にモジュールを初期化するタイミングをずらせます。今回のKernelモジュール(module_init)は、device向けのタイミングで初期化されます。タイミングは以下の8種類です。

  1. early
  2. core
  3. postcore
  4. arch
  5. subsys
  6. fs
  7. device
  8. late

            

KernelモジュールのLoad/Unloadを確認

Load時はinsmodコマンド、Unload時はrmmodコマンドを使用します。正しくLoad/Unloadができたかを確認するため、dmsegコマンドでKernelモジュールの初期化・終了時の文字列出力を見ます。以下に、Load、Unloadの順番で実行結果を示します。

以上が、Kernelモジュール開発の作成準備になります。上記のコードを発展させ、Device Driverを作成したい場合は、以下の記事を確認して下さい。

Linux Kernelの簡単なCharacter Deviceを作成する方法(Linked List APIの使用方法サンプル)

                             

       

おすすめ

1件の返信

  1. 2019年7月15日

    […] 過去の記事(環境構築: Linux Kernelモジュールの作成準備)では、 […]