I am just starting with modular programming.
Above are my two files:
hello.c
#include <linux/init.h>
#include <linux/module.h>
static int hello_init(void)
{
printk(KERN_ALERT "TEST: Hello world\n");
return 0;
}
static void hello_exit(void)
{
printk(KERN_ALERT "TEST: Good Bye");
}
module_init(hello_init);
module_exit(hello_exit);
Makefile
obj-m += hello.o
KDIR = /usr/src/linux-headers-3.13.0-46-generic
all:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
rm -rf *.o *.ko *.mod.* *.symvers *.order
And here's my terminal output showing error in insmod command, kindly help.
anubhav#anubhav-Inspiron-3421:~/Desktop/os$ make
make -C /usr/src/linux-headers-3.13.0-46-generic SUBDIRS=/home/anubhav/Desktop/os modules
make[1]: Entering directory `/usr/src/linux-headers-3.13.0-46-generic'
Building modules, stage 2.
MODPOST 1 modules
make[1]: Leaving directory `/usr/src/linux-headers-3.13.0-46-generic'
anubhav#anubhav-Inspiron-3421:~/Desktop/os$ insmod hello.ko
insmod: ERROR: could not insert module hello.ko: Operation not permitted
If you have secure boot enabled, the newer kernels won't allow inserting arbitrary kernel modules. So, either you can disable secure boot in your BIOS or you need to sign the kernel modules you want to install.
Steps to securely sign your kernel modules:
Create a X509 certificate that can be imported in firmware
Enrolling the public key just created
Sign the module you want to install
Install the module
You need to be root to do steps 2 & 4. The detailed process is described in a nice Ubuntu blog.
As isowen mentioned only root can load or unload the module.
You see the print in hello_init() when you do insmod hello and you see the print in hello_exit() when you do rmmod hello.
execute cat /proc/sys/kernel/modules_disabled and if you see the result
1 then execute echo 'kernel.modules_disabled=1' >> /etc/sysctl.d/99-custom.conf then reboot and try again. ;) BR nu11secur1ty
Related
I have some C code and a Makefile for that C code. The C program is called simple.c and the the makefile is just called Makefile.
Here are the contents of simple.c
#include <linux/init.h>
#include <linux/kernel.h>
#include <linux/module.h>
/* This function is called when the module is loaded. */
int simple_init(void)
{
printk(KERN_INFO "Loading Kernel Module\n");
return 0;
}
/* This function is called when the module is removed. */
void simple_exit(void)
{
printk(KERN_INFO "Removing Kernel Module\n");
}
/* Macros for registering module entry and exit points. */
module_init(simple_init);
module_exit(simple_exit);
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Simple Module");
MODULE_AUTHOR("SGG");
And this is the content of the Makefile:
obj-m += simple.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 have both of them in the same directory and I use the instruction make to compile it however it does not work and I get this error message:
make -C /lib/modules/5.15.79.1-microsoft-standard-WSL2/build M=/home/eddie modules make[1]: *** /lib/modules/5.15.79.1-microsoft-standard-WSL2/build: No such file or directory. Stop. make: *** [Makefile:3: all] Error 2
I have tried to install some things I have seen online for linux kernal but they do not seem to work.
I have tried the following:
sudo apt install linux-tools-virtual hwdata
sudo apt-get install linux-headers-$(uname -r)
It's important to note that these all do sucessfully install. When I use lsmod to list all current kernal modules nothing is listed.
Am I doing anything wrong? Missing a command to install something? I am using Ubuntu Linux subsystem for linux on windows 11
I am on Linux Ubuntu 14.04. I want to start Linux Kernel Module Programming. I have hello.c (simple Hello World module) and Makefile. But, on "make" command, I get error.
I tried Cannot use CONFIG_CC_STACKPROTECTOR_STRONG: -fstack-protector-strong not supported by compiler , but it did not work for me.
hello.c
/* hello.c − Illustrating the __init, __initdata and __exit macros. */
#include <linux/module.h>
/* Needed by all modules */
#include <linux/kernel.h>
/* Needed for KERN_INFO */
#include <linux/init.h>
/* Needed for the macros */
static int hello3_data __initdata = 3;
static int __init hello_3_init(void)
{
printk(KERN_INFO "Hello, world %d\n", hello3_data);
return 0;
}
static void __exit hello_3_exit(void)
{
printk(KERN_INFO "Goodbye, world 3\n");
}
module_init(hello_3_init);
module_exit(hello_3_exit);
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
On "make" :-
k#k-Inspiron-3542:~/Kernel programs$ make
make -C /lib/modules/4.2.0-27-generic/build M=/home/k/Kernel programs modules
make[1]: Entering directory `/usr/src/linux-headers-4.2.0-27-generic'
arch/x86/Makefile:138: CONFIG_X86_X32 enabled but no binutils support
Makefile:662: Cannot use CONFIG_CC_STACKPROTECTOR_REGULAR: -fstack-protector not supported by compiler
make[1]: *** No rule to make target `programs'. Stop.
make[1]: Leaving directory `/usr/src/linux-headers-4.2.0-27-generic'
make: *** [all] Error 2
Currently, my ubuntu has 4.2 kernel. I even tried this on 3.x kernel, but there was this same error.
Please help me in this. Thanks. :)
I had searched a lot before asking this question, but no solution worked for me. I continued my search and finally, this solution worked for me. https://askubuntu.com/questions/367838/compiling-error-while-installing-realtek-rtl8111e-in-64-bit-13-10-config-x86-x
Strangely, there should be no space(s) in the directory name in which kernel modules are there. So, I removed the space and it worked.
Hope it will help someone in future. :)
Your file works OK here. With your Makefile, and with the default Makefile:
obj-m := hello.o
KDIR := /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
default:
$(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
clean:
$(MAKE) -C $(KDIR) M=$(PWD) clean
The files hello.ko, hello.mod.c, hello.mod.o, hello.o, modules.order, Module.symvers are created. May be install this: sudo apt install g++ binutils-dev
If you don't have spaces in your compile directory and you're still getting this error, your kernel compilation may be failing because its directory belongs to root and you're running as an unprivileged user. Try sudo make
I am a beginner in linux kernel development and trying to load a simple module in linux.
I have created an hello.c file, to be loaded as kernel module.
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("A Simple Hello World module");
static int __init hello_init(void)
{
printk(KERN_INFO "Hello world!\n");
return 0;
}
static void __exit hello_cleanup(void)
{
printk(KERN_INFO "Cleaning up module.\n");
}
module_init(hello_init);
module_exit(hello_cleanup);
this hello.c and the makefile both, I have kept in /home/linux/ directory.
makefile
obj-m +=hello.o
src= /usr/src/linux-headers-3.5.0-17-generic
all:
$(MAKE) -C $(src) SUBDIR-$(PWD) modules
clean:
rm -rf *.o *.ko
to generate .ko file, when I run the make command on terminal from the /home/linux directory , I get following error
h2o#h2o-Vostro-1015:~/linux$ make
make -C /usr/src/linux-headers-3.5.0-17-generic SUBDIR-/home/h2o/linux modules
make[1]: Entering directory `/usr/src/linux-headers-3.5.0-17-generic'
make[1]: *** No rule to make target `SUBDIR-/home/h2o/linux'. Stop.
make[1]: Leaving directory `/usr/src/linux-headers-3.5.0-17-generic'
make: *** [all] Error 2
kindly advise what am I missing or doing wrong..
Makefile
obj-m := hello.o # Module Name is hello.c
KDIR := /lib/modules/$(shell uname -r)/build
all: $(MAKE) -C $(KDIR) M=$(PWD) modules
clean: $(MAKE) -C $(KDIR) M=$(PWD) clean $(RM) Module.markers
modules.order
its not guaranteed that headers file will always be located in /usr/src directory, but it will surely be located in /lib/modules directory.
make sure that system has latest header files
to find out which header files to be present
run `
uname -r
on terminal, output will be like
3.5.0-17-generic
to install header files run
sudo apt-get install linux-headers-$(uname -r)
You have:
$(MAKE) -C $(src) SUBDIR-$(PWD) modules
But it seems like you want:
$(MAKE) -C $(src)/SUBDIR-$(PWD) modules
Or something along those lines; where does the source code live? You need to -C there.
Kernel build system is a bit complex. It would be good to read the kernel build process documentation. Which gives better understanding about, say,
Targets like --- modules / modules_install
Options like --- -C $KDIR / M=$PWD
Command Syntax ---
$ make -C <path_to_kernel_src> M=$PWD
$ make -C /lib/modules/uname -r/build M=$PWD
$ make -C /lib/modules/uname -r/build M=$PWD modules_install
Loadable module goals --- obj-m
etc...
I have an openvz machine which I am root on, it is a virtual machine I am ssh to:
>uname -a
Linux molo 2.6.32-042stab084.25 #1 SMP Wed Feb 12 16:04:42 MSK 2014 x86_64 x86_64 x86_64 GNU/Linux
I am trying to build an hello world kernel module:
hello.c:
#include <linux/module.h> /* Needed by all modules */
#include <linux/kernel.h> /* Needed for KERN_INFO */
#include <linux/init.h> /* Needed for the macros */
static int __init hello_start(void)
{
printk(KERN_INFO "Loading hello module...\n");
printk(KERN_INFO "Hello world\n");
return 0;
}
static void __exit hello_end(void)
{
printk(KERN_INFO "Goodbye Mr.\n");
}
module_init(hello_start);
module_exit(hello_end);
Makefile:
obj-m = hello.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
And when I am trying to compile hello.c:
#make
make -C /lib/modules/2.6.32-042stab084.25/build M=/local/my_modules modules
make: *** /lib/modules/2.6.32-042stab084.25/build: No such file or directory. Stop.
make: *** [all] Error 2
That is the kernel version uname -r reports
#uname -r
2.6.32-042stab084.25
The following didn't help too:
$sudo apt-get install "linux-headers-$(uname -r)"
Reading package lists... Done
Building dependency tree
Reading state information... Done
E: Unable to locate package linux-headers-2.6.32-042stab084.25
E: Couldn't find any package by regex 'linux-headers-2.6.32-042stab084.25'
Here is the /lib/modules directory:
ls /lib/modules/2.6.32-042stab084.25/
modules.alias modules.ccwmap modules.dep.bin modules.ieee1394map modules.isapnpmap modules.pcimap modules.softdep modules.symbols.bin
modules.alias.bin modules.dep modules.devname modules.inputmap modules.ofmap modules.seriomap modules.symbols modules.usbmap
Download and install linux-headers package from openvz page (more on http://openvz.org/Installation_on_Debian)
1) Add source
cat << EOF > /etc/apt/sources.list.d/openvz-rhel6.list
deb http://download.openvz.org/debian wheezy main
# deb http://download.openvz.org/debian wheezy-test main
EOF
2) Install
wget http://ftp.openvz.org/debian/archive.key
sudo apt-key add archive.key
sudo apt-get update
sudo apt-get install "linux-headers-$(uname -r)"
Remember that you can only do this from the "Host", not from inside of a OpenVZ VPS. Meaning that loading kernel drivers to kernel is only permitted from the Host and would affect all containers on that Host.
Your kernel doesn't appear to be one of the ones provided by Canonical, usually official kernels end with a version number or with the generic or other suffix.
Usually you find the package with the kernel headers under pool/main/l as you can see here in the case of the security repository for Ubuntu Saucy.
You should ask the question to the person that provided the kernel that you are using, there is not that much you can do without more information unless you are willing to go for an officially supported kernel.
I am following the following tutorial, trying to learn how to develop device drivers, and in Chapter 2, the focus is to develop a working module and insert it into the kernel. I used the following code (hello.c):
#include <linux/init.h>
#include <linux/module.h>
#include <linux/kernel.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 my this is the 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
I then run the following in LXTerminal:
brian#brian-desktop:~/driver_stuff/hello$ su
root#brian-desktop:/home/brian/driver_stuff/hello# make
make -C /lib/modules/2.6.32-21-generic/build M=/home/brian/driver_stuff/hello modules
make[1]: Entering directory `/usr/src/linux-headers-2.6.32-21-generic'
Building modules, stage 2.
MODPOST 1 modules
make[1]: Leaving directory `/usr/src/linux-headers-2.6.32-21-generic'
root#brian-desktop:/home/brian/driver_stuff/hello# insmod ./hello.ko
root#brian-desktop:/home/brian/driver_stuff/hello# rmmod hello
root#brian-desktop:/home/brian/driver_stuff/hello# exit
However, after the insmod ./hello.ko command, one should expect that the terminal would print "Hello world!" and then "Goodbye, cruel world!" after the rmmod hello command. The book mentioned that this happens when you run the commands in the console, but not in an emulated terminal, could this be the problem?
I also checked under /var/log/messages and /var/log/messages.1 which had no record of either "Hello World!" nor "Good bye, cruel world!". Is it possible that these messages are in a different file, or is the issue that the messages aren't being pushed to the kernel in the first place?
If you need an info about the kernel I am running (Lubuntu 10.04, inside a VM):
brian#brian-desktop:~/driver_stuff/hello$ uname -r
2.6.32-21-generic
Thank you.
The output from kprintf is always to the kernel log. This may happen to also go to the system console (and, therefore, to the terminal you're using if you're on the console), but there's nothing to link it back to the specific terminal that you loaded the module in.
To read the kernel log, run dmesg.