No output to terminal after inserting a module with insmod - c

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.

Related

Cannot use a Makefile to comple kernel files in Ubuntu Linux on WSL

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

Initialization and Cleanup are swapped around in Kernel Module

Currently studying kernel modules, and we tasked with writing a small Hello World / Bye World kernel module (in C). Got the idea pretty quick and had a rough idea of what I should do.
Needed to make the initialization function print a Hello message, and the clean up function to print a Bye message. The initialization message should print when I add the kernel module to the list of modules (working on a Debian VM) using insmod, and the cleanup message should print when I remove the module using rmmod.
Here is a snippet of the code:
#define MODULE
#define LINUX
#define __KERNEL__
#include <linux/module.h> // all modules
#include <linux/kernel.h> // KERN_ALERT and potentially other priorities
#include <linux/init.h> // macros
static int __init do_initialization(void) {
printk(KERN_ALERT "Hello World :)");
return 0;
}
static void __exit do_cleanup(void){
printk(KERN_ALERT "Bye bye :)");
}
module_init(do_initialization);
module_exit(do_cleanup);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("A");
MODULE_DESCRIPTION("Exercise");
MODULE_VERSION("1.00");
This is the Makefile I use (this was provided to us but I understand most of it):
obj-m += mymodule.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
NB: I use KERN_ALERT instead of KERN_INFO just to make sure that it displays on my terminal regardless.
My problem lies in the following:
When I run insmod mymodule.ko, the Bye Bye message is printed. When I run rmmod mymodule.ko, the Hello message is printed. It really doesn't make any sense to me, and I made sure that my functions are correctly set inside the macros.
Any help is appreciated.
As indicated by the link that Tsyvarev added as a comment to the question on 1st March 2021, and by the answer by Roi on 2nd March 2021, I simply needed to add \n when logging the kernel. Thank you to everyone who helped.

"Segmentation fault" when `rmmod` or `modprobe -r`

Trying the simplest kernel module from LDD3 without any modification on custom built kernel v4.1.0-rc6 for Beagle Bone board with BusyBox v1.23.0. The code for the module is as follows:
#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);
The Makefile is:
ARCH := arm
CROSS_COMPILE := arm-cortex_a8-linux-gnueabi-
obj-m := hello.o
all:
make ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C /path/to/linux/source/tree M=$(PWD) modules
clean:
make ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILE) -C /path/to/linux/source/tree M=$(PWD) clean
The module is compiling and installing on the rootfs just fine. also it is loading:
$ insmod hello.ko
[ 30.692404] Hello, world
But when trying to remove it, I am getting:
$ rmmod hello.ko
Segmentation fault
$modprobe -r hello.ko
Segmentation fault
$ lsmod
hello 813 0 - Live 0xbf000000 (O)
The kernel is compiled with module unloading (both regular and forced) support enabled.
What can be the possible cause of this issue? What is the way to approach the investigation of it?
Update:
As suggested in the comments I have tried including linux/kernel.h, defining the MODULE,LINUX and __KERNEL__ symbols. Added the__init and __exit prefixes to the functions. Removed the static modifiers. Removed the printk lines. The result the same. dmesg shows only the initial greeting. Loading and unloading of the kernel's modules such a gpio_keys or crypto/ccm is working, surprisingly. So the only thing remaining to suspect is the way the module is compiled..
Update 2
Updating the kernel to the freshest snapshot didn't help. Compiled the module with different optimization settings didn't help. Next step, I guess, I am going to modify the BusyBox's rmmod to have some indication of the problem location..
Have a look at these tutorials:
http://www.tldp.org/HOWTO/Module-HOWTO/x839.html
http://www.tldp.org/LDP/lkmpg/2.4/html/x281.htm
Try adding:
#define MODULE
#define LINUX
#define __KERNEL__
#include <linux/kernel.h> /* Needed for KERN_ALERT */
I have managed to work around this problem. Using strace I've found out that the segfault is occurring somewhere when reading the BusyBox specific modules.dep.bb file. This file is used by BusyBox when it is compiled with the "Simplified modutils" option (CONFIG_MODPROBE_SMALL). By disabling the option, selecting the utils to be installed and rebuilding BusybBox I've got the module unloading work. I believe the problem root is near the fact the test module is compiled and stored outside the /lib/..../modules directory, so busybox with the simplified modutils is just getting confused.

insmod error in kernel module programming

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

Why doesn't my hello world driver module print anything?

I'm very new to kernel module programming and right now I'm trying to run the most basic hello world module program, however I could not get any output.
I have written the hello world program introduced in Linux Device Drivers 3rd ed and got some help from this website and this one.
hello.c
#include <linux/module.h>
#include <linux/kernel.h>
MODULE_LICENSE("GPL");
static int hello_init(void){
printk("<1>Hello, world!\n");
return 0;
}
static void hello_exit(void){
printk(KERN_ALERT "Goodbye, world..\n");
}
module_init(hello_init);
module_exit(hello_exit);
The file is in /home/volkan/drive directory. Along with the c file, I have my Makefile
Makefile
obj-m += hello.o
From the terminal, I execute this command for compiling the module:
sudo make -C /lib/modules/3.8.0-19-generic/build M=/home/volkan/drive/ modules
Resulting in:
make: Entering directory `/usr/src/linux-headers-3.8.0-19-generic'
CC [M] /home/volkan/drive/hello.o
Building modules, stage 2.
MODPOST 1 modules
CC /home/volkan/drive/hello.mod.o
LD [M] /home/volkan/drive/hello.ko
make: Leaving directory `/usr/src/linux-headers-3.8.0-19-generic'
I assume up to this point, nothing went wrong. Now, I insert my module and then remove:
volkan#Varaquilex ~/drive $ sudo insmod ./hello.ko
volkan#Varaquilex ~/drive $ sudo rmmod hello
volkan#Varaquilex ~/drive $
There is no output. I also have little experience in linux, so explanatory answers are more than welcome. Am I doing something wrong? Why cannot I see any output?
The kernel messages are logged in the kern.log file located in /var/log. Depending on your system, it may also be in dmesg. So you have to cat accordingly.
Use the command cat /var/log/kern.log
Dec 9 18:51:10 Varaquilex kernel: [ 2818.079572] <1>Hello, world!
Dec 9 18:55:02 Varaquilex kernel: [ 3050.256134] Goodbye, world..

Resources