Код драйвера в модуле ядра не выполняется?

Почему этот модуль ядра ничего не делает, когда я его загружаю?

#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);

Он должен напечатать Hello, world\n, если я сделаю lsmod, модуль будет загружен:

lsmod
hello_world 1538 0 - Live 0xbf000000 (O)

но ничего не печатается ни в консоли, ни в dmesg.

Если я использую module_init и module_exit, все работает, но мне нужен указатель platform_device *pdev на устройство, что я могу сделать?

РЕДАКТИРОВАТЬ:

исходный модуль выглядит так:

#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);

В моем дереве устройств blob присутствует эта запись:

hello {
    compatible = "dglnt,hello-1.00.a";
    reg = <0x41220000 0x10000>;
};

person Luca    schedule 10.11.2014    source источник
comment
Если я использую module_init и module_exit, все работает - Как выглядит этот код? Использует ли это ядро ​​BLOB-объект дерева устройств?   -  person sawdust    schedule 10.11.2014
comment
да, он использовал dtb, моя проблема в том, что ничего не печатается, когда я делаю insmod   -  person Luca    schedule 10.11.2014
comment
я добавил оригинальный исходный код   -  person Luca    schedule 10.11.2014
comment
Строки module_init и module_exit в основном информируют ядро ​​о том, какой метод выполнить при вставке и удалении модуля. Вот почему в dmesg ничего не печатается. Попробуйте сохранить весь код таким же и просто вставьте module_init и module_exit в конец вашего кода.   -  person Obscure Geek    schedule 10.11.2014
comment
вы не можете использовать module_platform_driver и module_init / exit в одном модуле, они исключают друг друга.   -  person Luca    schedule 10.11.2014
comment
Исходный код вызывает только загрузку модуля; это не драйвер. Загружается более длинный модуль ядра, но поскольку он имеет код инициализации и выхода по умолчанию, который ничего не делает, сообщений нет. Пробный код драйвера (который будет выводить сообщения) просто не вызывается, вероятно, потому что в вашем дереве устройств нет ничего, что указывало бы на то, что этот драйвер устройства необходим.   -  person sawdust    schedule 10.11.2014
comment
что вы имеете в виду под словом "необходимо" и как указать, что это необходимо?   -  person Luca    schedule 10.11.2014
comment
Вам понадобится узел устройства в дереве устройств, чтобы указать этот драйвер с помощью строки compatible = "myled_of_match,hello-1.00.a";   -  person sawdust    schedule 10.11.2014
comment
я уже добавил запись в dtb, в вопросе я добавил код   -  person Luca    schedule 10.11.2014
comment
Есть ли status = "okay"; для этого узла?   -  person sawdust    schedule 10.11.2014
comment
где мне его искать?   -  person Luca    schedule 10.11.2014
comment
Везде, где в DT у вас есть объявление Hello. Откуда взялся dglnt в compatible = "dglnt,hello-1.00.a";? Попробуйте использовать простой compatible = "hello-1.00.a";, поскольку это дословная строка в вашем драйвере.   -  person sawdust    schedule 10.11.2014
comment
Боже мой, это была проблема! ты мой спаситель! Если вы запишете ответ, я отмечу его как правильный   -  person Luca    schedule 10.11.2014


Ответы (1)


Если я использую module_init и module_exit, все работает

Этот короткий «исходный» код состоит только из структуры модуля. Процедура инициализации гарантированно вызывается при загрузке модуля, а процедура выхода вызывается перед выгрузкой. Этот «оригинальный» код не является драйвером.

Более длинный модуль ядра является драйвером и загружается, но поскольку он имеет код инициализации и выхода по умолчанию, который ничего не делает (как генерируется раскрытием макроса module_platform_driver ()), сообщений нет. Вызов кода драйвера в загружаемом модуле не гарантируется, если ядро ​​использует дерево устройств.

Почему этот модуль ядра ничего не делает, когда я его загружаю?

Функция проверки драйвера (которая будет выводить сообщения), вероятно, не вызывается, потому что в вашем дереве устройств нет ничего, что указывало бы на то, что этот драйвер устройства необходим.

Фрагмент дерева устройств платы имеет

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

но драйвер заявляет, что он должен быть указан как

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

Эти строки должны совпадать, чтобы драйвер мог связываться с указанным устройством в узле дерева устройств.

Также узел устройства должен быть объявлен как

    status = "okay";

для отмены любого состояния по умолчанию, которое могло бы отключить устройство.

Правильно настроенный узел в дереве устройств должен заставить функцию проверки драйвера выполняться должным образом.

person sawdust    schedule 10.11.2014