我正在kvm
做一些事情。我编写了一个名为logger
的设备驱动程序模块,其中定义了一个名为print_record()
的函数。我修改了kvm
中的一些代码,并希望调用print_record()
将一些信息放入logger
。然后,用户空间应用程序可以阅读logger
以获取有关kvm
的状态的信息。
这就是我想要做的事情:
例如,我在文件print_record()
中定义logger_main.c
并在EXPORT_SYMBOL(print_record)
中编写logger_main.c
。在/arch/x86/kvm/x86.c
中,我在开头写extern print_record(char *)
并在同一文件中的某个地方调用print_record()
。然后我编译logger
和insmod
。
但是,在编译kvm.ko
时遇到错误:
make -j 16 modules
make[1]: Nothing to be done for `all'.
CHK include/generated/uapi/linux/version.h
make[1]: Nothing to be done for `relocs'.
CHK include/generated/utsrelease.h
CALL scripts/checksyscalls.sh
CC [M] arch/x86/kvm/x86.o
LD [M] arch/x86/kvm/kvm.o
LD [M] arch/x86/kvm/kvm-intel.o
LD [M] arch/x86/kvm/kvm-amd.o
Building modules, stage 2.
MODPOST 2832 modules
ERROR: "print_record" [arch/x86/kvm/kvm.ko] undefined!
make[1]: *** [__modpost] Error 1
make: *** [modules] Error 2
我运行cat /proc/kallsyms
并看到符号print_record
位于't'旁边,这意味着'本地文字'。
我坚持了一天!我尝试了几种方法,就像其他人在互联网上做的那样,但却失败了。
问题:
我该怎么办?
Makefile可能有问题吗?
任何人都可以举一个简单但完整的例子来演示如何调用kvm
中外部模块中定义的函数,包括Makefile吗?
/ arch / x86 / kvm / Makefile的内容是这样的:
ccflags-y += -Ivirt/kvm -Iarch/x86/kvm
CFLAGS_x86.o := -I.
CFLAGS_svm.o := -I.
CFLAGS_vmx.o := -I.
KVM := ../../../virt/kvm
kvm-y += $(KVM)/kvm_main.o $(KVM)/ioapic.o \
$(KVM)/coalesced_mmio.o $(KVM)/irq_comm.o \
$(KVM)/eventfd.o $(KVM)/irqchip.o
kvm-$(CONFIG_KVM_DEVICE_ASSIGNMENT) += $(KVM)/assigned-dev.o $(KVM)/iommu.o
kvm-$(CONFIG_KVM_ASYNC_PF) += $(KVM)/async_pf.o
kvm-y += x86.o mmu.o emulate.o i8259.o irq.o lapic.o \
i8254.o cpuid.o pmu.o
kvm-intel-y += vmx.o
kvm-amd-y += svm.o
obj-$(CONFIG_KVM) += kvm.o
obj-$(CONFIG_KVM_INTEL) += kvm-intel.o
obj-$(CONFIG_KVM_AMD) += kvm-amd.o
我的Makefile的内容是这样的(我把我的代码放在/arch/x86/logger/
下)
ifneq ($(KERNELRELEASE),)
obj-m := logger.o
logger-objs := logger_main.o
else
KERNELDIR ?= /lib/modules/$(shell uname -r)/build
PWD := $(shell pwd)
modules:
$(MAKE) -C $(KERNELDIR) M=$(PWD) modules
endif
clean:
rm -rf *.o *.ko *.mod.c
答案 0 :(得分:0)
请参考以下答案: Warning building a kernel module that uses exported symbols
它在http://www.kernel.org/doc/Documentation/kbuild/modules.txt
中有解释有时,一个外部模块使用从另一个外部模块导出的符号。 kbuild需要全面了解所有符号,以避免吐出有关未定义符号的警告。针对这种情况存在三种解决方案。
注意:建议使用带有顶级kbuild文件的方法,但在某些情况下可能不切实际。
使用顶级kbuild文件如果您有两个模块foo.ko和bar.ko,其中foo.ko需要来自bar.ko的符号,则可以使用通用的顶级kbuild文件,以便对这两个模块进行编译在同一版本中。 ....