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 \n");
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 \n");
func();
return 0;
}

static void __exit hello1_exit(void)
{
printk("hello1 ,exit \n");
}

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 \n");
return 0;
}

EXPORT_SYMBOL(func1);

static int __init hello_init(void)
{
printk("Module A ,init \n");
return 0;
}

static void __exit hello_exit(void)
{
printk("Module A ,exit \n");
}

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 \n");
func2();
return 0;
}

static void __exit hello_exit(void)
{
printk("module B ,exit \n");
}

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

posted @ 2018-05-28 14:33  hellomq  阅读(1721)  评论(0编辑  收藏  举报