5

Why this kernel module doesn't do anything when i load it?

#include <linux/init.h>
#include <linux/module.h>
#include <linux/platform_device.h>

#define DEVICE_NAME "hello-1.00.a"
#define DRIVER_NAME "hello"
MODULE_LICENSE("Dual BSD/GPL");

static int hello_init(struct platform_device *pdev){
    printk(KERN_ALERT "Hello, world\n");
    return 0;
}
static int hello_exit(struct platform_device *pdev){
    printk(KERN_ALERT "Goodbye, cruel world\n");
    return 0;
}

static const struct of_device_id myled_of_match[] =
{
    {.compatible = DEVICE_NAME},
    {},
};

MODULE_DEVICE_TABLE(of, myled_of_match);

static struct platform_driver hello_driver =
    {
        .driver = {
        .name = DRIVER_NAME,
        .owner = THIS_MODULE,
        .of_match_table = myled_of_match
    },
    .probe = hello_init,
    .remove = hello_exit
};

module_platform_driver(hello_driver);

It musts print Hello, world\n, if i do lsmod the module appear to be loaded:

lsmod
hello_world 1538 0 - Live 0xbf000000 (O)

but nothing is printed neither in the console nor in dmesg.

If i use module_init and module_exit all works, but i need the pointer platform_device *pdev to the device, what can i do?

EDIT:

the original module looks like this:

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

static int hello_init(void){
    printk(KERN_ALERT "Hello, world\n");
    return 0;
}

static void hello_exit(void){
    printk(KERN_ALERT "Goodbye, cruel world\n");
}


module_init(hello_init);
module_exit(hello_exit);

In my device tree blob is present this entry:

hello {
    compatible = "dglnt,hello-1.00.a";
    reg = <0x41220000 0x10000>;
};
sawdust
  • 16,103
  • 3
  • 40
  • 50
Luca
  • 1,270
  • 1
  • 18
  • 34
  • *"If i use module_init and module_exit all works"* -- What does that code look like? Does this kernel use a Device Tree blob? – sawdust Nov 10 '14 at 10:33
  • yes, it used a dtb, my problem is that nothing is printed when i do insmod – Luca Nov 10 '14 at 10:34
  • i have added the original source code – Luca Nov 10 '14 at 10:38
  • The lines module_init and module_exit basically inform the kernel on what method to execute on inserting and removing the module. This is why there is nothing printed in dmesg. Try keeping the entire code same and simply inserting module_init and module_exit at the end of your code. – Obscure Geek Nov 10 '14 at 10:46
  • you can't use module_platform_driver and module_init/exit in the same module, they are mutually exclusive. – Luca Nov 10 '14 at 10:47
  • The "original" code only invokes module loading; **it is not a driver**. The longer kernel module is getting loaded, but since it has the default init and exit code that does nothing, there are no messages. The probe code of the driver (which would output messages) simply is not getting called probably because there is nothing in your Device Tree that indicates that this device driver is needed. – sawdust Nov 10 '14 at 10:48
  • what do you mean by "is needed" and how do I indicate that is needed? – Luca Nov 10 '14 at 10:50
  • You need a **device node** in the Device Tree to specify this driver by using a `compatible = "myled_of_match,hello-1.00.a";` line – sawdust Nov 10 '14 at 10:54
  • i have already add the entry in the dtb, in the question i've added the code – Luca Nov 10 '14 at 10:57
  • Is there a `status = "okay";` for that node? – sawdust Nov 10 '14 at 10:59
  • where do i have to look for it? – Luca Nov 10 '14 at 11:00
  • Anywhere you have "Hello" declared in the DT. Where did the "dglnt" come from in `compatible = "dglnt,hello-1.00.a";`? Try a simple `compatible = "hello-1.00.a";` since that is the verbatim string in your driver. – sawdust Nov 10 '14 at 11:16
  • Oh My God that was the problem! you are my saviour! If you write down the answer i will mark it as the correct – Luca Nov 10 '14 at 12:08

1 Answers1

6

If i use module_init and module_exit all works

That short "original" code only consists of the module framework. The init routine is guaranteed to be called when the module is loaded, and the exit routine is called prior to unloading. That "original" code is not a driver.

The longer kernel module is a driver and getting loaded, but since it has the default init and exit code that does nothing (as generated by the expansion of the module_platform_driver() macro), there are no messages. The driver code in the loadable module is not guaranteed to be called when the kernel uses a Device Tree.

Why this kernel module doesn't do anything when i load it?

The probe function of the driver (which would output messages) is probably not getting called because there is nothing in your Device Tree that indicates that this device driver is needed.

The snippet of the board's Device Tree has

    compatible = "dglnt,hello-1.00.a";

but the driver declares that it should specified as

#define DEVICE_NAME "hello-1.00.a"
...   
    {.compatible = DEVICE_NAME},

These strings should match so that the driver can bind with this referenced device in the Device Tree node.

Also the device node should be declared as

    status = "okay";

to override any default status that could disable the device.

A properly configured node in the Device Tree should get the driver's probe function to be executed as expected.

sawdust
  • 16,103
  • 3
  • 40
  • 50