내 드라이버에 다음 장치가 설정되지 않은 이유를 알아내려고 합니다.크리에이터 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
실행 중인 시스템을 디버깅하는 방법을 설명하는 몇 가지 다른 게시물을 찾았습니다. 예를 들면 다음과 같습니다.
- https://stackoverflow.com/questions/28406776/driver-bound-using-device-tree-without-known-string-in-the-driver
- https://stackoverflow.com/questions/35580862/device-tree-mismatch-probe-never-known
- https://stackoverflow.com/questions/41446737/platform-device-driver-autoloading-mechanism
- 실행 중인 커널의 /sys를 사용하여 장치 트리에 대한 정보를 얻을 수 있습니까?
이 게시물의 정보는 정확하지만 나에게는 별로 도움이 되지 않습니다. 커널을 로컬에서 구축 중이므로( 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>;
};
};
이는 다른 사례를 살펴보면서 알게 되었습니다. 나는 이전 시도가 잘못된 이유에 대해 올바른 진단을 받을 수 있는 솔루션을 선호합니다.