1

I tried to redo the code of the kernel module found in this topic How can I obtain battery level inside a Linux kernel module?. But when I try to use the functions contained in the power_supply.h header file, the loading of the module fails because it does not recognize the power_supply_get_by_name function.

Here is the code that I am using on Ubuntu 18.04 with kernel version 4.15.0-101-generic:

#include <linux/module.h>
#include <linux/power_supply.h>

static int __init test_init (void)
{
        struct power_supply *psy;
        char name[] = "BAT1";

        psy = power_supply_get_by_name(name);

        printk(KERN_DEBUG "Test module inserted");

        return 0;
}

static void __exit test_exit (void)
{
        printk(KERN_DEBUG "Test module removed");
}

module_init (test_init);
module_exit (test_exit);

I get no error at compiling except a warning concerning the module license which is I think not related to my problem but I get the following errors:

  1. when running insmod in the terminal: "insmod: ERROR: could not insert module test.ko: Unknown symbol in module"
  2. in the /var/log/kern.log file: "test: Unknown symbol power_supply_get_by_name (err 0)"

I checked the kallsyms proc file and the function is indicated as usable in other kernel modules if I understood well this topic What is the difference between T and t in /proc/kallsyms. Here is the output from reading the kallsyms file:

ffffffff8e9bd270 T power_supply_get_by_name

Does anyone knows why this is not working while I can use other linux headers functions without any problem and, if so, how I can fix my problem?

Thanks in advance

bla1r0
  • 25
  • 5

1 Answers1

1

This may actually be related to the module license! If you look at the kernel source code, the function power_supply_get_by_name is exported here. You can see it's using EXPORT_SYMBOL_GPL. As this answer explains:

EXPORT_SYMBOL_GPL will show the symbol only in GPL-licensed modules

The use of this macro is controversial, but that's the way the project operates... To gain access to the symbols you need, you'll need to license your module as GPL:

MODULE_LICENSE("GPL");
John Moon
  • 924
  • 6
  • 10
  • I tried your solution this morning and it works perfectly! I would never have thought about that... Thank you for your fast and precise answer! – bla1r0 Jun 11 '20 at 05:24