• Linux Driver 入门


    Abstract

    1. Coding and compile a simple dynamic driver module - HelloWorld
    2. loading module and unloading module
    3. dmesg
    4. Kernel symbol table

    Create a Simple Dynamic Driver Module - HelloWorld

    hello.c

    #include <linux/init.h>
    #include <linux/module.h>
    
    MODULE_LICENSE("Dual BSD/GPL");
    static
    int hello_init(void) { printk(KERN_ALERT "TEST: hello world, this is hello world module "); return 0; } static void hello_exit(void) { printk(KERN_ALERT "TEST: Good bye, from hello world module "); } module_init(hello_init); module_exit(hello_exit);

    > #include <linux/init.h>

    This header contains the definition of the functions used in this module.

    > module_init() is a macro which defines the function to be called at module insertion time or at system boot time.

    > module_exit() is a macro which defines the function to be called at module removal time. This function is also called clean up function

    > Kernel modules must always contain these two functions: init_module and cleanup_module

    > #include <linux/module.h>

    This header is included to add support for Dynamic loading of the module into the Kernel.

    A special macro like MODULE_LICENSE is defined in this header.

    MODULE_LICENSE

    This macro is used to tell the kernel that this module bears a free license; without such a declaration, the kernel complains when the module is loaded.

    > printk

    int printk(const char *fmt, ...);
    

     

    printk(KERN_DEBUG "Debug message shown!
    ");

    Different Loglevels, along with their numerical values, are shown here:

    0 KERN_EMERG Emergency condition, system is probably dead
    1 KERN_ALERT Some problem has occurred, immediate attention is needed
    2 KERN_CRIT A critical condition
    3 KERN_ERR An error has occurred
    4 KERN_WARNING A warning
    5 KERN_NOTICE Normal message to take note of
    6 KERN_INFO Some information
    7 KERN_DEBUG Debug information related to the program

     

    MakeFile Version 1

    This can tell you which header file you need in Makefile:

    obj-m +=hello.o
    
    KDIR=/usr/src/linux-headers-$(shell uname -r)
     all: $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules clean: rm -rf *.o *.ko *.mod *.syvers *.order

     > "-C" option tells make command to switch to $(KDIR) which is kernel directory

    MakeFile Version 2

    obj-m :=hello.o
    
    KDIR := /lib/modules/$(shell uname -r)/build
    PWD := $(shell pwd)
    
    all:
        $(MAKE) -C $(KDIR) SUBDIRS=$(PWD) modules
    
    clean:
        rm -rf *.o *.ko *.mod *.syvers *.order

     

    yubao@yubao-ThinkPad-E560:~$ uname  -r
    4.13.0-36-generic

     

     Compiling the Module

    Make

    yubao@yubao-ThinkPad-E560:~/Documents/LinuxStudy$ make
    make -C /usr/src/linux-headers-4.13.0-36-generic SUBDIRS=/home/yubao/Documents/LinuxStudy modules
    make[1]: Entering directory '/usr/src/linux-headers-4.13.0-36-generic'
      CC [M]  /home/yubao/Documents/LinuxStudy/hello.o
      Building modules, stage 2.
      MODPOST 1 modules
      CC      /home/yubao/Documents/LinuxStudy/hello.mod.o
      LD [M]  /home/yubao/Documents/LinuxStudy/hello.ko
    make[1]: Leaving directory '/usr/src/linux-headers-4.13.0-36-generic'
    yubao@yubao-ThinkPad-E560:~/Documents/LinuxStudy$ ls
    hello.c  hello.ko  hello.mod.c  hello.mod.o  hello.o  Makefile  modules.order  Module.symvers

     

    Loading Kernel Modules

    Two Kernel Utilities to load the modules:

    insmod
    > modprobe

    insmod

    > Insmod is a kernel utility that installs loadable Kernal modules into the kernel.

    > It actually loads the module code and data into the Kernal land, links any unresolved symbols in the module to the symbol table of the Kernal.

    > Insmod accepts a number of command line options and it can assign a value to parameters in a module before linking it to the current kernel.

    > Note that if a module is correctly designed, it can be configured at load time by passing arguments to insmod.

    yubao@yubao-ThinkPad-E560:~/Documents/LinuxStudy$ sudo insmod hello.ko
    [sudo] password for yubao:

     modprobe

    > It's a Linux utility which offers more features than basic insmod

    > It has the ability to decide which modules to load /lib/modules/$(uname -r)

    > Its aware of module dependencies

    > It supports resolution of recursive module dependencies

    I encountered this error:

    yubao@yubao-ThinkPad-E560:/lib/modules/4.13.0-36-generic$ sudo modprobe  hello
    modprobe: FATAL: Module hello not found in directory /lib/modules/4.13.0-36-generic

    The reason is that modprobe looks into /lib/modules/$(uname -r) for the modules and therefore won't work with local file path. That's one of differences between modprobe and insmod.

    Therefore:

    $ dmesg -c

    yubao@yubao-ThinkPad-E560:~/MyProjects/Linux/driver/HelloWorld$ sudo cp hello.ko /lib/modules/4 .13.0-36-generic/extra/
    yubao@yubao-ThinkPad-E560:~/MyProjects/Linux/driver/HelloWorld$ sudo depmod
    yubao@yubao-ThinkPad-E560:~/MyProjects/Linux/driver/HelloWorld$ sudo modprobe hello
    yubao@yubao-ThinkPad-E560:~/MyProjects/Linux/driver/HelloWorld$ dmesg

    dmsg

    dmseg -c : clear history

    [ 6384.761442] TEST: hello world, this is hello world module

     

    Remove Module

    > rmmod

    yubao@yubao-ThinkPad-E560:~/Documents/LinuxStudy$ sudo rmmod hello.ko

     >Modprobe

    $modprobe -r module-name

    yubao@yubao-ThinkPad-E560:~/MyProjects/Linux/driver/HelloWorld$ sudo modprobe -r hello
    yubao@yubao-ThinkPad-E560:~/MyProjects/Linux/driver/HelloWorld$ dmesg
    [15909.539018] TEST: Good bye, from hello world module

     How to debug symbol error?

    Sample code with Symbol Undefine Error:

    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/kernel.h>
    
    //Just declared
    extern int g_value;
    
    static int hello_init(void)
    {
      printk(KERN_ALERT "TEST: hello world, this is hello world module
    ");
      printk("Hello world!!. Value of g_value is %d 
    ",g_value);
      return 0;
    }
    
    static void hello_exit(void)
    {
      printk(KERN_ALERT "TEST: Good bye, from hello world module
    ");
    }
    
    module_init(hello_init);
    module_exit(hello_exit);
    
    MODULE_LICENSE("GPL");
    MODULE_AUTHOR("yubao");
    MODULE_DESCRIPTION("Kernal Sybmol Table");

    Makefile

    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

    Error description:

    yubao@yubao-ThinkPad-E560:~/MyProjects/Linux/driver/SybolError$ sudo insmod hello.ko
    [sudo] password for yubao:
    insmod: ERROR: could not insert module hello.ko: Unknown symbol in module

     Use "nm" to debug

    yubao@yubao-ThinkPad-E560:~/MyProjects/Linux/driver/SybolError$ nm hello.ko
    0000000000000030 T cleanup_module
                     U __fentry__
                     U g_value
    0000000000000030 t hello_exit
    0000000000000000 t hello_init
    0000000000000000 T init_module
    0000000000000068 r __module_depends
                     U printk
    0000000000000000 D __this_module
    0000000000000020 r __UNIQUE_ID_author9
    0000000000000000 r __UNIQUE_ID_description10
    000000000000002d r __UNIQUE_ID_license8
    0000000000000071 r __UNIQUE_ID_name9
    0000000000000040 r __UNIQUE_ID_srcversion10
    000000000000007c r __UNIQUE_ID_vermagic8

     

     How to solve this problem?

    Replace "extern int g_value;" with "extern int g_value;". Then "make clean &make".

    Is it mandatory to export your module symbols?

    yes

    > "static" - visible only within their own source file

    > "external" - potentially visible to any other code built into the kernel itself

    >"exported" - visible and available to any loadable module

     

     

     

     

     

    新博客地址:www.ybliu.com
  • 相关阅读:
    1016: 写出来吧
    从硬件工程师转到纯软件开发,回顾那些岁月
    用大白话聊聊JavaSE -- 自定义注解入门
    数组中的一些常用方法总结
    js中的隐式转换
    开源OSS.Social微信项目进阶介绍
    .Net开源oss项目进度更新(含小程序接口)
    windows下部署免费ssl证书(letsencrypt)
    完成OSS.Http底层HttpClient重构封装 支持标准库
    谈javascript变量声明
  • 原文地址:https://www.cnblogs.com/yubao/p/8535626.html
Copyright © 2020-2023  润新知