The concept of user space and kernel space is bit abstract.
This is a set of addresses where the kernel is hosted and where it runs. Kernel memory (or kernel space) is a memory range, owned by the kernel, protected by access flags, preventing any user apps from messing with the kernel.
On the other hand, the kernel can acees the whole system memory, since it runs with the higher priority on the system. In kernel mode, the CPU can access the whole memory.
This is a set of addresses (locations) where normal programs are restricted to run. In user mode, the CPU can only access memory tagged with user-space access rights. The only way for the user app to run into the kernel space is through system calls. Some of these are read, write, open, close, mmap and so on. User-space code can runs with lower priority. When a process perfoms a system call, a software interrupt is sent to the kernel, which turns on privileged mode so that the process can run in kernel space. When the system call returns, the kernel truns off the privileged mode and the process is jailed again.
A module is to the Linux Kernel what a add-on to google chrome. Most of the kernel modules are plug and play. It dynamically extends the kernel functionalities without even the need to restart the computer. In order to support modules, the kernel must have benn built with the following option enabled:
CONFIG_MODULES=y
If you want some module to be loaded at boot time, just create the file /etc/modules-load.d/filename.conf, and add the module's name that should be loaded, one per line. <filename> should be meaningful to you.
An example of /etc/modules-load.d/my_modules.conf is as follows:
#This line is a commentiwlwifimy_moduleThe depmod utility doesn't only build modules.dep and modules.dep.bin files. It does more than that. When a kernel developer actually writes a driver, they knwo exactly what hardware the driver will support. They are the reponsible for feeding the driver with the product and vendor IDs of all devices supported by the driver. depmod also processes module files in order to extract and gather that information, and generates a modules.alias file, located in /lib/modules/<kernel_release>/modules.alias, which will map devices to their drivers.
helloworld.c:
# include <linux/init.h># include <linux/module.h># include <linux/kernel.h>static int __init helloworld_init(void) { pr_info("Hello world!\n"); return 0;}static void __exit helloworld_exit(void) { pr_info("Bye world!\n");}module_init(helloworld_init);module_exit(helloworld_exit);MODULE_AUTHOR("Oscar Gomez Fuente <oscargomezf@gmail.com>");MODULE_LICENSE("GPL");And ELF(Executable and Linkable Format) is made of various named sections. One can run:
$ objdump -h module.koIn order to print out different sections that constitute the given module.ko. Only a few of the sectionsin the caption are standard ELF sections:
Other sections are added by demand for the kernel purpose. The most important are .modinfo sections.
Makefile for compile your helloworld
obj-m += helloworld.oKVERSION = $(shell uname -r)KLIB_PATH = /lib/modules/$(KVERSION)/buildEXTRA_CFLAGS += -DDEBUGall: echo $(obj-m) make -C $(KLIB_PATH) M=$(PWD) modulesclean: make -C $(KLIB_PATH) M=$(PWD) cleanModule license, author(s) and description
MODULE_LICENSE("GPL");MODULE_AUTHOR("Oscar Gomez Fuente <oscargomezf@gmail.com");MODULE_DESCRIPTION("This is a description");A kernel can accept arguments from the command line. This allows dynamically changin the behaviour of the module according to given parameters, and can help the developer not having to indefinitely change/compile the module during a test/debug session. The macro uses for this purpose is module_param(), this macro is defined in include/linux/moduleparam.h (This should be include in the code too: #include </linux/moduleparam.h>). This macro contains the following elements:
One can use eventually a | (OR operation) to set multiple permissions. If perm is 0, the file parameter in sysfs will not be created. You should use only S_IRUGO read-only parameters, which I highly recommend.
You can use the macro MODULE_PARM_DESC in order to describe each of them. This macro will populate the module info section with each parameter's description.
static short int myshort = 1;static int myint = 420;static long int mylong = 9999;static char *mystring = "blah";static int myintArray[2] = { -1, -1 };static int arr_argc = 0;module_param(myshort, short, S_IRUSR | S_IWUSR | S_IRGRP | S_IWGRP);MODULE_PARM_DESC(myshort, "A short integer");module_param(myint, int, S_IRUSR | S_IWUSR | S_IRGRP | S_IROTH);MODULE_PARM_DESC(myint, "An integer");module_param(mylong, long, S_IRUSR);MODULE_PARM_DESC(mylong, "A long integer");module_param(mystring, charp, 0000);MODULE_PARM_DESC(mystring, "A character string");module_param_array(myintArray, int, &arr_argc, 0000);MODULE_PARM_DESC(myintArray, "An array of integers");One could have used modinfo prior loading the module in order to display description of parameters suppoertes by the module:
$ modinfo name_module.ko