Linux kernel module development

1.LINUX kernel module basis

1.1 What is a kernel module ?

  • The overall structure of the Linux kernel is very large, components it contains very much, how to use these components do ? Method 1: all the components are compiled into the kernel file, namely: zImage or bzImage, but this will cause a problem: take up memory too . Is there a mechanism to allow the kernel file itself does not contain a component, but when the components need to be used dynamically added to the kernel is running it?
  • Kernel module has the following characteristics:
    • 1) the module itself is not compiled into the kernel file (zImage or bzImage);
    • 2) according to the needs, during the operation of the kernel dynamically installed or uninstalled.

1.2 Installation and uninstallation

  • Installation insmod Example: insmod /home/dnw_usb.ko 
  • Unloading rmmod example: rmmod dnw_usb 
  • View lsmod example: lsmod   lsmod is listed as the name of all modules in memory exists, occupancy size, how many users are using other information.  

2. Kernel Module Design

2.1 Analysis of sample code

#include <linux/init.h>
#include <linux/module.h>


static int hello_init()
{
    printk(KERN_WARNING"Hello world!\n");
    return 0;	
}

static void hello_exit()
{
    printk(KERN_WARNING"hello exit!\n");	
}

module_init(hello_init);
module_exit(hello_exit);
  • 1. The contrast can be found in our application, this code is no main () function, we all know that main () is a function of the entrance, we do not need the module code entry function? Definitely want, the entry function of () module_init to indicate, when using insmod function to load a module, module_init () function specified will be invoked, that is hello_init () will be executed.
  • 2. At the same time when using rmmod to unload a module, the module_exit () macro function will get the specified call.
  • 3. The need to include header <linux / init.h> and <linux / module.h>
  • 4. Add a static before the function indicates that the function after the loss of global visibility, visible only within the scope of the function in the file is located, other scopes can not call this function
  • The print information is not used but printf printk, generally use information indicative KERN_WARING, without intermediate comma.

Write 2.2Makefile

obj-m := helloworld.o

KDIR := /home/linux/workdir/kernel/linux-mini2440

all:
    make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm
    
clean:
    rm -f *.o *.ko *.order *.symvers
  • obj-m represents the name of the production of documents
  • If you have multiple .c files you need to use the following wording:
    • obj-m := helloworld.o
    • helloworld-objs: = file1.o file2.o file3.o
  • Define a Makefile variable KDIR, save path development board to run the kernel code, here to write an individual basis;
  • Generating a target, make -C $ (KDIR) descend into the inside of the kernel code, M = $ {PWD} showed path module code, is the current path, and the command is expressed modules Make modules, indicating the last tool cross chain
  • Clear generated file

2.3 kernel module to run

  • When developing the plate using NFS file system, it can be directly generated helloworld.ko copy file to the file system, and execute insmod: some cases two prints a warning message, and then print out Hello world !.
  • Then execute rmmod, found an error, suggesting no **** catalog, because when unloading a module in lib / modules / kernel version and below the same directory, if no new: mkdir -p / lib / modules / $ (uname -r) and then uninstalled, you can see the print out hello exit !.

3. optional information kernel module

1. module Affirms

  • MODULE_LICENSE ( "compliance agreement") affirmed the module to comply with the license agreement, such as: "GPL", "GPL v2, etc.
  • MODULE_AUTHOR author ( "author") affirmed module
  • MODULE_DESCRIPTION ( "function module description") stated function module
  • MODULE_VERSION version ( "V1.0") affirmed module

2. The module parameters

  • In applications int main (int argc, char ** argv) argc represents the number of parameters of the command line parameters stored in argv entered.
  • 1) then the kernel module via the command line parameters it? Answer: Yes
  • 2) how the incoming parameters, save where the incoming?
    • By macro module_param specified variable holds the module parameters. Parameters passed to the module when the module is in the loading module for the parameter
    • module_param(name,type,perm)
      • name: name of the variable
      • type: variable type, bool: boolean int: Integer charp: string
      • perm is the access. S_IRUGO: read access S_IWUSR: write permission
#include <linux/init.h>
#include <linux/module.h>

int a = 3;
char *p;

static int hello_init()
{
    printk(KERN_WARNING"hello world!\n");
    printk("a = %d\n",a);	
	printk("p = %s\n", p);
    return 0;
}

static void hello_exit()
{
    printk(KERN_WARNING"hello exit!\n");        	
}

MODULE_LICENSE("GPL");

module_param(a, int, S_IRUGO | S_IWUSR);
module_param(p, charp, S_IRUGO | S_IWUSR);

module_init(hello_init);
module_exit(hello_exit);

3. Symbol Output

  • Function requires kernel module is achieved when a kernel module to call another, need to use the sign of the output module.
  • Macro kernel module using the output symbols:
    • EXPORT_SYMBOL (symbolic name)
    • EXPORT_SYMBOL_GPL (symbolic name), Description: where EXPORT_SYMBOL_GPL only be used for module contains GPL license.
#include <linux/init.h>
#include <linux/module.h>

extern add(int a, int b);

int a = 3;
char *p;

static int hello_init()
{
    printk(KERN_WARNING"hello world!\n");
    printk("a = %d\n",a);	
	printk("p = %s\n", p);
    return 0;
}

static void hello_exit()
{
	add(1, 3);
	printk(KERN_WARNING"hello exit!\n");        	
}

// 模块信息声明
MODULE_LICENSE("GPL");

// 模块参数声明
module_param(a, int, S_IRUGO | S_IWUSR);
module_param(p, charp, S_IRUGO | S_IWUSR);

// 模块函数声明
module_init(hello_init);
module_exit(hello_exit);
#include <linux/init.h>
#include <linux/module.h>

int add(int a, int b)
{
	return a + b;
}

static int add_init()
{
	return 0;
}

static void add_exit()
{
    
}

// 模块信息声明
MODULE_LICENSE("GPL");

// 模块符号输出
EXPORT_SYMBOL(add);

// 模块函数声明
module_init(add_init);
module_exit(add_exit);
obj-m := helloworld.o add.o

KDIR := /home/S4_a/part3/lesson3/lesson-2440/linux-mini2440

all:
	make -C $(KDIR) M=$(PWD) modules CROSS_COMPILE=arm-linux- ARCH=arm
	
clean:
	rm -f *.o *.ko *.order *.symvers *.mod.c
  • Define a Makefile variable KDIR, save path development board to run the kernel code, here to write based on individual circumstances.
  • Generating a target, make -C $ (KDIR) descend into the inside of the kernel code, M = $ {PWD} showed path module code, is the current path, and the command is expressed modules Make modules, indicating the last tool cross chain.
  • Clear some intermediate files.

Guess you like

Origin blog.csdn.net/qq_22847457/article/details/90752859
Recommended