编写将符号导出到kvm模块的设备驱动程序

时间:2014-01-13 12:55:30

标签: drivers linux-kernel kvm

我正在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()。然后我编译loggerinsmod

但是,在编译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

1 个答案:

答案 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文件,以便对这两个模块进行编译在同一版本中。 ....