Linux中相互依赖的树外可加载模块

时间:2013-08-09 17:33:41

标签: c module linux-kernel linux-device-driver

我有两个内核可加载模块的设计,我正在用树构建。这些模块可以独立运行,也可以在两者都加载时一起工作(使用彼此的服务)。

所以我有funcA和funcB的module1.ko。我也有module2.ko与funcC和funcD。当module1.ko自己加载时,它只使用funcA和funcB。但是如果还加载了module2.ko,我想让它成为module1.ko可以使用funcC。

module1.ko如何检测module2.ko是否已加载,以便知道funcC是否可供其使用?

此外,由于我正在Linux内核之外构建这两个模块,如何在构建时更新我的​​Makefile以添加此条件依赖项?

我的Makefile目前看起来像是这样的:

MODULE_NAME=module1
SOURCE_FILES=module1_driver.c
CROSS_COMPILER=powerpc-timesys-linux-gnu-
ARCH=powerpc

ifneq ($(KERNELRELEASE),)

    obj-m := $(MODULE_NAME).o
    $(MODULE_NAME)-objs := $(SOURCE_FILES:.c=.o)
    ccflags-y := -I$(src)/../common
    sinclude $(TOPDIR)/Rules.make

else

    KERNELDIR ?= ../../linux/2.6-xlnx-rt
    PWD := $(shell pwd)

default:
    $(MAKE) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILER) -C $(KERNELDIR) M=$(PWD) modules

clean:
    $(MAKE) ARCH=$(ARCH) CROSS_COMPILE=$(CROSS_COMPILER) -C $(KERNELDIR) M=$(PWD) clean
    rm -rf ../common/*.o module1_test

endif

2 个答案:

答案 0 :(得分:2)

一个简单的解决方案是使用第三个模块。

第三个woulf总是被加载,并且将包含一个导出的函数指针 module2将设置指针,如果已设置,module1将使用它。

答案 1 :(得分:2)

根据ugoren's回答,您只需将一些挂钩添加到计算机文件中即可。

static void (*funcA_ptr)();
void register_funcA(void(*)() fnc)
{
  funcA_ptr = fnc;
}
EXPORT_SYMBOL(register_funcA);
void funcA_proxy()
{
  if(funcA_ptr)
       funcA_ptr();
}
EXPORT_SYMBOL(funcA_proxy);

这个开销很小,没有必要把它变成一个模块。

另一种机制是浏览module.h。功能,

  1. int register_module_notifier(struct notifier_block * nb);
  2. int unregister_module_notifier(struct notifier_block * nb);
  3. 无论何时加载任何模块,都可用于通知。通知函数传递enum module_state和指向模块结构的指针。您可以使用它来遍历导出的符号并修补模块中包含的函数指针。

    对于有限数量的函数,第一个解决方案看起来最好,如果您预计最终可能会像这样添加许多函数,那么2 nd 似乎很好。 2 nd 解决方案支持模块删除,但您也可以使用register_funcA(NULL);中的module_exit()执行此操作。