Write a simple Linux2.6 kernel module (1)

Source: Internet
Author: User
Tags dmesg

Your kernel must have these options enabled for compilation:

Loadable module support  --->  [*] Enable loadable module support  [*]   Module unloading  [ ]   Module versioning support (EXPERIMENTAL)  [*]   Automatic kernel module loading

If you follow the instructions in the first tutorial to compile the kernel, you have correctly set these options. Otherwise, modify these options, re-compile the kernel, and boot to the new kernel.

A simple module skeleton

First, find the source code for compiling the current Linux kernel. Switch the directory to the Linux source code directorydrivers/misc/. Now, copy the following code and paste it tomymodule.cFile:

#include 
      
       #include 
       
        #include 
        
         static int __init mymodule_init(void){    printk ("My module worked!\n");    return 0;}static void __exit mymodule_exit(void){    printk ("Unloading my module.\n");    return;}module_init(mymodule_init);module_exit(mymodule_exit);MODULE_LICENSE("GPL");
        
       
      
Save the file and edit it in the same directory. MakefileFile. Add this line:

obj-m += mymodule.o
Compilation module:

# make -C 
      
        SUBDIRS=$PWD modules
      
Use insmod ./mymodule.koLoad this module and check whether your message is printed: dmesg | tail. It should be seen at the end of the output:

My module worked!
Delete the kernel module now: rmmod mymodule. View dmesg again; you will see:

Unloading my module.
In this way, you have compiled and run a new kernel module! Congratulations!

Module/kernel interface

Now let's do something more interesting about your module. One key thing to understand is that the module can only "see" The functions and variables that the kernel intentionally allows it to access. First, we try it in the wrong way.

Edit Filekernel/printk.cAdd the following line after all the contained files and other global variable declarations are near but outside of all functions:

int my_variable = 0;
Now recompile the kernel and boot it to the new kernel. Then, add the following content to the module's mymodule_initThe start of the function, before other code.

extern int my_variable;printk ("my_variable is %d\n", my_variable);my_variable++;
Save the changes and re-compile the module:

# make -C 
      
        SUBDIRS=$PWD modules
      
Failed to load the module ): insmod ./mymodule.ko. The module fails to be loaded and a message is displayed:

insmod: error inserting './mymodule.ko': -1 Unknown symbol in module
This indicates that the kernel does not allow the module to access that variable. When a module is loaded, it must parse all external references, such as the function name or variable name. If it cannot find all unresolved names in the list of symbols exported by the kernel, the module cannot write the variable or call the function. There is a variable somewhere in the kernel my_variableThe allocated space, but the module does not know where it is.

To solve this problem, we willmy_variableAdd to the list of symbols exported by the kernel. In many kernel directories, a specific file is used to export the symbols defined in that directory. Open againkernel/printk.cFile, add the following line after the variable declaration:

EXPORT_SYMBOL(my_variable);
Recompile and reboot to the new kernel. Now try again to load the module: insmod ./mymodule.ko. This time, when you view dmesg, you should see:

my_variable is 0My module worked!
Reload the module:

# rmmod mymodule && insmod ./mymodule.ko
Now we can see:

Unloading my module.my_variable is 1My module worked!
Each time you reload that module, my_variableWill increase by 1. You are reading and writing a variable defined in the main kernel. As long EXPORT_SYMBOL()Explicitly declare that the module can access any variable in the main kernel. For example, Function printk()Is defined in the kernel and in the file kernel/printk.c.

A simple bootable kernel module is an interesting way to study the kernel. For example, you can use a module to enable or disableprintkTo define a variable in the kerneldo_printIt is initialized to 0 ). Then, let allprintkAll rely on"do_print":

if (do_print) {    printk ("Big long obnoxious message\n");}
Then, open the module only when it is loaded.

Module Parameters

When guiding a module, you can pass parameters to it. To use the module parameters to load the module, write as follows:

insmod module.ko [param1=value param2=value ...]
To use the values of these parameters, declare variables in the module to save them and use macros somewhere outside all functions. MODULE_PARM(variable, type)And MODULE_PARM_DESC(variable, description)To receive them. typeThe parameter format is [min[-max]]{b,h,i,l,s}String, where min and max are the length limits of the array. If both are ignored, the default value is 1. The last character is a type specifier:

b       byteh       shorti       intl       longs       string

You canMODULE_PARM_DESCOfdescriptionAdd any required specifiers to the domain.


Related Article

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.