0

I have developed 2 kernel drivers and I can build them using yocto as dynamic kernel modules without any probem but when I need to build them as static I had some issue related to dependency, because my driver1 is used by driver2.

Here is the issue:

| drivers/built-in.o: In function `init_module':
| mydriver2.c:(.init.text+0xd474): undefined reference to `__this_module'
| drivers/built-in.o: In function `mydriver_two_init':
| mydriver2.c:(.init.text+0xd53c): undefined reference to `my_driver_fn'
| /bsp/build/tmp/work-shared/bsp/kernel-source/Makefile:1003: recipe for target 'vmlinux' failed
| make[2]: *** [vmlinux] Error 1
| Makefile:152: recipe for target 'sub-make' failed
| make[1]: *** [sub-make] Error 2
| Makefile:24: recipe for target '__sub-make' failed
| make: *** [__sub-make] Error 2

In my driver1 I have developed a function that it is exported using EXPORT_SYMBOL(my_driver_fn); and this function is used in driver2.

I have tried to Kconfig file but error still exist : Kconfig file :

menu "personal Driver "
comment "Personal driver Config"

config DRIVER_ONE
        bool "driver 1"
        default y
        help
            driver 1

config DRIVER_TWO
        bool "driver 2"
        depends on  DRIVER_ONE
        default y
        help
            driver 2
endmenu

folder tree :

linux-sources
           \----->drivers (Makefile updated with obj-$(CONFIG_DRIVER_ONE) += driver_one/ and obj-$(CONFIG_DRIVER_TWO) += driver_two/)
                   |------------->personaldrivers
                             \--->Kconfig
                             \--->driver_one----contains---> mydriver1.c and Makefile (obj-$(CONFIG_DRIVER_ONE) = mydriver1.o)
                             \--->driver_two----contains---> mydriver2.c and Makefile(obj-$(CONFIG_DRIVER_TWO) = mydriver2.o)
developer
  • 4,744
  • 7
  • 40
  • 55
  • 1
    Is the `CONFIG_DRIVER_ONE=y` setting missing from your .config file for some reason? Does `my_driver_fn` have external linkage (not `static`)? – Ian Abbott Jun 21 '21 at 09:37
  • @lanAbbott I have already added them on .config file and it is not working, I think the problem is related to EXPORT_SYMBOL() function – developer Jun 21 '21 at 12:30
  • `EXPORT_SYMBOL()` is for exporting symbols to loadable modules. Built-in code uses C external linkage (`extern`) to link to other built-in code. – Ian Abbott Jun 21 '21 at 12:35
  • I have already in driver1 `EXPORT_SYMBOL(my_driver_fn);` and driver2 `extern int my_driver_fn(void);` before calling it later – developer Jun 21 '21 at 13:25
  • I have tried also without EXPORT_SYMBOL() only I have used extern and it fails also – developer Jun 21 '21 at 13:42
  • You can leave the `EXPORT_SYMBOL()` in there because it does no harm (and is required) when building driver_two as a module. Normally, you should declare `int my_driver_fn(void);` in a header file that is `#include`d by both driver_one and driver_two, and of course the function can not be defined `static` in driver_one because it is externally linked. – Ian Abbott Jun 21 '21 at 14:36
  • 1
    It's also weird that you are getting "undefined reference to \`__this_module'" because built-in driver modules should not be linking to `__this_module`. Driver code normally refers to it via the `THIS_MODULE` macro which expands to the address of `__this_module` when building as a module, but expands to a null pointer when building as a built-in. – Ian Abbott Jun 21 '21 at 15:10
  • And how can I fix this issue ? NOTE both of my 2 kernel drivers are configured in static build mode (builtin) – developer Jun 21 '21 at 16:51
  • I'm not sure what is wrong. Check the two `CONFIG_` options are *really* set to `=y` (not `=m`) in the .config file. Try `make clean`. – Ian Abbott Jun 21 '21 at 19:42

0 Answers0