Device drivers in Linux serve as intermediary software components, facilitating communication between the operating system and hardware devices. They abstract hardware complexities, providing a standardized interface for user activities while remaining flexible to accommodate diverse usage scenarios. By separating mechanism from policy, drivers enable efficient hardware access and simplify maintenance. Additionally, many drivers are accompanied by user programs for configuration and access, enriching the ecosystem with utilities and graphical interfaces.
Things written in kernel space don't see glibc library ---> so kernel provides equivelent functions in kernel space.
ex:
printf
in glibc ==printk
in kernel space
main.c
#include <linux/module.h>
#include <linux/init.h>
//Meta information
MODULE_LICENSE("GPL");
MODULE_DESCRIPTION("Second Driver");
MODULE_AUTHOR("HEMA");
static int __init hellodriver_init(void)
{
printk("Hello, world\n");
return 0;
}
static void __exit hellodriver_exit(void)
{
printk("Goodbye, world\n");
}
module_init(hellodriver_init);
module_exit(hellodriver_exit);
module_init
serves as the entry point for kernel modules, initializing resources and registering device drivers upon module loading. Unlike in GCC where the startup code searches for the main function, in kernel builds, it looks for module_init as the entry point, executing the specified function at the start of the program.
module_exit
serves as the exit point for kernel modules, releasing resources and unregistering device drivers before unloading the module. Similar to module_init, it defines a function that is executed at the end of the program's execution.
static int __init
to put the function hellodriver_init
---> .init section in memory , after executing that function it will be removed from Memory to save resources.
static void __exit
to put the function hellodriver_exit
---> .exit section in memory , after executing that function it will be removed from Memory to save resources.
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
obj-m
build as a dyanmic module (can load and unload)
, obj-y
build as a static module (comiled as a part with zImage)
make -C /lib/modules/$(shell uname -r)/build
---> i want this make to use Makefile of the linux kernel.
uname -r
refers to ---> 6.5.0-27-generic
the version of linux in my device
modules
just do this task in the Makefile of the kernel
clean
just do this task in the Makefile of the kernel
make
- After that will appear the kernel module hello.ko that will be inserted to the kernel
sudo insmod hello.ko
dmesg
it will print hello, world
sudo rmmod hello
dmesg
it will print Goodbye, world
so it's the function executed when the driver removed from the kernel.
you have to put \n in printk()
function
Using \n in printk() ensures each log message appears on a new line in the kernel log file.
Omitting \n may cause subsequent log messages to concatenate, making it hard to read the log file with dmesg.
Including \n maintains clear and organized log output, aiding in effective debugging and system monitoring.