Heng30的博客
搜索 分类 关于 订阅

Linux驱动相互调用

2025-02-23

应用层的程序一般都会依赖一些外部的库,驱动程序也不例外。驱动间也可以形成一个依赖链,将驱动的功能分割到不同的驱动。能减少驱动的复杂性和增加可维护性。

下面我就给大家带来一个例子,简单介绍下如何实现驱动相互调用。

调用者代码

// caller.c

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

extern void callee_print(void);

static int __init caller_init(void) {
    printk(KERN_INFO "caller init\n");
    callee_print();
    return 0;
}

static void __exit caller_exit(void) {
    printk(KERN_INFO "caller exit\n");
}

module_init(caller_init);
module_exit(caller_exit);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("heng30");
MODULE_DESCRIPTION("A simple caller kernel module");

被调用者代码

// callee.c

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

void callee_print(void);
void callee_print(void) {
    printk(KERN_INFO "hi from callee_print\n");
}

static int __init callee_init(void) {
    printk(KERN_INFO "callee init\n");
    return 0;
}

static void __exit callee_exit(void) {
    printk(KERN_INFO "callee exit\n");
}

module_init(callee_init);
module_exit(callee_exit);

EXPORT_SYMBOL(callee_print);

MODULE_LICENSE("GPL");
MODULE_AUTHOR("heng30");
MODULE_DESCRIPTION("A simple callee kernel module");

Makefile构建脚本

#!/bin/sh

arch = x86
top-dir = $(shell pwd)
kernel-version = $(shell uname -r)
kernel-dir ?= /lib/modules/$(kernel-version)/build

obj-m = callee.o caller.o

all:
        make -C $(kernel-dir) modules M=$(top-dir)

install:
        insmod callee.ko
        insmod caller.ko

uninstall:
        rmmod caller.ko
        rmmod callee.ko

clean:
        rm -f *.o *.ko *.mod *.mod.c *.order *.symvers
        make -C $(kernel-dir) clean m=$(top-dir)

运行make进行编译,make install进行安装驱动。

如果你的被调用者驱动在别的目录,需要使用KBUILD_EXTRA_SYMBOLS指明链接符号。

callee-symbols = $(path-to-callee)/Module.symvers
make -C $(kernel-dir) KBUILD_EXTRA_SYMBOLS=$(callee-symbols) modules M=$(top-dir)