Debugging of module in linux - c

How to debug the modules in Linux? As their will be no executable file for the modules? What does ELF will do ? Only the Makefile i have complied and given me object file and various other files.

As their will be no executable file for the modules?
There is no executable (like a.out), but there is kernel object file *.ko. Kernel object files are added to or removed from the kernel via insmod and rmmod.
So at minimum, you need to be able to do the following to debug a kernel module:
Locate the module itself (*.c file and corresponding *.ko kernel object).
Add (a lot of) printk
Rebuild the kernel.
rmmod the old module, insmod the new version.
Watch out debug logs, normally via dmesg.

There are several methods for debugging by printing (i.e printk),watching,querying
Refer to understand different debugging methods for module. Obvious method is we can use printk and after inserting (insmod) and removing (rmmod) module and that message can be seen in kernel buffer using $dmesg

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

linux kernel module compilation pre-requisites

I've just started to learn about linux kernel modules and the book I'm referring to says:
"For this [compilation] to work, the kernel source has to be suitably prepared; in particular it has to have a configuration file (.config in the main kernel source directory) and proper dependencies setup"
However, as far as I know (and have tried), the .config file is generated by the make menuconfig (or any of the equivalent make config commands) - and that doesn't seem to be enough for my module files to compile. What's the bare minimum I need to do in the kernel source directory?
make modules?
Yes, the .config file is generated using make *config.
Here are some of them:
make defconfig creates the default configuration for your architecture.
make config is the most primitive method, it prompts on every configuration.
make menuconfig is ncurses config menu. That's the one I prefer if I'm not editing .config file directly.
make gconfig is like menuconfig, but using gtk+.
Don't forget that make oldconfig should be called after modifying the .config file yourself.
Your current config might also be stored somewhere on your disk. For many linux versions, it's location is /boot/config-$(uname -r) If it exists, you can start with it. If not, your best bet is make defconfig, then editing the config file to suit your needs.
After configuration:
Before building modules, you might want to compile the kernel since your modules will not be used by the current kernel and even if you make your current kernel use those modules, it'll most probably cause a panic since symbol tables will not be in the order that your compiled modules assumes. make -jN is the most used method for compiling, N being twice your CPU core count. This also compiles modules, but creates .ko files for them, instead of embedding into the vmlinuz file.
After that, you can sudo make install to install your kernel. This usually wraps the kernel object you've just compiled into a suitable format and puts under /boot (it doesn't have to be /boot, actually).
Then you sudo make modules_install to copy the created .ko files into /lib/modules/$(uname -r). This builds all modules.
After doing that, you might prefer only building your own module, instead of all of them. When on the kernel tree root, you may make M=your_modules_relative_path to only build your module.
I don't know which book you're reading, but if you're building a module externally, you still have to perform the work above. After that, you may use LDD examples as a starting point for your makefiles.
See https://github.com/duxing2007/ldd3-examples-3.x

Compiling an individual kernel module (Debian/Ubuntu)

I need to modify the ELF loader's kernel implementation of an Ubuntu 14.04 distribution. Having downloaded the sources using:
sudo apt-get source linux-image-$(uname -r)
I ran the configuration script:
make config
in the root source tree. After a seemingly endless sequence of input requests, the script created the .config file needed to build the kernel(or a set of modules). The kernel version I am using is linux-3.13.0 and has the following source tree layout:
$ ls
arch COPYING crypto Documentation dropped.txt FileSystemMakefile fs init Kbuild kernel MAINTAINERS mm README samples security sound ubuntu virt
block CREDITS debian.master drivers elf.dat firmware include ipc Kconfig lib Makefile net REPORTING-BUGS scripts shortcuts tools usr
The ELF loader is located in /path/to/source/fs/binfmt_elf.c. Following this question,in order to compile an individual module it is sufficient to run
make /path/to/module/directory.
In this case that would be:
make ./path/to/source/fs
The compilation is quite lengthy; it takes about twenty minutes(on a virtual machine) and the output is written(by default) in the same directory in which the module is located. I've found the object files by running:
find . -name "*.o"
in /path/to/source/fs. Filtering by name the ELF loader can be located by running:
find . -name "*elf*.o"
In the current sources it is written(by default) in:
/path/to/source/fs/binfmt_elf.o
Having gone through this tutorial, I've noticed that kernel modules have the naming convention [module_name].ko in order to distinguish them from user space object files.
My question is how can I insert the new(modified) ELF loader into the kernel given that the current ELF loader is present(as unloading it may prevent binaries from being executed)?
What you have described is not really compiling a "kernel module" as it is commonly referred to. You have built an object that is statically linked into the kernel and there is no way that you can load just that object into a running kernel.
"kernel module" usually refers to "loadable kernel module" (LKM). Building and loading the fs as an LKM is what you need/want. Take a look at the below HOWTO. Follow that to build the desired fs as an LKM. Then you can just replace that one LKM (.ko) file and reboot (normally you can dynamically remove and insert LKMs but not sure how that will affect something fundamental like the ELF fs - you can try rmmod/modprobe without a reboot first if you ike).
http://www.tldp.org/HOWTO/Module-HOWTO/x73.html

Can we only recompile a kernel module in kernel source tree?

Let's say we install a kernel 2.6.32.el6, then we download the 2.6.32.el6.src.rpm, can we just install the source and modify some module, and use make -C 2.6.32.el6.src.source.directry -M$PWD in the module directory to compile the module, then we copy into /lib/modules/2.6.32.el6/kernel/moduledirectory and the new module would work?
I try to modify kvm modules and compile it, but when I recompile the module and copy it into the directory, machine said when booting:
kvm: no symbol version for module_layout
kvm_intel: no symbol version for module_layout
Anyone knows what is wrong?
Probably linux kernel 2.6.32.el6 has been compiled with modversions but your module was compiled without it. Check if you have CONFIG_MODVERSIONS selected or deselected in your kernel config file. Compare it with /proc/.config file which is the kernel confguration file - of course if you have it.
In other words - probably your linux kernel requires that modules supports versioning, but your module doesn't provide it.

loading module and object files automatically on booting

I have created a module.ko and a object file a.out that uses the module.
Does someone know how I load them both on booting?
I did depmod to my module and then modprobe -a.
I think it damaged my system.
It is likely that your distro has a configuration file to list all kernel modules that must be loaded when the system boots. Try man 5 modules to check how it works. Otherwise check a file named /etc/modules, or the documentation of your OS.

Resources