在Linux下爲PCI設備寫驅動程序,發現insmod插入內核模塊正常,可是rmmod時出錯,報下面的錯誤:java
rmmod: ERROR: could not remove 'xxxxxx': Device or resource busy
rmmod: ERROR: could not remove module xxxxxx: Device or resource busylinux
使用lsmod能夠看到此模塊的Used by是0,一開始懷疑是本身的代碼有問題,因而精簡了一個最基本的框架,代碼以下:c++
#include <linux/init.h> #include <linux/module.h> static int __init demo_init(void) { printk(KERN_INFO "DEMO_INIT"); return 0; } static void __exit demo_exit(void) { printk(KERN_INFO "DEMO_EXIT"); } module_init(demo_init); module_exit(demo_exit);
編譯後仍然是insmod正常但rmmod報錯,奇怪的是換一臺機器就行了,因而開始比對兩邊環境的差別。正常的環境是CentOS-7.9-x86_64,內核版本3.10.0,gcc版本4.8.5。異常的環境是CentOS-7.9-aarch64,內核版本4.18.0,gcc版本4.8.5。差別在於內核和CPU架構。bootstrap
因而開始懷疑多是系統的鍋,多方查找,最後發現是編譯時使用的gcc與系統gcc版本不一致致使的,在異常的環境上查看:centos
[root@centos145 ~]# dmesg | grep gcc
[ 0.000000] Linux version 4.18.0-193.28.1.el7.aarch64 (mockbuild@aarch64-01.bsys.centos.org) (gcc version 8.3.1 20190311 (Red Hat 8.3.1-3) (GCC)) #1 SMP Wed Oct 21 16:25:35 UTC 2020架構[root@centos145 ~]# gcc -v
Using built-in specs.
COLLECT_GCC=gcc
COLLECT_LTO_WRAPPER=/usr/libexec/gcc/aarch64-redhat-linux/4.8.5/lto-wrapper
Target: aarch64-redhat-linux
Configured with: ../configure --prefix=/usr --mandir=/usr/share/man --infodir=/usr/share/info --with-bugurl=http://bugzilla.redhat.com/bugzilla --enable-bootstrap --enable-shared --enable-threads=posix --enable-checking=release --with-system-zlib --enable-__cxa_atexit --disable-libunwind-exceptions --enable-gnu-unique-object --enable-linker-build-id --with-linker-hash-style=gnu --enable-languages=c,c++,objc,obj-c++,java,fortran,ada,lto --enable-plugin --enable-initfini-array --disable-libgcj --with-isl=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-aarch64-redhat-linux/isl-install --with-cloog=/builddir/build/BUILD/gcc-4.8.5-20150702/obj-aarch64-redhat-linux/cloog-install --enable-gnu-indirect-function --build=aarch64-redhat-linux
Thread model: posix
gcc version 4.8.5 20150623 (Red Hat 4.8.5-44) (GCC) app
能夠看到gcc分別是8.3.1和4.8.5。而正常的環境上二者是一致的,均爲4.8.5。升級一下gcc應該能夠解決沒法rmmod的問題,後續能夠試下。至於有沒有其它方案有待研究。框架