Linuxでデバイスにバインドできないドライバをデバッグする方法は?

Linuxでデバイスにバインドできないドライバをデバッグする方法は?

私のドライバに次のデバイスが設定されていない理由を見つけようとしています。クリエイター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

実行中のシステムをデバッグする方法を説明するいくつかの異なる記事が見つかりました。たとえば、次のようになります。

この投稿の情報は正確ですが、私にとってはあまり役に立ちません。カーネルをローカルで構築しているので(printkドライバの検索機能に追加jz4780-rng)質問は次のとおりです。

  • コンパイル時にどのオプションをオンにする必要がありますか?カーネルがドライバプローブ機能呼び出しの失敗に関する正確な情報を印刷するにはjz4780-rng
  • 特にテスト済みのバス/運転者の完全なリストを印刷するにはどうすればよいですかdriver_probe_device

printkデバッグのためにコードのどこにでも追加できます。問題は、どの関数がデバイスツリーを探索し、プローブ/初期化関数を呼び出すかです。

参考までに:

$ 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

答え1

ドライバをデバイスにバインドするための考えられる解決策は次のとおりです。

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

これは他の事例を見てわかりました。私は以前の試みが間違った理由について正しい診断を受けることができる解決策を好みます。

関連情報