0

KO之间互相调用 - zhengcixi

 11 months ago
source link: https://www.cnblogs.com/mrlayfolk/p/17419124.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

假设有两个KO,命名为moduleA.KO,moduleB.KO,现在要实现在moduleB.KO中调用moduleA.KO中的函数。

ModuleA实现

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

void moduleA_func(void)
{
    printk("moduleA function\r\n");
}

static int __init moduleA_init(void)
{
    printk("moduleA init!\r\n");

    return 0;
}

static void __exit moduleA_exit(void)
{
    printk("moduleA exit!\r\n");
}

EXPORT_SYMBOL_GPL(moduleA_func);

MODULE_AUTHOR("moduleA");
MODULE_DESCRIPTION("moduleA functions");
MODULE_LICENSE("GPL v2");

module_init(moduleA_init);
module_exit(moduleA_exit);

moduleA导出符号moduleA_func。

编译Makefile实现:

# Kernel modules
obj-m += moduleA.o

KVERS = $(shell uname -r)

# Specify flags for the module compilation.
#EXTRA_CFLAGS=-g -O0

OUTPUT_DIR := $(shell pwd)

build: kernel_modules

kernel_modules:
	make -C /lib/modules/$(KVERS)/build M=$(OUTPUT_DIR) modules

clean:
	make -C /lib/modules/$(KVERS)/build M=$(OUTPUT_DIR) clean
$ make
$ more Module.symvers
0xcaecb33a      moduleA_func    /home/grace/ko_test/moduleA/moduleA     EXPORT_SYMBOL_GPL

可以看出,moduleA_func已经在导出的符号表中了。

ModuleB实现

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

extern void moduleA_func(void);

static int __init moduleB_init(void)
{
    printk("moduleB init!\r\n");

    moduleA_func();

    return 0;
}

static void __exit moduleB_exit(void)
{
    printk("moduleB exit!\r\n");
}

MODULE_AUTHOR("moduleB");
MODULE_DESCRIPTION("moduleB functions");
MODULE_LICENSE("GPL v2");

module_init(moduleB_init);
module_exit(moduleB_exit);

编译Makefile:

# Kernel modules
obj-m += moduleB.o

KVERS = $(shell uname -r)

# Specify flags for the module compilation.
#EXTRA_CFLAGS=-g -O0

# 引用moduleA.ko的符号表, 需要先编译SDK才能得到, 路径为绝对路径
KBUILD_EXTRA_SYMBOLS += /home/grace/ko_test/moduleA/Module.symvers

OUTPUT_DIR := $(shell pwd)

build: kernel_modules

kernel_modules:
	make -C /lib/modules/$(KVERS)/build M=$(OUTPUT_DIR) modules

clean:
	make -C /lib/modules/$(KVERS)/build M=$(OUTPUT_DIR) clean

1、插入moduleA.ko

$ sudo insmod moduleA.ko
$ sudo dmesg -c
[ 1567.642413] moduleA: loading out-of-tree module taints kernel.
[ 1567.642507] moduleA: module verification failed: signature and/or required key missing - tainting kernel
[ 1567.642823] moduleA init!
$ cat /proc/kallsyms | grep moduleA_func
ffffffffc071b030 r __ksymtab_moduleA_func       [moduleA]
ffffffffc071b07b r __kstrtab_moduleA_func       [moduleA]
ffffffffc071b040 r __kcrctab_moduleA_func       [moduleA]
ffffffffc071a000 t moduleA_func [moduleA]

2、插入moduleB.ko

$ sudo dmesg -c
[ 1900.514577] moduleB init!
[ 1900.514580] moduleA function

可以看出,moduleB成功调用到了moduleA的moduleA_func函数。

1、moduleA没有编译就编译了ModuleB

这时候会提示:WARNING: "moduleA_func" [/home/grace/ko_test/moduleB/moduleB.ko] undefined!

2、没有在ModuleB的Makefile中添加KBUILD_EXTRA_SYMBOLS

这时候会提示:WARNING: "moduleA_func" [/home/grace/ko_test/moduleB/moduleB.ko] undefined!

3、注意:KBUILD_EXTRA_SYMBOLS后面跟的是绝对路径

ModuleB.ko调用ModuleA.ko的使用步骤:

  1. 先编译ModuleA.ko, 得到KO的符号表, 也就是Module.symvers文件
  2. 再编译ModuleB.ko, 需要在Makefile中指定ModuleA.ko的符号表位置KBUILD_EXTRA_SYMBOLS+="符号表位置",并且使用绝对路径方式。
  3. 插入时,需要先插入ModuleA.ko,再插入ModuleB.ko
  4. 卸载时,需要先卸载ModuleB.ko,再卸载ModuleA.ko,否则会提示:rmmod: ERROR: Module moduleA is in use by: moduleB

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK