2

ツリーから構築している 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

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

このオーバーヘッドは非常に小さいため、モジュールにする必要はありません。

もう 1 つのメカニズムは、module.hを調べることです。関数、

  1. int register_module_notifier(struct notifier_block * nb);
  2. int unregister_module_notifier(struct notifier_block * nb);

モジュールがロードされるたびに通知を受け取るために使用できます。通知関数が渡さenum module_stateれ、モジュール構造へのポインターが渡されます。これを使用して、エクスポートされたシンボルをウォークスルーし、モジュール内に含まれる関数ポインターにパッチを適用できます。

最初の解決策は限られた数の機能に最適であり、多くの機能が最終的にこのように追加されることが予想される場合は 2番目の解決策が適していると思われます。2番目のソリューションはモジュールの削除をサポートしていますが、.in を使用register_funcA(NULL);して最初のソリューションでもこれを実行できますmodule_exit()

于 2013-08-09T19:10:09.057 に答える