• Linux 内核模块编程(一)


    实现一个模块的编译、加载、卸载;实现模块内两个文件的调用;实现两个模块间函数调用。

    编译部署spl
    
    cd /lcf/spl
    ./autogen.sh
    ./configure --enable-debug --disable-silent-rules
    make -j8
    make install

    一、模块的编译、加载、卸载

    1、#新建文件夹,mkdir filename

    #修改../module中Makefile.in,增加子目录subdir-m += spltest;


    2、在../module/spltest中用touch filename创建源文件(如helloworld.c)和Makefile.in,主要修改以下三个地方:

    src = @abs_top_srcdir@/module/spltest //模块目录名

    MODULE := spltest //模块名(生成.ko文件)

    $(MODULE)-objs += helloworld.o //源文件名

    Makefile.in

    # makefile.in for spltest kernel module
    
    src = @abs_top_srcdir@/module/spltest
    obj = @abs_builddir@
    
    MODULE := spltest
    EXTRA_CFLAGS = $(SPL_MODULE_CFLAGS) @KERNELCPPFLAGS@
    
    # Solaris Porting LAyer Tests
    obj-$(CONFIG_SPL) := $(MODULE).o
    
    $(MODULE)-objs += modA.o

    3、修改工程目录下configure.ac文件,AC_CONFIG_FILES中增加module/spltest/Makefile;


    4、重新编译部署spl,执行autogen.sh、configure、make操作。

          cd /lcf/spl
          ./autogen.sh

          ./configure --enable-debug --disable-silent-rules

          make -j8

          make install

    5、安装、卸载模块,打印信息

          insmod spltest.ko     //安装模块
          rmmod |grep spltest.ko      //卸载模块
          dmesg       //打印message

    二、实现模块内两个文件的调用。

     1、用上面一的方法新建模块splinner,在../module/splinner中用touch filename创建源文件hello.c和hello1.c,其中hello1.c调用hello.c中的函数。

    hello.c

    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/kernel.h>
    
    int func(void)
    {
    printk("this is a function in hello.c 
    ");
    return 0;
    }

    hello1.c

    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/kernel.h>
    
    extern int func(void);
    
    static int __init hello1_init(void)
    {
    printk("hello1 ,init 
    ");
    func();
    return 0;
    }
    
    static void __exit hello1_exit(void)
    {
    printk("hello1 ,exit 
    ");
    }
    
    module_init(hello1_init);
    module_exit(hello1_exit);

    2、加载模块,打印信息。

          insmod splinner.ko      //安装模块
          rmmod |grep splinner.ko      //卸载模块
          dmesg       //打印message

    三、实现两个模块间函数调用。

    1、用上面一的方法新建两个模块spltest和spltest2,两个模块中的文件分别为modA.c和modB.c,其中modB.c调用moA.c中的函数

    modA.c

    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/kernel.h>
    
    int func1(void)
    {
    printk("this is function1 
    ");
    return 0;
    }
    
    EXPORT_SYMBOL(func1);
    
    static int __init hello_init(void)
    {
    printk("Module A ,init 
    ");
    return 0;
    }
    
    static void __exit hello_exit(void)
    {
    printk("Module A ,exit 
    ");
    }
    
    module_init(hello_init);
    module_exit(hello_exit);

    modB.c

    #include <linux/init.h>
    #include <linux/module.h>
    #include <linux/kernel.h>
    
    int func2(void)
    {
    extern int func1(void);
    func1();
    return 0;
    }
    
    static int __init hello_init(void)
    {
    printk("module B ,init 
    ");
    func2();
    return 0;
    }
    
    static void __exit hello_exit(void)
    {
    printk("module B ,exit 
    ");
    }
    
    module_init(hello_init);
    module_exit(hello_exit);

    2、加载模块时遇到Unknown symbol in module:

         mesg | tail 查看未知模块;

         modinfo *.ko | grep depend 查找模块的依赖;

         modprobe xxx安装依赖的模块;

    3、加载模块,打印信息。

          insmod spltest2.ko      //安装模块
          rmmod |grep spltest2.ko      //卸载模块
          dmesg       //打印message

  • 相关阅读:
    读取XML示例:C#获取XML的数据
    GridView不換行
    List<T> 的条件筛选 where使用方法
    [HDU] 1016 Prime Ring Problem
    [HDU] 1072 Nightmare 和HDU1180有点类似
    [HDU] 1180 诡异的楼梯个人觉得比较有趣的广搜索
    [HDU] 1312Red and Black 用广搜求能探寻到的点的数目
    [HDU] 1026 Ignatius and the Princess I 简单建模后广搜索求最短路径生成树
    [HDU] 1010 Tempter of the Bone最基本的深搜
    [HDU] 1175 连连看 剪枝优化后的性能飙升
  • 原文地址:https://www.cnblogs.com/meiqin970126/p/9100044.html
Copyright © 2020-2023  润新知