About exporting symbols from an external module

Chetan Nanda chetannanda at gmail.com
Tue Jan 14 22:47:00 EST 2014


On Tue, Jan 14, 2014 at 6:38 PM, Le Tan <tamlokveer at gmail.com> wrote:

> Sorry, forgive me. I don't know how to reply the email like you.
> My linux kernel version is 3.11, and I do not touch the kvm makefile. Now
> let me show you in detail.
> First I put the files of my module in " /arch/x86/logger ", "logger" is
> the directory I create. The Makefile in " /arch/x86/kvm/" I think is the
> Makefile of kvm. It is like this:
>
> 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
>
> And the Makefile of my module in "/arch/x86/logger" is like this:
>
> 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
>
> So I compile my module first by running "make", then insmod it. I don't
> install it because I don't know if it is necessary. Then I go to the root
> of my linux code, and run a shell containing "make modules". Then it will
> show that :
>
> 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
> rmmod kvm_intel
> rmmod kvm
> cp
> /home/tanle/study/replay/linux-log/linux-3.11-replay/arch/x86/kvm/kvm.ko
> /lib/modules/3.11.0+/kernel/arch/x86/kvm/kvm.ko
> cp
> /home/tanle/study/replay/linux-log/linux-3.11-replay/arch/x86/kvm/kvm-intel.ko
> /lib/modules/3.11.0+/kernel/arch/x86/kvm/kvm-intel.ko
> modprobe kvm
> modprobe kvm_intel
>
> Notice that I add two sentences to the /arch/x86/kvm/x86.c:
>
> extern void print_record(char *format);           //This functino is
> defined in my module, this sentence is global
>
> print_record(NULL);                //Call this function in the
> vcpu_enter_guest() function
>
> So I don't know how to deal with this. I have poor knowledge about
> makefile and KBuild.
> Thanks for helping me again!
>
> How you are specifying kvm module to use symbol which is exported by some
other module?

After compiling your logger module, it must have generated a Module.symvers
file containing symbols exported by your module,
Please try with adding following in kvm module make file and compile again:

*KBUILD_EXTRA_SYMBOLS+= <Your logger module>/Module.symvers *


2014/1/14 Chetan Nanda <chetannanda at gmail.com>
>
>>
>>
>>
>> On Tue, Jan 14, 2014 at 12:38 PM, Le Tan <tamlokveer at gmail.com> wrote:
>>
>>> Thanks very much! I will try that later. What you mentioned is another
>>> amazing sight. But I am confused that why it can't work if I export a
>>> function from my module and call it in the kvm? Do I have to modify the
>>> makefile of kvm? How? I have referenced to the doc of KBuild. It said that :
>>>      Sometimes, an external module uses exported symbols from
>>>     another external module. kbuild needs to have full knowledge of
>>>     all symbols to avoid spliitting out warnings about undefined
>>>     symbols. Three solutions exist for this situation.
>>>
>>>     NOTE: The method with a top-level kbuild file is recommended
>>>     but may be impractical in certain situations.
>>>
>>>     Use a top-level kbuild file
>>>         If you have two modules, foo.ko and bar.ko, where
>>>         foo.ko needs symbols from bar.ko, you can use a
>>>         common top-level kbuild file so both modules are
>>>         compiled in the same build. Consider the following
>>>         directory layout:
>>>
>>>         ./foo/ <= contains foo.ko
>>>         ./bar/ <= contains bar.ko
>>>
>>>         The top-level kbuild file would then look like:
>>>
>>>         #./Kbuild (or ./Makefile):
>>>             obj-y := foo/ bar/
>>>
>>>         And executing
>>>
>>>             $ make -C $KDIR M=$PWD
>>>
>>>         will then do the expected and compile both modules with
>>>         full knowledge of symbols from either module.
>>>
>>>     Use an extra Module.symvers file
>>>         When an external module is built, a Module.symvers file
>>>         is generated containing all exported symbols which are
>>>         not defined in the kernel. To get access to symbols
>>>         from bar.ko, copy the Module.symvers file from the
>>>         compilation of bar.ko to the directory where foo.ko is
>>>         built. During the module build, kbuild will read the
>>>         Module.symvers file in the directory of the external
>>>         module, and when the build is finished, a new
>>>         Module.symvers file is created containing the sum of
>>>         all symbols defined and not part of the kernel.
>>>
>>>     Use "make" variable KBUILD_EXTRA_SYMBOLS
>>>         If it is impractical to copy Module.symvers from
>>>         another module, you can assign a space separated list
>>>         of files to KBUILD_EXTRA_SYMBOLS in your build file.
>>>         These files will be loaded by modpost during the
>>>         initialization of its symbol tables.
>>>
>>> But I have tried those methods. They don't work. Why?
>>> Thanks for your help very much!
>>>
>>
>> Please show your kvm module makefile,
>>
>>
>>>
>>>
>>
>>>
>>> 2014/1/14 Henrique Rodrigues <henriquesilvar at gmail.com>
>>>
>>>> Hi Le,
>>>>
>>>> You can do that by exporting a function pointer from the kvm code that
>>>> is only called if it is not null. Then, when you load your module, you set
>>>> that exported function pointer (I'm assuming that you want to call your
>>>> module's function from the kvm code... ). Here is a post on how to do that:
>>>>
>>>>
>>>> http://stackoverflow.com/questions/11463184/how-to-use-exported-symbols-in-the-linux-kernel
>>>>
>>>> http://stackoverflow.com/questions/1196944/can-i-replace-a-linux-kernel-function-with-a-module
>>>>
>>>> Best,
>>>> --
>>>> Henrique Rodrigues
>>>> http://www.dcc.ufmg.br/~hsr
>>>>
>>>>
>>>> On Mon, Jan 13, 2014 at 2:47 AM, Le Tan <tamlokveer at gmail.com> wrote:
>>>>
>>>>> Hello! I am writing a device driver module. I define some functions in
>>>>> the module, for example print_record(). I am doing something in the kvm, so
>>>>> I want to call print_record() in the file of kvm module, for example, I may
>>>>> call print_record() in file /arch/x86/kvm/x86.c to put something into my
>>>>> device driver module.
>>>>> Now comes the question.
>>>>> 1. Where should I put the codes of my device driver module? It's the
>>>>> first time I write the device driver.
>>>>> 2. After compiling my module, I encounter an error when I compile the
>>>>> kvm module.
>>>>>      ERROR: "print_record" [arch/x86/kvm/kvm.ko] undefined!
>>>>>     I use EXPORT_SYMBOL(print_record) in my module file. I use
>>>>> "extern" to declare print_record() and then call print_record()  in file
>>>>> x86.c.
>>>>>     To solve this problem, I have tried to copy the Module.symvers
>>>>> from my module folder to /arch/x86/kvm/. But it doesn't work. I have also
>>>>> tried to add *KBUILD_EXTRA_SYMBOLS *to the Makefile of kvm. It
>>>>> doesn't work either.
>>>>>     I cat /proc/kallsyms and find that the type of symbol
>>>>> "print_record" is "t" ( local text). What should I do? How to call
>>>>> functions defined in my own module from kvm? Maybe there is something wrong
>>>>> in Makefiles?
>>>>>
>>>>> Any suggestion is appreciated!
>>>>> Thanks!
>>>>>
>>>>> _______________________________________________
>>>>> Kernelnewbies mailing list
>>>>> Kernelnewbies at kernelnewbies.org
>>>>> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>>>>>
>>>>>
>>>>
>>>
>>> _______________________________________________
>>> Kernelnewbies mailing list
>>> Kernelnewbies at kernelnewbies.org
>>> http://lists.kernelnewbies.org/mailman/listinfo/kernelnewbies
>>>
>>>
>>
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.kernelnewbies.org/pipermail/kernelnewbies/attachments/20140115/f0755ed7/attachment-0001.html 


More information about the Kernelnewbies mailing list