2025
01
18
2012
02
26
カーネルモジュールのコンパイル環境を整える(Scientific Linux 6.2)
カーネルモジュールをコンパイルするためには、Linuxのソースコードが必要&適切なパスの場所に ソースコードを展開しなければいけない。 書きだしてみると結構面倒。。
注意
HDD15GB程度だとカーネルコンパイル時に容量が足りなくなりました
手順
#1 再構築に必要なパッケージをインストール (rpmdev-setuptreeのため) yum install rpmdevtools yum-utils #2 パッケージ再構築の準備 (rpmbuildディレクトリを正しく作るため) # ホームディレクトリの中にrpmbuildディレクトリが作成される。 # BUILD RPMS SOURCES SPECS SRPMS rpmdev-setuptree ls ~/rpmbuild/ # 確認 #3 カーネルソースのダウンロード yumdownloader --source kernel ls ./ # 確認 kernel-****.src.rpmファイルができているはず #4 カーネルソースの再構築に必要となるパッケージをインストール yum-builddep kernel-****.src.rpm #5 カーネルソースのインストール # これにより、rpmdev-setuptreeコマンドによって作成された # ~/rpmbuildディレクトリ下にカーネルソースが展開される rpm -Uhv kernel-****.src.rpm #6 カーネルソースのツリーを準備 # ツリーは~/rpmbuild/BUILD/kernel-<バージョン>/ # linux-<バージョン>.<アーキテクチャ>ディレクトリに作成される cd ~/rpmbuild/SPECS rpmbuild -bp --target=`uname -m` kernel.spec #7 いろいろ足りないと言われる なので必要なものを入れる # 筆者実行時エラー #************************************************************************ #[root@sl62-64bit SPECS]# rpmbuild -bp --target=`uname -m` kernel.spec #Building target platforms: x86_64 #Building for target x86_64 #error: Failed build dependencies: # elfutils-libelf-devel is needed by kernel-2.6.32-220.4.2.el6.x86_64 # zlib-devel is needed by kernel-2.6.32-220.4.2.el6.x86_64 # binutils-devel is needed by kernel-2.6.32-220.4.2.el6.x86_64 # newt-devel is needed by kernel-2.6.32-220.4.2.el6.x86_64 # python-devel is needed by kernel-2.6.32-220.4.2.el6.x86_64 # perl(ExtUtils::Embed) is needed by kernel-2.6.32-220.4.2.el6.x86_64 #************************************************************************ yum install elfutils-libelf-devel yum install zlib-devel yum install binutils-devel yum install newt-devel yum install python-devel yum install perl-ExtUtils-Embed # 名前そのままじゃないから、ちょっと引っかかった #8 改めてカーネルソースのツリーを準備 # ### Now generating a PGP key pair to be used for signing modules. # のところで時間かかるのですが、バッググラウンドで # rngd -r /dev/urandomするとすぐ終わります cd ~/rpmbuild/SPECS rpmbuild -bp --target=`uname -m` kernel.spec #9 現在使っているカーネルの.configファイルを使うために # ファイルをコピーしてくる cp /boot/config***** ~/rpmbuild/BUILD/kernel-****/linux-**++/.config #10 現行の設定をそのまま使う (この作業いらない?) cd ~/rpmbuild/BUILD/kernel-****/linux-**++/ make oldconfig #11 先の.configを元にカーネルソースのコンパイルをする # -j オプションを使うとMakefileに従った処理のうち依存関係が無く # 直列に処理しなくても済む部分を,複数のプロセスを生成し並行処理する make -j8 #12 カーネルソースへのリンクを適切に設定する cd /lib/module/(kernel)/ ln -s ~/rpmbuild/BUILD/kernel-****/linux-**++/ ./build ls -l # 確認 #13 hello.cとMakefileがあるフォルダへ移動 cd helloフォルダ
上記の手順で、makeもinsmodでカーネルにモジュールを組み込むこともできるようになると思います。
その他注意
上記の手順で、最も面倒な設定は済んでいますが、それでも失敗する場合は、 以下のところを気にしてください。 ・Makefileのタブがスペースになっている ・リンクの設定が正しいか ・権限がないか など
検索用タグ Linuxドライバ デバイスドライバ Linuxカーネル
PR
2012/02/26 (Sun.) Comment(0) Linuxデバイスドライバ
2012
02
25
複数のデバイスドライバソースをコンパイルする
main.c
/* main.c */ #include <linux/module.h> MODULE_LICENSE("Dual BSD/GPL"); extern void sub(void); static int hello_init(void) { printk(KERN_ALERT "[%s] driver loaded.\n", __func__); sub(); return 0; } static void hello_exit(void) { printk(KERN_ALERT "[%s] driver unloaded.\n", __func__); } module_init(hello_init); module_exit(hello_exit);
sub.c
/* sub.c */ #include <linux/module.h> void sub(void) { printk("[%s] sub() called\n", __func__); }
Makefile
CFILES = main.c sub.c obj-m += hello.o hello-objs := $(CFILES:.c=.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 insmod hello.ko lsmod | grep hello dmesg | tail -5 rmmod hello dmesg | tail -5 ※ su じゃないとダメかも (sudo付き版) make sudo insmod hello.ko lsmod | grep hello dmesg | tail -5 sudo rmmod hello dmesg | tail -5 実行環境 Ubuntu10.04 64bit Linux 2.6.32-33-generic #70-Ubuntu SMP x86_64 GNU/Linux (uname -aで確認)
makeで失敗する or insmodで失敗する
前者:Linuxのソースコードが入っていなかったり、パスが間違っている 後者:起動したLinuxカーネルとコンパイル時のソースでconfigが異なっていてモジュールを組み 込めない sudo付け忘れ insmodする権限がない などの原因が考えられます。 そんなときはこちらのページへ
検索用タグ C言語 Linuxドライバ デバイスドライバ
2012/02/25 (Sat.) Comment(0) Linuxデバイスドライバ
2012
02
24
LinuxドライバでHello worldを表示
ソースコード
/* hello.c */ #include <linux/module.h> // absolutely necessary MODULE_LICENSE("Dual BSD/GPL"); static int hello_init(void) { printk(KERN_INFO "[%s] Hello world\n", __func__); return 0; } static void hello_exit(void) { printk(KERN_INFO "[%s] driver unloaded.\n", __func__); } module_init(hello_init); module_exit(hello_exit);
Makefile
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 insmod hello.ko lsmod | grep hello dmesg | tail -5 rmmod hello dmesg | tail -5 ※ su じゃないとダメかも (sudo付き版) make sudo insmod hello.ko lsmod | grep hello dmesg | tail -5 sudo rmmod hello dmesg | tail -5 実行環境 Ubuntu10.04 64bit Linux 2.6.32-33-generic #70-Ubuntu SMP x86_64 GNU/Linux (uname -aで確認)
makeで失敗する or insmodで失敗する
前者:Linuxのソースコードが入っていなかったり、パスが間違っている 後者:起動したLinuxカーネルとコンパイル時のソースでconfigが異なっていてモジュールを組み 込めない sudo付け忘れ insmodする権限がない などの原因が考えられます。 そんなときはこちら(Scientific Linux用)かこちら(Ubuntu用)のページへ
検索用タグ C言語 Linuxドライバ デバイスドライバ
2012/02/24 (Fri.) Comment(0) Linuxデバイスドライバ