我有两个内核可加载模块的设计,我正在用树构建。这些模块可以独立运行,也可以在两者都加载时一起工作(使用彼此的服务)。
所以我有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
答案 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。功能,
int register_module_notifier(struct notifier_block * nb);
int unregister_module_notifier(struct notifier_block * nb);
无论何时加载任何模块,都可用于通知。通知函数传递enum module_state
和指向模块结构的指针。您可以使用它来遍历导出的符号并修补模块中包含的函数指针。
对于有限数量的函数,第一个解决方案看起来最好,如果您预计最终可能会像这样添加许多函数,那么2 nd 似乎很好。 2 nd 解决方案支持模块删除,但您也可以使用register_funcA(NULL);
中的module_exit()
执行此操作。