Brief summary of Linux kernel module programming

Source: Internet
Author: User
Summary

Linux Kernel module programming materials are complicated, some are too simple, some are too complex, I try to use the form of notes to show readers how to process LINUX module programming, trying to make it simple
Clearly, this article is also a piece of information I have forgotten, so it is inevitable that it is too simple in some places. The purpose of this article is to let users know about it. For more information, see
There is no better information than Linux kernel source.

Applicability:

  • Linux kernel> = 2.6.0

Introduction to Linux

First, this module is different from the microkernel module. The microkernel module is a daemon process, which works for users.
Space, the LINUX module is only the target code of the kernel. The kernel integrates it into the kernel by executing the runtime connection.
It does not change the Linux kernel to monolithic OS, and its module also works in the kernel mode and enjoys all the privileges of the kernel.

As to why Linux kernle module (lkm) should be introduced, I would like to have at least a few points:

  • Modular programming needs to reduce development and maintenance costs.
  • Enhances system flexibility, so that you do not have to recompile the kernel or restart the system to modify some kernel functions.
  • Reduces the complexity of kernel programming and lowers the entry threshold.

Related macros and header files

Lkm must contain the following header files: <Linux/kernel. h> <Linux/module. h>

The following macros must be defined: __kernel __, Module

Example of a simple kernel module
/*file:   hello.c*/
#ifndef __KERNEL__
#define __KERNEL__
#endif
#ifndef MODULE
#define MODULE
#endif
#include <linux/module.h>
#include <linux/kernel.h>
static int __init hello_init(void)
{
printk(KERN_ALERT "Hello, my LKM./n");
return 0;
}
static void __exit hello_exit(void)
{
printk(KERN_ALERT "Bye, my LKM./n");
}
module_init(hello_init);
module_exit(hello_exit);

It's a simple answer, isn't it? This lkm function is actually very simple, that is, when loading it through insmod, it prints hello, my
Lkm. Print bye, my
Lkm. A basic kernel module generally contains two functions. One is the initialization function (for example, hello_init) and the other is the unmount function (hello_exit ),
Of course, there can be no function, but some variables are provided. However, the initialization and uninstallation functions must appear in pairs. And when the init function is successful, the return value is greater than or equal to zero. When the operation fails
Non-zero. Macro module_init and module_exit are used to register the initialization function and uninstall the function.

Lkm Compilation

The makefile example is as follows:

obj-m := hello.o 
KERNELBUILD := /lib/modules/`uname -r`/build
default:
make -C $(KERNELBUILD) M=$(shell pwd) modules
clean:
rm -rf *.o .*.cmd *.ko *.mod.c .tmp_versions

If there are other modules under this directory, you just need to add them after hello. O.

obj-m := hello.o mod.o

Execute make in the directory where the module is located. After successful execution, we can get the desired module (hello. Ko.

If a module has many source files, such as hello, which are connected by hello1.c hello2.c, add the following lines to makefile:

hello-objs := hello1.o hello2.o

Lkm Loading

Linux provides modutils for users to manipulate modules. This tool set mainly includes:

Insmod installation Module
Rmmod Delete Module
Modprobe is more advanced in loading and deleting modules, which can solve the dependencies between modules.
Lsmod lists the loaded modules and their information
Modinfo is used to query information about a module, such as the author, copyright...

Try to use the command insmod hello. Ko to load the module and rmmod to delete the module and see what happened. You may not see any output. Is there an error? No. Run the command tail/var/log/message. Why?

Feb 19 00:07:35 gentux Hello, my LKM.
Feb 19 00:07:38 gentux Bye, my LKM.

Other module information

The commonly used information often includes author, description, and copyright. Therefore, lkm provides the following macros for us:

Module_author ("author ");
Module_description ("the description ");
Module_license ("GPL ");
Module_supported_device ("Dev"); // The device supported by the device driver.

The commonly used free licenses include "GPL", "GPL V2", "GPL and additional rights", "dual BSD/GPL", and "dual MPL/GPL ".

Module Parameters

The user space applications can accept user parameters, and the lkm can do the same, but the method is somewhat different. Related macros include:

MODULE_PARM(var, type);
MODULE_PARM_DESC(var, "the description of the var");

There are several types of module parameters (that is, type in module_parm:

  • B byte (unsigned char)
  • H short
  • I int
  • L long
  • S string (char *)

It is best to have default values for these parameters. If some parameters are not set, you can reject module loading by returning a negative value in the init function specified by module_init.
Lkm also supports array modules. If the number N is added before the type symbol, it indicates the array with the maximum number n, the numbers separated by "-" represent the minimum and maximum array lengths respectively.

Example:
Module_parm (VAR, "4I"); // integer array with a maximum length of 4
Module_parm (VAR, "2-6i"); // an integer array with a minimum length of 2 and a maximum length of 6

How to Use insmod to pass in the parameter is actually man, but now man is too simple, so here is a description:

insmod variable=value[,value2...] ...

Value can be enclosed in quotation marks or not used. But there is a bit of "=" and there cannot be spaces before and after, and there cannot be spaces in the value.

Module symbol Export

Unlike applications in a user space, the purpose of introducing a module is often to provide some routine to the kernel for specific functions. Few modules do not export any symbols, therefore, Linux provides the following macros for users:

Export_symbol (VAR); // output the symbol VaR
Export_symbol_gpl (VAR); // The copyright of the output symbol is GPL.

Dependencies between modules

Sometimes there may be dependencies between the two modules. Module A to be loaded depends on Module B. At this time, insmod is powerless and can only be used to load modules and their dependent modules, otherwise, you can only manually load them one by one.

Modprobe reads/lib/modules/version/modules generated by depmod-. dep to obtain the list of dependent modules (or a module tree), and then call insmod to load them one by one in sequence.

Namespace Problems
  1. We recommend that you use static to modify the global symbol that does not require export to restrict its scope to this file to prevent contamination of the kernel namespace.
  2. It is best to use extern to modify some symbrs of the kernel or other modules to show that they are not in this file.
  3. When the errno variable may be used, because the kernel does not have the export symbol, it can only be customized by users, such as: int errno;

A complicated module example
/* File: Hello. C */
# Ifndef _ KERNEL __
# DEFINE _ KERNEL __
# Endif
# Ifndef Module
# Define Module
# Endif
# Include <Linux/module. h>
# Include <Linux/kernel. h>
Module_author ("xiaosuo <xiaosuo@gmail.com> ");
Module_license ("GPL ");
Module_description ("this module is a example .");
Static int int_var = 0;
Static const char * str_var = "default ";
Static int int_array [6];
Module_parm (int_var, "I ");
Module_parm_desc (int_var, "a integer variable ");
Module_parm (str_var, "S ");
Module_parm_desc (str_var, "a string variable ");
Module_parm (int_array, "2-6i ");
Module_parm_desc (int_array, "a integer array ");
// The above part is not compiled in my system. Check the information and change it to the following syntax.
Module_param (int_var, Int, 0 );
Static int _ init hello_init (void)
{
Int I;
Printk (kern_alert "Hello, my lkm./N ");
Printk (kern_alert "int_var % d./N", int_var );
Printk (kern_alert "str_var % S./N", str_var );
For (I = 0; I <6; I ++ ){
Printk ("int_array [% d] = % d/N", I, int_array [I]);
}
Return 0;
}
Static void _ exit hello_exit (void)
{
Printk (kern_alert "bye, my lkm./N ");
}
Module_init (hello_init );
Module_exit (hello_exit );

References

The Linux kernel module programming guide

Linux Kernel Programming Guide (Third edition)

Linux Kernel analysis and programming

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.