I have a problem with modprobe command... I compiled the hello world module and loaded it with insmod, it works fine and when I do lsmod, I can see it in the output list. But when I insert this module using modprobe I am getting a FATAL error:
root#okapi:/home/ravi# modprobe ./hello.ko
FATAL: Module ./hello.ko not found.
root#okapi:/home/ravi#
Here is the module code:
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void)
{
printk(KERN_ALERT "Hello, world\n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "Goodbye, cruel world\n");
}
module_init(hello_init);
module_exit(hello_exit);
and Makefile
obj-m += hello.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
The reason is that modprobe looks into /lib/modules/$(uname -r) for the modules and therefore won't work with local file path. That's one of differences between modprobe and insmod.
The best thing is to actually use the kernel makefile to install the module:
Here is are snippets to add to your Makefile
around the top add:
PWD=$(shell pwd)
VER=$(shell uname -r)
KERNEL_BUILD=/lib/modules/$(VER)/build
# Later if you want to package the module binary you can provide an INSTALL_ROOT
# INSTALL_ROOT=/tmp/install-root
around the end add:
install:
$(MAKE) -C $(KERNEL_BUILD) M=$(PWD) \
INSTALL_MOD_PATH=$(INSTALL_ROOT) modules_install
and then you can issue
sudo make install
this will put it either in /lib/modules/$(uname -r)/extra/
or /lib/modules/$(uname -r)/misc/
and run depmod appropriately
i think there should be entry of your your_module.ko in /lib/modules/uname -r/modules.dep and in /lib/modules/uname -r/modules.dep.bin for "modprobe your_module" command to work
Try insmod instead of modprobe. Modprobe
looks in the module directory /lib/modules/uname -r for all the modules and other
files
Ensure that your network is brought down before loading module:
sudo stop networking
It helped me - https://help.ubuntu.com/community/UbuntuBonding
Insert this in your Makefile
$(MAKE) -C $(KDIR) M=$(PWD) modules_install
it will install the module in the directory /lib/modules/<var>/extra/
After make , insert module with modprobe module_name (without .ko extension)
OR
After your normal make, you copy module module_name.ko into directory /lib/modules/<var>/extra/
then do modprobe module_name (without .ko extension)
Related
So, I was trying to install a hello world kernel shown the book "Linux Device Drivers" by Corbet, Jonathan.
This is the code for the file hello.c
#include <linux/init.h>
#include <linux/module.h>
MODULE_LICENSE("Dual BSD/GPL");
static int hello_init(void) {
printk(KERN_ALERT "Hello World!!\n");
return 0;
}
static void hello_exit(void) {
printk(KERN_ALERT "Good Bye Module!!\n");
}
module_init(hello_init);
module_exit(hello_exit);
To build it, I use this makefile:
obj-m += hello.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
After running
make all
sudo insmod ./hello.ko
and I have the error
ERROR: could not insert module Operation not permitted
Installing a kernel space module with root privileges. Also tried
sudo su
sudo insmod ./hello.ko
Also tried
sudo modprove -v hello.ko
With similar error.
So, there are several things going on, the main issue is that your computer(usually a laptop) have the secure boot option enabled in the bios.
This usually does the trick, BUT, in some notebooks, the option does not appear(or is disabled) until you set the administration password for the bios.
If after changing the secure boot option to disabled sometimes is not enough. In some newer Intel laptops, you need to disable the Intel Platform Trust Technology also from the BIOS.
Finally, you can run insmod or modprobe without problem.
To check the output of printk(KERN_ALERT "Hello World!!\n"); you need to do a
tail -f /var/log/kern.log
That should work.
I have a slight problem with a Linux module compilation. No matter where I put a -lhidapi-libusb library reference in the make command, the module just refuses to compile. I know I'm doing something wrong, please help me, if you have some time.
Thanks
obj-m += light.o
all:
make -lhidapi -libusb -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -lhidapi -libusb -C /lib/modules/$(shell uname -r)/build M=$(PWD)
Output:
fatal error: hidapi/hidapi.h: No such file or directory
#include <hidapi/hidapi.h>
What you're trying to do doesn't make sense, and will not work.
libusb and HIDAPI are userspace libraries. They cannot be used within a kernel module.
You need to actually install the hidapi header library:
$ sudo apt install libhidapi-dev
https://github.com/libusb/hidapi#installing-hidapi
I'm trying to compile a simple hello world module following this guide and I'm confused about what the Makefile is actually doing.
obj-m += hello-1.o
all:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
I understand that when i type the make command it will run the all recipe which runs make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules. So now it runs the Makefile found at the path given after the -C flag but what does the M=$(PWD) modules do?
'obj-m' :- specifies object files which are built as loadable
kernel modules.
'all and clean' :- If you run 'make' by default it will run "all :".
But we can use all and clean with make. it will run only those specific command.
Example :-
'make all' will run "make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules"
'make clean will run "make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean"
3.'uname -r' :- get name and information about current kernel.
Example :- for me, my kernel is "4.6.0-rc1".
Option ‘-C dir’ :- Change to directory dir before reading the makefiles.
Example :- "make -C /lib/modules/$(shell uname -r)/build" will change to "make -C /lib/modules/4.6.0-rc1/build.
'$pwd':- get the path of your current directory.
Now you want to create your loadable module by using "make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules".
Your source code need environment to run. That's why we have to use -C option to change build directory. Which have all needed definition, header file, Macro and etc. Now after changing to build directory you need to tell where is your module present, that's why we are using M=$PWD.
To compile kernel module, the make command you normally need is in this form:
make -C /lib/modules/3.16.0-70-generic/build M=/home/test/ldd3/hello modules
in which, -C means switching to another path.
/lib/modules/3.16.0-70-generic/
is the path to the kernel in used, and
/home/test/ldd3/hello
is where the source of your module resides.
what does the M=$(PWD) modules do?
So as I said M=$(PWD) is simply a shell variable that stores the current path to your kernel module. make needs to store this as it switches to the kernel build path.
The functions you write to provide procfs interfaces is just code that is part of your LKM source.
http://linux.die.net/lkmpg/x769.html has a simple example using procfs, reproduced here:
I copied the code from above link -
You'll find a tutorial for building kernel modules at http://www.cyberciti.biz/tips/compiling-linux-kernel-module.html. The summary of that is:
1) Ensure you have kernel source installed in /usr/src.
2) Create a makefile that looks like:
obj-m = procfs2.o
KVERSION = $(shell uname -r)
all:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean
3) build the module with the command make 4) load the module into memory with the command insmod procfs2.ko (do this as the root user)
I copied the code and created the MAKEFILE and later if I give the make command from the console then it is showing as : make: nothing to be done for all. could someone please tell me what could be the error ??
Here is an example of a Makefile for a kernel module.
the important thing here to note is that the dots shown below must be replaced by a TAB, replacing them by spaces will cause Makefile to malfunction.
obj-m += hello.o
all:
.......make -C /lib/modules/$(shell uname -r)/build M=$(PWD) modules
clean:
.......make -C /lib/modules/$(shell uname -r)/build M=$(PWD) clean
I try to compile simple linux kernel module:
#include <linux/module.h>
#include <linux/kernel.h>
int init_module(void)
{
printk("Hello world 1.\n");
return 0;
}
void cleanup_module(void)
{
printk(KERN_ALERT "Goodbye world 1.\n");
}
My makefile:
obj-m = testmodule.o
KVERSION = $(shell uname -r)
all:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean
Now i haven't errors in my .c file.
But when i try make in terminal: make: Nothing to be done for `all'.
What's wrong?
Thank you.
The default command in your makefile is
make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
That instructs make to cd to /lib/modules/$(KVERSION)/build and run
make module m=YOUR_CURRENT_DIR
In turn, that makefile is not finding anything to do. Presumably, that makefile expects to find some particular structure in your current directory.
You need to more carefully read whatever instructions led you to set up this makefile.
You really don't give enough information to determine the correct answer, but I'll give you some things to look into.
How are you compiling it? Do you have the correct include path in your build? Build paths are specified with the -I option to gcc. Make sure you are pointing to your kernel source tree.
Have you build the kernel? When you do a make, certain things are setup that allows you to build. Doing a make doesn't build everything (like modules) but will get the initial stuff setup for you.
Make sure your have your distributions the kernel header/development packages installed that provide these include files.
If they are installed, search where these include files are located on your computer and add these directories to your compilers include search path (the -I option).
This is because your Makefile contains no tab before giving make command
make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
So normally your file should be like below:
obj-m = test.o
KVERSION = $(shell uname -r)
all:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) modules
clean:
make -C /lib/modules/$(KVERSION)/build M=$(PWD) clean