panda大学習帳外伝

荒ぶる子パンダのポーズ。

メインページ | panda大学習帳 | 第三倉庫 | 用語集📒 | 本サイトについて | プライバシーポリシー


convert everything to “struct proc_ops”する必要が生じたので、Intel NUCのLED操作用のドライバのコードを書き換えてみた。

最終更新日: Mon Feb 22 21:01:02 2021 +0900

はじめに

参考文献[2]のpatchが適用されているLinuxのkernelを使用すると、Intel NUCのLED操作用のドライバ(参考文献[1]、以下単に「ドライバ」と書きます。)のコンパイル時にエラーが発生するようになったので、ドライバのソースコードを修正することにしました。

スポンサーリンク

コンパイルエラーの内容

Fedora 33のkernel(5.9.16)のコードを使ってドライバのソースコードに対するコンパイルを実行すると以下のエラーが表示され、コンパイルが中断してしまいます。

[root@pandanote.info intel_nuc_led]# make -j4 KERNELRELEASE=5.9.16-200.fc33.x86_64 -C /lib/modules/5.9.16-200.fc33.x86_64/build M=/var/lib/dkms/intel-nuc-led/1.0/build
make: ディレクトリ '/usr/src/kernels/5.9.16-200.fc33.x86_64' に入ります
  CC [M]  /var/lib/dkms/intel-nuc-led/1.0/build/nuc_led.o
/var/lib/dkms/intel-nuc-led/1.0/build/nuc_led.c: 関数 ‘init_nuc_led’ 内:
/var/lib/dkms/intel-nuc-led/1.0/build/nuc_led.c:475:75: エラー: 互換性のないポインタ型から 4 番目の ‘proc_create’ の引数に渡しています [-Werror=incompatible-pointer-types]
  475 | ntry = proc_create("nuc_led", nuc_led_perms, acpi_root_dir, &proc_acpi_operations);
      |                                                             ^~~~~~~~~~~~~~~~~~~~~
      |                                                             |
      |                                                             struct file_operations *

次のファイルから読み込み:  /var/lib/dkms/intel-nuc-led/1.0/build/nuc_led.c:36:
./include/linux/proc_fs.h:107:122: 備考: expected ‘const struct proc_ops *’ but argument is of type ‘struct file_operations *’
  107 |  mode, struct proc_dir_entry *parent, const struct proc_ops *proc_ops);
      |                                       ~~~~~~~~~~~~~~~~~~~~~~~^~~~~~~~

cc1: いくつかの警告はエラーとして取り扱われます
make[1]: *** [scripts/Makefile.build:283: /var/lib/dkms/intel-nuc-led/1.0/build/nuc_led.o] エラー 1
make: *** [Makefile:1787: /var/lib/dkms/intel-nuc-led/1.0/build] エラー 2
make: ディレクトリ '/usr/src/kernels/5.9.16-200.fc33.x86_64' から出ます

エラーメッセージを見る限り、proc_create関数の第4引数の型が合わないことが原因でコンパイルに失敗しているようです。

作業の方針

kernelのソースコード(proc_fs.h)を見る限りでは、proc_create関数の引数のうち第4引数の型がproc_ops型の構造体(へのポインタ)を指定する仕様に変更になっているようです。

そこで、file_operations型の構造体(へのポインタ)を指定しているドライバ側のコードを修正して、proc_ops型の構造体(へのポインタ)を指定するよう変更します。

また、ドライバに定義されていたfile_operations型の構造体のメンバ名については以下のように変更します。

スポンサーリンク

ソースコードの差分

ソースコードの変更の結果生じた差分は以下の通りです。変数名については変更していません。

diff --git a/nuc_led.c b/nuc_led.c
index c975f22..8a5ed78 100644
--- a/nuc_led.c
+++ b/nuc_led.c
@@ -443,10 +443,9 @@ static ssize_t acpi_proc_read(struct file *filp, char __user *buff,
         return ret;
 }

-static struct file_operations proc_acpi_operations = {
-        .owner    = THIS_MODULE,
-        .read     = acpi_proc_read,
-        .write    = acpi_proc_write,
+static struct proc_ops proc_acpi_operations = {
+        .proc_read     = acpi_proc_read,
+        .proc_write    = acpi_proc_write,
 };

 /* Init & unload */

動作確認

コンパイル

もともとドライバのコンパイルにはdkmsを使用しているため、ドライバのソースコードの修正に関連する修正を行った後、以下のコマンドを実行してコンパイルしてインストールします。

$ sudo make dkms-install

モジュールのロードの設定

/etc/modules-load.dディレクトリの下にnuc_led.confという名前のファイルを作成し、以下のようにモジュール名を記述します。

nuc_led

記述ができたら、PCを再起動します。

procファイルからの読み出し

試しにcatコマンドを使って読み出してみます。

$ cat /proc/acpi/nuc_led
Power LED Brightness: 100%
Power LED Blink/Fade: Always On (0x04)
Power LED Color: Amber (0x02)

Ring LED Brightness: 100%
Ring LED Blink/Fade: Always On (0x04)
Ring LED Color: White (0x07)

動作していることが確認できました。👍

スポンサーリンク

まとめ

Linux kernelのproc_fs.hのソースコードによると、proc_create関数の第4引数の型が変わったのはVersion 5.6-rc1からのようです。

最近はLinuxのkernelのソースコードを直接コンパイルしたりすることも少なくなりましたが、時々ドライバのソースコードをコンパイルしたりすると、ソースコードの最新の状況が垣間見えたりするので、割とおすすめです。

この記事は以上です。

参考文献

  1. Linux Kernel Driver for NUC LED Control
  2. [PATCH 2/2] proc: convert everything to “struct proc_ops”

リンク

Fedora 32からFedora 33へのupgrade | メインページ | panda大学習帳 | 第三倉庫 | 用語集📒 | 本サイトについて | プライバシーポリシー


スポンサーリンク