GNU/Linux >> Linux の 問題 >  >> Linux

簡単な例で独自の Linux カーネル モジュールを作成する方法

カーネルモジュールとは?

カーネル モジュールは、必要に応じてカーネルからロードおよびアンロードできるコードの一部です。

カーネル モジュールは、カーネルを再構築または再コンパイルすることなく、ベース カーネルの機能を拡張する簡単な方法を提供します。ほとんどのドライバは、Linux カーネル モジュールとして実装されています。これらのドライバーが不要な場合は、その特定のドライバーのみをアンロードできます。これにより、カーネル イメージのサイズが縮小されます。

カーネル モジュールには .ko 拡張子が付きます。通常の Linux システムでは、カーネル モジュールは /lib/modules//kernel/ ディレクトリ内にあります。

以前に、ソースからカーネルをコンパイルする方法について説明しました。

このチュートリアルでは、単純な Hello World の例を使用してカーネル モジュールを作成する方法について説明します。

I.カーネル モジュールを操作するユーティリティ

1. lsmod – すでにロードされているモジュールのリスト

lsmod コマンドは、以下に示すように、カーネルに既にロードされているモジュールを一覧表示します。

# lsmod
Module                  Size  Used by
ppp_deflate            12806  0 
zlib_deflate           26445  1 ppp_deflate
bsd_comp               12785  0 
..

2. insmod – モジュールをカーネルに挿入

insmod コマンドは、以下に示すように新しいモジュールをカーネルに挿入します。

# insmod /lib/modules/3.5.0-19-generic/kernel/fs/squashfs/squashfs.ko

# lsmod | grep "squash"
squashfs               35834  0

3. modinfo – モジュール情報を表示

modinfo コマンドは、以下に示すように、カーネル モジュールに関する情報を表示します。

# modinfo /lib/modules/3.5.0-19-generic/kernel/fs/squashfs/squashfs.ko

filename:       /lib/modules/3.5.0-19-generic/kernel/fs/squashfs/squashfs.ko
license:        GPL
author:         Phillip Lougher 
description:    squashfs 4.0, a compressed read-only filesystem
srcversion:     89B46A0667BD5F2494C4C72
depends:        
intree:         Y
vermagic:       3.5.0-19-generic SMP mod_unload modversions 686

4. rmmod – カーネルからモジュールを削除

rmmod コマンドは、カーネルからモジュールを削除します。既にプログラムで使用されているモジュールを削除することはできません。

# rmmod squashfs.ko

5. modprobe – カーネルからモジュールを追加または削除

modprobe は、モジュール間の依存関係に基づいてモジュールをロード/アンロードするインテリジェントなコマンドです。詳細な例については、modprobe コマンドを参照してください。

II.シンプルな Hello World カーネル モジュールを作成する

1. Linux ヘッダーのインストール

以下に示すように、最初に linux-headers-.. をインストールする必要があります。ディストリビューションに応じて、apt-get または yum を使用してください。

# apt-get install build-essential linux-headers-$(uname -r)

2. Hello World モジュールのソース コード

次に、C プログラミング言語で次の hello.c モジュールを作成します。

#include <linux/module.h>    // included for all kernel modules
#include <linux/kernel.h>    // included for KERN_INFO
#include <linux/init.h>      // included for __init and __exit macros

MODULE_LICENSE("GPL");
MODULE_AUTHOR("Lakshmanan");
MODULE_DESCRIPTION("A Simple Hello World module");

static int __init hello_init(void)
{
    printk(KERN_INFO "Hello world!\n");
    return 0;    // Non-zero return means that the module couldn't be loaded.
}

static void __exit hello_cleanup(void)
{
    printk(KERN_INFO "Cleaning up module.\n");
}

module_init(hello_init);
module_exit(hello_cleanup);

警告: すべてのカーネル モジュールは、高度な特権モードであるカーネル空間で動作します。そのため、カーネル モジュールに記述する内容には注意してください。

3.カーネル モジュールをコンパイルする Makefile の作成

次の makefile を使用して、上記の基本的な hello world カーネル モジュールをコンパイルできます。

obj-m += hello.o

all:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules

clean:
    make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean

以下に示すように、make コマンドを使用して、hello world カーネル モジュールをコンパイルします。

# make

make -C /lib/modules/3.5.0-19-generic/build M=/home/lakshmanan/a modules
make[1]: Entering directory `/usr/src/linux-headers-3.5.0-19-generic'
  CC [M]  /home/lakshmanan/a/hello.o
  Building modules, stage 2.
  MODPOST 1 modules
  CC      /home/lakshmanan/a/hello.mod.o
  LD [M]  /home/lakshmanan/a/hello.ko
make[1]: Leaving directory `/usr/src/linux-headers-3.5.0-19-generic'

上記により、サンプル カーネル モジュールである hello.ko ファイルが作成されます。

4.サンプル カーネル モジュールの挿入または削除

hello.ko ファイルができたので、以下に示すように insmod コマンドを使用して、このモジュールをカーネルに挿入できます。

# insmod hello.ko

# dmesg | tail -1
[ 8394.731865] Hello world!

# rmmod hello.ko

# dmesg | tail -1
[ 8707.989819] Cleaning up module.

モジュールがカーネルに挿入されると、module_init マクロが呼び出され、hello_init 関数が呼び出されます。同様に、モジュールが rmmod で削除されると、module_exit マクロが呼び出され、hello_exit が呼び出されます。 dmesg コマンドを使用して、サンプル カーネル モジュールからの出力を確認できます。

printk はカーネルで定義されている関数であり、IO ライブラリの printf と同様に動作することに注意してください。カーネル モジュールのライブラリ関数は使用できないことに注意してください。

これで、独自の Linux カーネル モジュールを作成するための基本を学びました。


Linux
  1. Linux カーネルモジュールのコーディング方法は?

  2. すべてのカーネル リリースと互換性があるように Linux カーネル モジュールをビルドするにはどうすればよいですか?

  3. .Net Core で Linux デーモンを作成する方法

  1. 例を使用してLinuxでRmmodコマンドを使用する方法

  2. Linux –どのモジュールがカーネルを汚染しているかを判断する方法は?

  3. Linux – Linuxの汚染されたカーネル?

  1. Linux –カーネルモジュールを適切にリロードする方法は?

  2. Linux でスレッドを作成する方法 (C サンプル プログラムを使用)

  3. LinuxでCでファイルを書く方法は?