I'm trying to port a device driver from a 2.2.14 kernel to the latest RedHat 7 release (2.2.16 kernel). We did a fresh installation of RedHat 7 -- not an upgrade. I didn't get very far with porting the driver... during debugging I ran across a weird problem that can be reproduced using the following minimal driver. #include <linux/module.h> extern void printk( const char *fmt, ... ); int init_module( void ) { printk( "<1>Hello, world!\n" ); return 0; } void cleanup_module( void ) { printk( "<1>Goodbye, cruel world!\n" ); } (1) When I build this minimal driver ("gcc -D__KERNEL -DMODULE -c drv.c") I get a weird assembler warning: /tmp/ccWGbbyQ.s: Assembler messages: /tmp/ccWGbbyQ.s:9: Warning: Ignoring changed section attributes for .modinfo (2) Since the above message is only a warning, not an error, I go ahead and try to load the module. When I do so ("insmod drv.o"), I get the following error: drv.o: kernel-module version mismatch drv.o was compiled for kernel version 2.4.0-0.26 while this kernel is version 2.2.16-22. (3) I've tracked it down... normally /usr/include/linux is a symbolic link into the /usr/src/linux-x.y.zz/include/linux directory (where x.y.zz is the currently installed kernel version). With RedHat 7 this is not true... /usr/include/linux is an actual directory rather than a symbolic link, and it contains header files for kernel version 2.4!!! At least that is what is indicated in version.h. Further, the pci_dev struct in pci.h has been redefined in 2.4 (which is what started this mess, because our driver wouldn't build because there is no more 'base_address' field defined). So I moved the /usr/include/linux directory into linux-2.4, then created a symbolic link into the "normal" /usr/src/linux-2.2.16/include/linux directory. (4) Unfortunately, I still get that weird assembler warning when compiling, but I _am_ able to load the driver. What does the assembler warning mean, and how do I get rid of it? (5) I need to know if my "fix" of redefining /usr/include/linux to point into the kernel source code is okay, or if there's something more basic that I'm missing. We have a customer reporting the same problem... and since RedHat 7 is the current release available in stores everywhere, we're expecting a lot of calls on this issue. (6) Another problem (?) I've encountered is that no matter what error value I return in init_module(), I always get the same message displayed when I try to load the driver: drv.o: init_module: Device or resource busy Hint: insmod errors can be caused by incorrect module parameters, including invalid IO or IRQ parameters Is this normal, i.e. to get the exact same message no matter what error value is returned in init_module()? Thank you very much for your time.
You need to include the kernel headers for the kernel you're compiling for, such as doing -I/usr/src/linux-2.2.16/include/linux. The headers in /usr/include/linux are for glibc and general system application use; they do *not* need to reflect the kernel installed. You also most likely want to use kgcc, not gcc, to compile your kernel module. As for your last question, kernel/module.c has, where it calls the init_module function (in sys_init_module): if (mod->init && mod->init() != 0) { atomic_set(&mod->uc.usecount,0); mod->flags &= ~MOD_INITIALIZING; error = -EBUSY; goto err0; } So, any return code will get you 'device or resource busy'. The 'insmod errors can be caused...' message is actually from modutils.
*** Bug 20467 has been marked as a duplicate of this bug. ***