【问题标题】:Driver code in kernel module doesn't execute?内核模块中的驱动程序代码不执行?
【发布时间】:2023-03-24 20:51:01
【问题描述】:

为什么这个内核模块在我加载它时什么都不做?

#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_initmodule_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>;
};

【问题讨论】:

  • "如果我使用 module_init 和 module_exit 一切正常" -- 这段代码是什么样的?此内核是否使用设备树 blob?
  • 是的,它使用了 dtb,我的问题是当我执行 insmod 时没有打印任何内容
  • 我已经添加了原始源代码
  • module_init 和module_exit 行基本上告诉内核在插入和删除模块时要执行什么方法。这就是为什么 dmesg 中没有打印任何内容的原因。尝试保持整个代码相同,只需在代码末尾插入 module_init 和 module_exit。
  • 不能在同一个模块中使用module_platform_driver和module_init/exit,它们是互斥的。

标签: linux-kernel linux-device-driver kernel-module device-tree insmod


【解决方案1】:

如果我使用 module_init 和 module_exit 一切正常

那个简短的“原始”代码只包含模块框架。保证在加载模块时调用 init 例程,并在卸载之前调用 exit 例程。那个“原始”代码不是驱动程序。

较长的内核模块是一个驱动程序并被加载,但由于它具有默认的初始化和退出代码,不执行任何操作(由 module_platform_driver() 宏的扩展生成),因此有没有消息。当内核使用设备树时,不保证调用可加载模块中的驱动程序代码。

为什么这个内核模块在我加载它时什么都不做?

驱动程序的探测函数(将输出消息)可能没有被调用,因为您的设备树中没有任何内容表明需要此设备驱动程序。

板子的Device Tree的sn-p有

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

但驱动程序声明它应该指定为

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

这些字符串应该匹配,以便驱动程序可以与设备树节点中的此引用设备绑定。

设备节点也应该声明为

    status = "okay";

覆盖任何可能禁用设备的默认状态。

设备树中正确配置的节点应该可以按预期执行驱动程序的探测功能。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2013-01-17
    • 2020-05-24
    • 2020-07-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-07-31
    相关资源
    最近更新 更多