linux-kernel - 设备树不匹配 : . 从未调用过探测器

标签 linux-kernel arm linux-device-driver device-tree

我无法理解设备树是如何工作的,或者特别是为什么这个驱动程序不会启动。这是用于 android 的 Rockchip 供应商内核,版本 3.10

驱动程序/看门狗/rk29_wdt.c (为了可读性而减少)

static const struct of_device_id of_rk29_wdt_match[] = {
    { .compatible = "rockchip,watch dog" }
};
static struct platform_driver rk29_wdt_driver = {
    .probe          = rk29_wdt_probe,
    [..]
            .of_match_table = of_rk29_wdt_match,
            .name   = "rk29-wdt",
    },
};

static int __init watchdog_init(void)
{ 
    printk("watchdog_init\n");
    return platform_driver_register(&rk29_wdt_driver);
}

这是soc dtsi

拱/臂/引导/dts/rk3288.dtsi
    watchdog: wdt@2004c000 {
            compatible = "rockchip,watch dog";
            reg = <0xff800000 0x100>;
            clocks = <&pclk_pd_alive>;
            clock-names = "pclk_wdt";
            interrupts = <GIC_SPI 79 IRQ_TYPE_LEVEL_HIGH>;
            rockchip,irq = <0>;
            rockchip,timeout = <2>;
            rockchip,atboot = <1>;
            rockchip,debug = <0>;
            status = "okay";
    };

但是,驱动程序的 .probe 函数永远不会被调用。它被编译并调用 __init 函数。我怀疑它与设备树条目不匹配有关?也许空间是个问题?

还是在 .probe 之前运行其他任何东西来确定驱动程序是否应该继续?

另外我不确定扁平树是如何工作的,所以也许这是相关的:

拱/臂/mach-rockchip/rk3288
DT_MACHINE_START(RK3288_DT, "Rockchip RK3288 (Flattened Device Tree)")
    .smp            = smp_ops(rockchip_smp_ops),
    .map_io         = rk3288_dt_map_io,
    .init_time      = rk3288_dt_init_timer,
    .dt_compat      = rk3288_dt_compat,
    .init_late      = rk3288_init_late,
    .reserve        = rk3288_reserve,
    .restart        = rk3288_restart,
MACHINE_END

最佳答案

发生这种情况的方式有很多种,其中大多数都远离驱动程序代码本身。首先,仅 .dtsi 片段并不能说明全部情况 - 设备树语法是分层的,因此属性(特别是 status )可能仍会被包含基本 SoC 的板级 .dts 覆盖。 .dtsi 文件。其次,编译后的 DTB 也不是硬道理,因为引导加载程序可能会在将其传递给内核之前对其进行动态修改——这通常用于内存节点和 SMP 启用方法,但可能会影响任何事情。

这种调试通常最好反过来解决,通过检查启动系统的状态,然后向后工作以找出事情是如何发展的——这个特定问题的细节已经排除了其中一些,但是为了完整性:

  • 如果内核知道驱动程序,并且它已加载并正确初始化,它应该显示在/sys/bus/*/drivers/中的某个位置 - 否则,它可能位于需要加载的模块中,或者它可能无法初始化由于对其他驱动程序或资源的一些未满足的依赖。
  • 如果内核知道该设备,它应该出现在/sys/bus/*/devices/中的某个位置,并且如果它正确绑定(bind)到驱动程序并进行了探测,那么它们应该都具有彼此的符号链接(symbolic link)。
  • 如果找不到设备,那么在基于 DT 的系统上,下一个要检查的地方是/proc/device-tree/(取决于旧内核上的 CONFIG_PROC_DEVICETREE,并且在/sys/firmware/devicetree/base 中可以找到)/在较新的上) - 这将显示内核找到它时的 DT View ,并且在那里稍微戳一下应该可以清除任何丢失的节点或不合适的属性,例如导致内核的禁用节点完全跳过创 build 备。请注意,属性文件本身只是原始数据——因此您可能希望使用 hexdump 而不是 cat 进行窥探——并且所有数字单元格都是大端字节序。
  • 关于linux-kernel - 设备树不匹配 : . 从未调用过探测器,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35580862/

    相关文章:

    python - 无需 CUPS 即可获取 USB 打印机信息

    c - recvmsg 返回 EDEADLK?

    linux - 在linux下安装补丁

    linux - arm linux中MMU页表中的缓存属性

    security - TrustZone 与虚拟机管理程序

    arm - NEON :float32x4_t 向量中最多四个浮点值

    c - 平台设备;为什么是 'alloc' 和 'add' ?

    linux-kernel - 标志 PF_MEMALLOC 有什么用

    linux - 如何使用QEMU学习ARM Linux内核开发?

    c - block 设备 - 当不是 512 字节的倍数时初始化 gendisk 结构