2

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

所以我有带有 funcA 和 funcB 的 module1.ko。我也有带有 funcC 和 funcD 的 module2.ko。当 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
4

2 回答 2

2

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

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

于 2013-08-09T17:38:43.597 回答
2

根据ugoren 的回答,您可以将一些钩子添加到机器文件中。

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);

可用于在加载任何模块时获得通知。通知器函数enum module_state和一个指向模块结构的指针被传递。您可以使用它来遍历导出的符号并修补模块中包含的函数指针。

第一个解决方案似乎最适合有限数量的功能,如果您预计最终可能会像这样添加许多功能,那么第二个似乎很好。第二个解决方案支持模块删除,但您也可以通过在第一个解决方案register_funcA(NULL);中使用module_exit().

于 2013-08-09T19:10:09.057 回答