Mirakurun が起動しない (./include/linux/export.h:29:22: error: passing argument ... でドライバのコンパイルエラー)

ドライバのコンパイルエラーが発生したお話。

# 症状

「docker-mirakurun-epgstation のチューナーカードを PX-MLT8PE に換装」
https://qiita.com/nanbuwks/items/ef160c9b9ee1f402b3cf
で設定した環境で、トラブルに見舞われました。

(ここでは 192.168.0.200 で設定したサーバの場合です。 )

EPGStation 画面が出ない `http://192.168.0.200:8888/`

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/139524/c0f8da25-5d65-12e6-d731-cb2c0190ebf8.png)

Miarakurun `http://192.168.0.200:40772/` も同様でした。


# 診断

docker ps でみてみると、あれ? Mirakurun は?
```
$ docker ps
CONTAINER ID   IMAGE                                    COMMAND                   CREATED       STATUS         PORTS                                                           NAMES
387abc3c6b6b   docker-mirakurun-epgstation_epgstation   "npm start"               6 weeks ago   Up 8 minutes   0.0.0.0:8888-8889->8888-8889/tcp, :::8888-8889->8888-8889/tcp   docker-mirakurun-epgstation_epgstation_1
3543c591c5a3   mariadb:10.5                             "docker-entrypoint.s…"   6 weeks ago   Up 8 minutes   3306/tcp                                                        docker-mirakurun-epgstation_mysql_1
```


```
$ docker-compose start
Starting mirakurun  ... error
Starting mysql      ... done
Starting epgstation ... error

ERROR: for mirakurun  Cannot start service mirakurun: error gathering device information while adding custom device "/dev/pxmlt8video0": no such file or directory
```

うーん、デバイスが認識できてないのかな?


 PX-MLT8PE は、PCI-E カードのように見えますが PCI-E スロット以外にもカード上の2つのコネクタから 2つの USB ポートにケーブルを配線していて、実はそれが接続に使われています。

 そのUSBポートを取り外してみました。

```

[  183.302160] usb 1-14: USB disconnect, device number 4
[  188.216622] usb 1-13: USB disconnect, device number 3
```
取り付けてみます。

```
[  208.488314] usb 1-13: new high-speed USB device number 5 using xhci_hcd
[  208.642095] usb 1-13: New USB device found, idVendor=0511, idProduct=0253, bcdDevice= 1.00
[  208.642108] usb 1-13: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[  208.642113] usb 1-13: Product: PXML͔8PE
[  208.642118] usb 1-13: Manufacturer: PLEX
[  208.642121] usb 1-13: SerialNumber: 000061946007472
[  224.344173] usb 1-14: new full-speed USB device number 6 using xhci_hcd
[  224.472191] usb 1-14: device descriptor read/64, error -71
[  224.708210] usb 1-14: device descriptor read/64, error -71
[  224.944166] usb 1-14: new high-speed USB device number 7 using xhci_hcd
[  225.097912] usb 1-14: New USB device found, idVendor=0511, idProduct=0252, bcdDevice= 1.00
[  225.097924] usb 1-14: New USB device strings: Mfr=1, Product=2, SerialNumber=3
[  225.097930] usb 1-14: Product: PXML͔8PE
[  225.097934] usb 1-14: Manufacturer: PLEX
[  225.097938] usb 1-14: SerialNumber: 000061946007471
```

デバイスの取り付けは問題ないようですね。しかしながら以下のようにしても何も出てきません。


```

$ lsmod | grep -e ^px4_drvq!
```

デバイスドライバがロードされていないようです。
```
$ modprobe px4_drv
modprobe: FATAL: Module px4_drv not found in directory /lib/modules/6.5.0-15-generic
```

ドライバが無い?

```
$ ls /lib/modules
5.15.0-25-generic  5.19.0-43-generic  6.2.0-33-generic  6.2.0-34-generic  6.2.0-35-generic  6.2.0-36-generic  6.2.0-37-generic  6.2.0-39-generic  6.5.0-14-generic  6.5.0-15-generic
```
カーネルがアップデートされたかな。DKMS 設定したつもりだったけど、忘れてたかな?


# おまけ的なポカミス
```
$ cd px4_drv
$ cd driver
$ sudo make uninstall
```
ここで間違えて make install してしまったら・・・

```
$ sudo make install
install: ディレクトリ '/lib/modules/6.5.0-15-generic/misc' を作成しています
'px4_drv.ko' -> '/lib/modules/6.5.0-15-generic/misc/px4_drv.ko'
'/etc/udev/rules.d/99-px4video.rules' を削除しました
'../etc/99-px4video.rules' -> '/etc/udev/rules.d/99-px4video.rules'
modprobe: ERROR: could not insert 'px4_drv': Exec format error
make: *** [Makefile:55: install] エラー 1
```

これは make してなかったからですね。

# コンパイルエラー

```

$ make clean
```

として、

```
$ make
```
とすると

```
'revision.h' was updated.
make[1]: ディレクトリ '/usr/src/linux-headers-6.5.0-15-generic' に入ります
warning: the compiler differs from the one used to build the kernel
  The kernel was built by: x86_64-linux-gnu-gcc-12 (Ubuntu 12.3.0-1ubuntu1~22.04) 12.3.0
  You are using:           gcc-12 (Ubuntu 12.3.0-1ubuntu1~22.04) 12.3.0
  CC [M]  /home/nanbuwks/Downloads/px-mlt8pe/px4_drv/driver/driver_module.o
  CC [M]  /home/nanbuwks/Downloads/px-mlt8pe/px4_drv/driver/ptx_chrdev.o
In file included from ./include/linux/linkage.h:7,
                 from ./include/linux/preempt.h:10,
                 from ./include/linux/spinlock.h:56,
                 from ./include/linux/kref.h:16,
                 from /home/nanbuwks/Downloads/px-mlt8pe/px4_drv/driver/ptx_chrdev.h:13,
                 from /home/nanbuwks/Downloads/px-mlt8pe/px4_drv/driver/ptx_chrdev.c:9:
/home/nanbuwks/Downloads/px-mlt8pe/px4_drv/driver/ptx_chrdev.c: In function ‘ptx_chrdev_context_create’:
./include/linux/export.h:29:22: error: passing argument 1 of ‘class_create’ from incompatible pointer type [-Werror=incompatible-pointer-types]
   29 | #define THIS_MODULE (&__this_module)
      |                     ~^~~~~~~~~~~~~~~
      |                      |
      |                      struct module *
/home/nanbuwks/Downloads/px-mlt8pe/px4_drv/driver/ptx_chrdev.c:573:35: note: in expansion of macro ‘THIS_MODULE’
  573 |         ctx->class = class_create(THIS_MODULE, name);
      |                                   ^~~~~~~~~~~
In file included from ./include/linux/device.h:31,
                 from ./include/linux/cdev.h:8,
                 from /home/nanbuwks/Downloads/px-mlt8pe/px4_drv/driver/ptx_chrdev.h:16:
./include/linux/device/class.h:230:54: note: expected ‘const char *’ but argument is of type ‘struct module *’
  230 | struct class * __must_check class_create(const char *name);
      |                                          ~~~~~~~~~~~~^~~~
/home/nanbuwks/Downloads/px-mlt8pe/px4_drv/driver/ptx_chrdev.c:573:22: error: too many arguments to function ‘class_create’
  573 |         ctx->class = class_create(THIS_MODULE, name);
      |                      ^~~~~~~~~~~~
./include/linux/device/class.h:230:29: note: declared here
  230 | struct class * __must_check class_create(const char *name);
      |                             ^~~~~~~~~~~~
cc1: some warnings being treated as errors
make[3]: *** [scripts/Makefile.build:251: /home/nanbuwks/Downloads/px-mlt8pe/px4_drv/driver/ptx_chrdev.o] エラー 1
make[2]: *** [/usr/src/linux-headers-6.5.0-15-generic/Makefile:2037: /home/nanbuwks/Downloads/px-mlt8pe/px4_drv/driver] エラー 2
make[1]: *** [Makefile:234: __sub-make] エラー 2
make[1]: ディレクトリ '/usr/src/linux-headers-6.5.0-15-generic' から出ます
make: *** [Makefile:19: px4_drv.ko] エラー 2
```

あれれ? カーネルとドライバのバージョン違いではなくて、DKMS はちゃんと設定できていたけれどもビルドエラーが起こっていたのかな?


# DKMS エラー

DKMS 設定を削除して

```

$ cd ..
$ sudo dkms remove px4_drv/0.2.1 --all
Deleting module px4_drv-0.2.1 completely from the DKMS tree.
$ sudo rm -rf /usr/src/px4_drv-0.2.1
```

再度 DKMS 設定をインストールしようとすると・・・
```
$ sudo cp -a ./ /usr/src/px4_drv-0.2.1
$ sudo dkms add px4_drv/0.2.1
Creating symlink /var/lib/dkms/px4_drv/0.2.1/source -> /usr/src/px4_drv-0.2.1
$ sudo dkms install px4_drv/0.2.1

Kernel preparation unnecessary for this kernel. Skipping...

Building module:
cleaning build area...
cd ./driver; make KVER=6.5.0-15-generic px4_drv.ko...(bad exit status: 2)
ERROR (dkms apport): binary package for px4_drv: 0.2.1 not found
Error! Bad return status for module build on kernel: 6.5.0-15-generic (x86_64)
Consult /var/lib/dkms/px4_drv/0.2.1/build/make.log for more information.

```

うーむ。エラーが出てますね。

# 原因

ここに、そのものズバリがありました。
「driver: Linuxカーネルv6.4の関数シグニチャの変更に対応 by kznrluk · Pull Request #26 · nns779/px4_drv · GitHub」
https://github.com/nns779/px4_drv/pull/26

カーネル6.4 系以降と 6.3 系以前で呼び出し処理が変わっているようです。



# カーネルのダウングレード

grub を見ると、6.2.0-39 から 6.5.0-15 にアップデートがなされていたようです。

```

$ sudo grep menuentry /boot/grub/grub.cfg
if [ x"${feature_menuentry_id}" = xy ]; then
  menuentry_id_option="--id"
  menuentry_id_option=""
export menuentry_id_option
menuentry 'Ubuntu' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-simple-c94ececc-f91c-4c30-bb03-f5c1ff6388b4' {
submenu 'Advanced options for Ubuntu' $menuentry_id_option 'gnulinux-advanced-c94ececc-f91c-4c30-bb03-f5c1ff6388b4' {
	menuentry 'Ubuntu, with Linux 6.5.0-15-generic' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-6.5.0-15-generic-advanced-c94ececc-f91c-4c30-bb03-f5c1ff6388b4' {
	menuentry 'Ubuntu, with Linux 6.5.0-15-generic (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-6.5.0-15-generic-recovery-c94ececc-f91c-4c30-bb03-f5c1ff6388b4' {
	menuentry 'Ubuntu, with Linux 6.2.0-39-generic' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-6.2.0-39-generic-advanced-c94ececc-f91c-4c30-bb03-f5c1ff6388b4' {
	menuentry 'Ubuntu, with Linux 6.2.0-39-generic (recovery mode)' --class ubuntu --class gnu-linux --class gnu --class os $menuentry_id_option 'gnulinux-6.2.0-39-generic-recovery-c94ececc-f91c-4c30-bb03-f5c1ff6388b4' {
menuentry 'Memory test (memtest86+.elf)' {
menuentry 'Memory test (memtest86+.bin, serial console)' {
```

今回は、カーネルをダウングレードすることで対処することにしました。

「Ubuntu でアップデートで問題の発生したカーネルを旧カーネルに戻す」
https://qiita.com/nanbuwks/items/f3d3949be8116b62bd5a

の作業を行って、6.2.0-39 に戻して再起動。

改めて設定し直すと

```
$ sudo dkms add px4_drv/0.2.1
Error! DKMS tree already contains: px4_drv-0.2.1
You cannot add the same module/version combo more than once.
```

多分 6.2.0-39 のモジュールはインストールされているのでしょうね。念の為消して手動で確認。

```
$ sudo dkms remove px4_drv/0.2.1 --all
Deleting module px4_drv-0.2.1 completely from the DKMS tree.
$ sudo rm -rf /usr/src/px4_drv-0.2.1
```

インストール

```
$ sudo cp -a ./ /usr/src/px4_drv-0.2.1
$ sudo dkms add px4_drv/0.2.1
Creating symlink /var/lib/dkms/px4_drv/0.2.1/source -> /usr/src/px4_drv-0.2.1
$ sudo dkms install px4_drv/0.2.1

Kernel preparation unnecessary for this kernel. Skipping...

Building module:
cleaning build area...
cd ./driver; make KVER=6.2.0-39-generic px4_drv.ko......
Signing module:
 - /var/lib/dkms/px4_drv/0.2.1/6.2.0-39-generic/x86_64/module/px4_drv.ko
EFI variables are not supported on this system
/sys/firmware/efi/efivars not found, aborting.
cleaning build area...

px4_drv.ko:
Running module version sanity check.
 - Original module
   - No original module exists within this kernel
 - Installation
   - Installing to /lib/modules/6.2.0-39-generic/updates/dkms/

Running the post_install script:
'/etc/udev/rules.d/99-px4video.rules' を削除しました
'./etc/99-px4video.rules' -> '/etc/udev/rules.d/99-px4video.rules'

depmod.....
```

問題ありませんでした。

再起動したら、 Mirakurun も EPGstation も無事起動しました。