Can't install some driver modules from C program - c

I have an embedded Linux application that can find and install some drivers from my C based application, but there are other drivers that it can't find at all.
From application:
system("insmod i2c_core.ko");
Debug error message:
insmod: i2c_core.ko: no module by that name found
However I have no problem installing any of the same drivers from the command line using the insmod command.
It's not a driver sequence dependency problem because the error message would be different than the above error message.
Linux version is 2.6.10 (old yes, but from reference design)
All the drivers are under this path '/lib/modules' and are built as part of the kernel build.

insmod wants the correct path (absolute or relative, insmod i2c_core.ko is same as insmod ./i2c_core.ko). If the module is properly installed for the kernel, try using modprobe:
system("modprobe i2c_core");
Otherwise, you need to figure out how to find the correct path to the module file.

Related

Disagrees about version of symbol symbol_name after insmod

I am new in kernel programming.
For implementing my project work, I have downloaded the latest stable kernel (v4.3) from kernel.org.
Just for checking I have copied a few files from the kernel directories into my project directory. Made changes to it and inserted a few more code to it.
Then I compiled on SLES11 Linux kernel using
make -C /lib/modules/$(uname -r)/build M=$PWD modules
I have used the below makefile
obj-m := my_module.o
my_module-objs := module_main.0 other_module1.o other_module2.o other_module3.o
It compiled successfully.
But when I tried to insert into the kernel using
insmod my_sample.ko
It showed the following
disagrees about version of symbol symbol_name
You need to build your kernel module against the same version kernel you are going to run. Thus if you have kernel 4.3 sources that you have downloaded you need to compile that version of the kernel and boot with that running before trying to load your kernel.
You have two solutions then:
Download the kernel sources for the kernel you are currently running (you can install those with zypper install kernel-source on SLES or an equivalent command on other distributions.)
Compile and install the 4.3 kernel in to your operating system. If you need help with this then ask a separate question (and it probably belongs on superuser not here). Note that if kernel and glibc are tightly coupled, and it is possible that you can't run a new kernel if you have a very old C library.
The problem here is that your Kernel module is using the exported symbols of other kernel modules which in this case appears to be the linux InfiniBand RDMA stack's exported methods or symbols.
To solve the symbol version problems, copy the Module.symvers file from the
/usr/src/ofa-kernel
directory and paste it to your current working directory. Then you make your modules again. Now the insmod should work perfectly fine.
NOTE: The Module.symvers file contains information of all the kernel
module exported symbol. So by copying it to your working directory,
you are helping kbuild to know more about the used exported symbols.
And if you don't find Module.symvers or it is empty, then create one using create_Module.symvers.sh
make -C /lib/modules/$(uname -r)/build M=$PWD modules,
"$(uname -r)" shows that you are compiling against the kernel version you are running now so you should be able to insmod the module in the current kernel if you haven't changed the headers.
From your text,
"Just for checking I have copied a few files from the kernel directories into my project directory. Made changes to it and inserted a few more code to it."
If you have made modifications to the kernel source then you may need to recompile the new kernel and boot with the new updated kernel. Then you should be able to compile your kernel module with the modified headers.
Looks like you built agAinst right kernel.something to do with how your kernel is compiled. (See Config_conversions). Try --force

Compiling embedded linux drivers

This might have passed to the unix and linux stack exchange, but since it involves compiling, i am posting it here.
I want to compile usbserial, usb-wwan, and/or qcserial drivers for 2.6.35-9 Debian for ARMv7.
First problem, there is no 2.6.35-9 driver in the apt-get repos. I tried to compile with 2.6.32-kirkwood, while compilation works, insmod / modprobe, including -f, respectively --force switch fails, with the message :
insmod: error inserting 'usbserial.ko': -1 Invalid module format
I have looked up this and this. In this question, I was pointed to Debian 2.6.35-9 headers, but they did not install, for some dependency problem (Error message : Couldn't resolve dependency, without a list of missing dependencies). So I opened the .deb with ar, but it does not contain anything besides under data.tar.gz a /usr/share/doc ... etc - so no usable header files (or am I missing something?)
I am doing the compilation on the target machine (A Mirabox from Marvell) itself.
So, my question is,
Can I download the Ubuntu 2.6.35 headers? Ubuntu uses Debian core, and the linux kernel is the same, with adaptions to the distro, or it is a fatal error? Is there any Armv7 header for a 2.6.35-9 at all?
If not, then what do I do? Where do I get the correct header files?
Also, 2.6.35 code for usbserial / qcserial is buggy anyway. I was using the code from the 3.2 kernel, thinking the errors might have been fixed. Was it a bad choice? If so, what to do

How to compile a module from downloaded Linux source?

I would ultimately like to modify and compile the existing Linux USB storage driver and test it. For the first step, I wanted to compile the module as is.
I downloaded the latest Linux kernel (version 3.12) and extracted it to ~/linux-3.12.
I found the driver I wanted to compile: drivers/usb/storage, but when I ran make, I got the following error:
make: *** No targets. Stop.
I found many guides online, but none of them worked for the USB storage driver. All I want is to compile this one module and get the .ko so I can test it out.
NOTE: I'm running Ubuntu 13.04 64-bit, and uname -r outputs 3.8.0-30-generic - I'm not sure if that's the problem, but I managed to compile the whole Kernel before. I don't want to do that now because it takes an eon.
If you wanted to build the drivers/usb/storage module you would do this:
make M=drivers/usb/storage
from the root directory of the kernel tree. Before doing so, you will need to make sure that your configuration is the same as the config of the running kernel.
You can't simply take the source code for one kernel and use it to build modules for another one. The module needs to be built from the same source and with the same configuration as the kernel itself.
Basically, you need to find the source code for the Ubuntu kernel you're running. In Ubuntu, as in Debian, that can be done with 'apt-get source '. The package name is probably something like 'linux-image-3.8-2-amd64'.
Once you have the source code you need to find the configuration of your running kernel. Fortunately Ubuntu keeps that in /boot/config-3.8-....
Copy that config to your kernel source tree as .config and run 'make oldconfig'. Now you should be able to build the module (assuming it's not already built into your kernel!).

How to build and deploy a Linux driver?

I am using ubuntu, but the question is for linux in general.
I installed a module/driver by compiling my linux kernel and install the new compiled kernel. It works fine.
In order to make this driver work in another machine without installing the new kernel, I copy the .ko file to the new machine under /lib/modules/<version>/... and then run sudo depmod -a. Then run sudo modprobe <drivername>. The module can be loaded without a problem. but the device is not working well with this .ko module.
The two machines are not identical to hardwares, BUT they are identical to kernel version and ubuntu release version. Normally, copying .ko file should work for the same linux release and the same kernel.
More information about the driver. it's a hid pen tablet driver. All patch files:
one .c file in drivers/hid/
add one line in drivers/hid/Makefile
add a few lines to drivers/hid/usbhid/Kconfig
add a few lines to drivers/hid/hid-ids.h
add a few lines to drivers/hid/usbhid/hid-quirks.c's hid_blacklist struct before { 0, 0 }
That's all.
I even tried to copy the entire drivers/hid/ directory includig all the .ko files from the first machine to the second one. but no luck. The pen tablet can be recognized in the second machine, I am able to do mouse left click event with the pen, but the pen can not move the cursor.
Hopefully, I provided enough details. My goal is to only install the module to identical linux release (kernel) without reinstalling the kernel. I am not sure how to achieve that or if it's possible.
Thanks a lot.
PS:
The dmesg output in 1st machine which works: http://paste.ubuntu.com/6419301/
The dmesg output in 2nd machine: http://paste.ubuntu.com/6419302/
In 1st machine, before plugging in the tablet, lsmod doesn't show the module. after plugging in, the module can be loaded automatically. I can see lsmod shows the module.
In 2nd mahcine, the module can not be loaded automatically by plugging in the device. I have to do sudo modprobe <module> manually.
Since I will have to install the module to many machines in my company, it's easier to install the module without reinstalling the kernel. I tried to install the kernel .deb packages which built in the 1st machine to the 2nd machine, it works fine in 2nd machine. but I don't feel good to reinstall the kernel to many machines. Thanks.
It seems the kernel you built isn't a 1:1 match. Also, generally there's no need to compile a new kernel.
The simplest way to deal with an out-of-tree driver deployment is to use DKMS.
What you need to provide is just a dkms.conf file specifying the package name, version, and driver names and destinations (within /lib/modules/{kernel}).
In the following examples, things within braces need to be replaced with the real thing, e.g. if version is 1.0.0, then {version} with 1.0.0, obviously.
Example dkms.conf:
PACKAGE_NAME="{mydriver}"
PACKAGE_VERSION="{version}"
BUILT_MODULE_NAME[0]="{mydriver}"
BUILT_MODULE_LOCATION[0]="/{mycompany?}"
AUTOINSTALL="yes"
Then you just need to install the sources to /usr/src/{mydriver}-{version}, and run dkms:
dkms add -m {mydriver} -v {version}
dkms build -m {mydriver} -v {version}
dkms install -m {mydriver} -v {version}
You should take a look at what other people have done in this area, there's a great deal of automation you can apply to testing and release processes. Bluecherry's solo6x10 out-of-tree version provides some useful make targets (disclosure: I'm the one who wrote that).
Also, you definitely want to build and distribute packages, you can use solo6x10/debian as a template, and you can read about repositories in the Debian wiki.
You can add the module to /etc/modules so it's loaded at boot time.

Qemu configure throws zlib,pthread and kvm missing errors

I have been trying to get my qemu version running on a new machine. I installed zlib1g-dev, zlib-bin etc. When I do a whereis zlib, I get
zlib: /usr/include/zlib.h /usr/share/man/man3/zlib.3.gz
I tried compiling and installing zlib from source too, but the same issue was present.
The exact error I get is
big/little test failed
Error: zlib check failed
Make sure to have the zlib libs and headers installed.
Additionally, if I comment out the the exit due to this, I get
Error: pthread check failed
and
ERROR: User requested feature kvm
ERROR: configure was not able to find it
kvm modules are enabled and the machine supports hardware virtualization. I had checked it using kvm-ok. lsmod shows kvm and kvm_intel modules.
I am really stumped about these errors. Any help or pointers would be greatly appreciated.
I am still not sure of the actual dependencies that caused the problem, but all the issues were fixed by using
sudo apt-get depmod qemu
After this, I am now able to configure qemu

Resources