如何在Linux上调试未能绑定到设备的驱动程序?

马拉特

我试图弄清楚为什么未在Creator CI20上将以下设备设置为其驱动程序作为参考,我正在使用Linux内核v4.13.0并在本地进行编译:

make ARCH=mips ci20_defconfig
make -j8 ARCH=mips CROSS_COMPILE=mipsel-linux-gnu- uImage

从正在运行的系统中,我可以看到:

ci20@ci20:~# find /sys | grep rng
/sys/firmware/devicetree/base/jz4780-cgu@10000000/rng@d8
/sys/firmware/devicetree/base/jz4780-cgu@10000000/rng@d8/compatible
/sys/firmware/devicetree/base/jz4780-cgu@10000000/rng@d8/name
/sys/bus/platform/drivers/jz4780-rng
/sys/bus/platform/drivers/jz4780-rng/bind
/sys/bus/platform/drivers/jz4780-rng/unbind
/sys/bus/platform/drivers/jz4780-rng/uevent

因此内核在运行时可以看到该设备,现在缺少的部分是为什么驱动程序从未绑定?我本来希望是这样的:

/sys/bus/platform/drivers/jz4780-rng/100000d8.rng

我确实找到了其他一些文章来解释如何调试正在运行的系统,例如:

尽管这些帖子的信息准确无误,但对我来说却不是很有帮助。由于我是在本地构建内核(我printkjz4780-rng驱动程序的probe函数中添加),所以我的问题是:

  • 我应该在编译时打开什么选项,以便内核在无法调用jz4780-rng驱动程序的probe函数时打印出准确的信息
  • 特别是,我该如何打印经过测试的总线/驱动器的完整列表driver_probe_device

printk可以在代码中的任何地方进行调试。问题是:哪个函数正在遍历设备树并调用probe / init函数?

以供参考:

$ dtc -I fs -O dts /sys/firmware/devicetree/base | grep -A 1 rng
              rng@d8 {
                      compatible = "ingenic,jz4780-rng";
              };

兼容字符串声明为:

cgu: jz4780-cgu@10000000 {
    compatible = "ingenic,jz4780-cgu", "syscon";
    reg = <0x10000000 0x100>;

    clocks = <&ext>, <&rtc>;
    clock-names = "ext", "rtc";

    #clock-cells = <1>;

    rng: rng@d8 {
        compatible = "ingenic,jz4780-rng";
    };
};

并在驱动程序中为:

static const struct of_device_id jz4780_rng_dt_match[] = {
    {
        .compatible = "ingenic,jz4780-rng",
    },
    { },
};
MODULE_DEVICE_TABLE(of, jz4780_rng_dt_match);

static struct platform_driver jz4780_rng_driver = {
    .driver     = {
        .name   = "jz4780-rng",
        .of_match_table = jz4780_rng_dt_match,
    },
    .probe      = jz4780_rng_probe,
    .remove     = jz4780_rng_remove,
};
module_platform_driver(jz4780_rng_driver);

更新1:

当我使用构建内核时CONFIG_DEBUG_DRIVER=y,可以看到以下内容:

# grep driver_probe_device syslog
Sep  6 10:08:07 ci20 kernel: [    0.098280] bus: 'platform': driver_probe_device: matched device 10031000.serial with driver ingenic-uart
Sep  6 10:08:07 ci20 kernel: [    0.098742] bus: 'platform': driver_probe_device: matched device 10033000.serial with driver ingenic-uart
Sep  6 10:08:07 ci20 kernel: [    0.099209] bus: 'platform': driver_probe_device: matched device 10034000.serial with driver ingenic-uart
Sep  6 10:08:07 ci20 kernel: [    0.106945] bus: 'platform': driver_probe_device: matched device 1b000000.nand-controller with driver jz4780-nand
Sep  6 10:08:07 ci20 kernel: [    0.107282] bus: 'platform': driver_probe_device: matched device 134d0000.bch with driver jz4780-bch
Sep  6 10:08:07 ci20 kernel: [    0.107470] bus: 'platform': driver_probe_device: matched device 16000000.dm9000 with driver dm9000
Sep  6 10:08:07 ci20 kernel: [    0.165618] bus: 'platform': driver_probe_device: matched device 10003000.rtc with driver jz4740-rtc
Sep  6 10:08:07 ci20 kernel: [    0.166177] bus: 'platform': driver_probe_device: matched device 10002000.jz4780-watchdog with driver jz4740-wdt
Sep  6 10:08:07 ci20 kernel: [    0.170930] bus: 'platform': driver_probe_device: matched device 1b000000.nand-controller with driver jz4780-nand

但是只有:

# grep rng syslog
Sep  6 10:08:07 ci20 kernel: [    0.166842] bus: 'platform': add driver jz4780-rng
Sep  6 10:08:42 ci20 kernel: [   54.584451] random: crng init done

附带说明一下,此处未引用rng顶级节点:cgu,但有一个jz4780-cgu驱动程序。


更新2:

如果将rng节点声明移到顶级cgu节点之外,至少可以看到最后发生了一些绑定:

# grep rng /var/log/syslog 
Sep  6 10:30:57 ci20 kernel: [    0.167017] bus: 'platform': add driver jz4780-rng
Sep  6 10:30:57 ci20 kernel: [    0.167033] bus: 'platform': driver_probe_device: matched device 10000000.rng with driver jz4780-rng
Sep  6 10:30:57 ci20 kernel: [    0.167038] bus: 'platform': really_probe: probing driver jz4780-rng with device 10000000.rng
Sep  6 10:30:57 ci20 kernel: [    0.167050] jz4780-rng 10000000.rng: no pinctrl handle
Sep  6 10:30:57 ci20 kernel: [    0.167066] devices_kset: Moving 10000000.rng to end of list
Sep  6 10:30:57 ci20 kernel: [    0.172774] jz4780-rng: probe of 10000000.rng failed with error -22
Sep  6 10:31:32 ci20 kernel: [   54.802794] random: crng init done

使用:

    rng: rng@100000d8 {
        compatible = "ingenic,jz4780-rng";
    };

我还可以验证:

# find /sys/ | grep rng
/sys/devices/platform/10000000.rng
/sys/devices/platform/10000000.rng/subsystem
/sys/devices/platform/10000000.rng/driver_override
/sys/devices/platform/10000000.rng/modalias
/sys/devices/platform/10000000.rng/uevent
/sys/devices/platform/10000000.rng/of_node
/sys/firmware/devicetree/base/rng@100000d8
/sys/firmware/devicetree/base/rng@100000d8/compatible
/sys/firmware/devicetree/base/rng@100000d8/status
/sys/firmware/devicetree/base/rng@100000d8/reg
/sys/firmware/devicetree/base/rng@100000d8/name
/sys/bus/platform/devices/10000000.rng
/sys/bus/platform/drivers/jz4780-rng
/sys/bus/platform/drivers/jz4780-rng/bind
/sys/bus/platform/drivers/jz4780-rng/unbind
/sys/bus/platform/drivers/jz4780-rng/uevent
马拉特

使驱动程序绑定到设备的可行解决方案是:

cgublock: jz4780-cgublock@10000000 {
    compatible = "simple-bus", "syscon";

    #address-cells = <1>;
    #size-cells = <1>;

    reg = <0x10000000 0x100>;
    ranges;

    cgu: jz4780-cgu@10000000 {
        compatible = "ingenic,jz4780-cgu";
        reg = <0x10000000 0x100>;

        clocks = <&ext>, <&rtc>;
        clock-names = "ext", "rtc";

        #clock-cells = <1>;
    };

    rng: rng@d8 {
        compatible = "ingenic,jz4780-rng";
        reg = <0x100000d8 0x8>;
    };
};

盯着其他例子可以发现这一点。我希望能得到正确诊断的解决方案,以便能正确解释为什么先前的尝试是不正确的。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章

如何在Linux设备驱动程序中设置errno?

如何为USB-HID设备使用Linux内核驱动程序绑定/取消绑定接口?

自动将设备绑定到特定驱动程序

如何从Linux驱动程序访问和调试FDT / DTS设备树(seg-fault)

Linux下如何从块设备驱动程序执行I/O到块设备

从设备属性读取时,在container_of上调试简单的char驱动程序失败

如何将驱动程序与USB设备绑定?

Linux:如何查找用于设备的设备驱动程序?

如何在设备上调试

如何在Cassandra C ++驱动程序中绑定到UDT的集合

如何在INSERT,Cassandra C ++驱动程序中将值绑定到TTL

如何在正在运行的Debian Linux机器上换出网络设备的驱动程序?

如何在Linux上找到与SATA设备关联的驱动程序(模块)?

如何在Linux上找到与设备关联的驱动程序(模块)?

在Linux上调试简单的char驱动程序在device_create()上失败

如何编写简单的Linux设备驱动程序?

如何练习编写真正的Linux设备驱动程序?

Linux内核驱动程序-SPI如何识别SPI设备?

linux内核驱动程序调试日志

使用 RxSwift、驱动程序并绑定到

Linux设备驱动程序访问控制

IOCTL Linux设备驱动程序

Linux字符设备驱动程序问题

linux 设备驱动程序文档

如何更新设备驱动程序?

USB存储驱动程序如何在Linux中工作?

如何在 Linux 驱动程序中列出 MMC 分区?

如何在使用中更改驱动程序Linux

绑定I2C设备驱动程序