
platform device
이 질문은 부팅 시 내장 드라이버가 초기화되는 방식을 이해하려는 시도에서 나온 것입니다 .
SoC(ARM + FPGA)에서 임베디드 Linux 배포판(Yocto)을 사용하고 있습니다. 장치 드라이버는 a용으로 작성되었으며 platform device
IP는 플랫폼 장치로 설명된 장치 트리에서 찾을 수 있습니다. "호환" 속성은 C 드라이버와 일치하며 지금까지는 모두 양호했습니다.
플랫폼 장치에 대한 커널 문서 인용[1],
일반적으로 '호환' 속성을 가진 모든 노드는 어떤 종류의 장치를 나타내는 것으로 가정하며, 둘째, 트리 루트에 있는 모든 노드는 프로세서 버스에 직접 연결되거나 기타 시스템이라고 가정할 수 있습니다. 달리 설명할 수 없는 장치.이러한 각 노드에 대해 Linux는 platform_device를 할당하고 등록하며, 이는 차례로 platform_driver에 바인딩될 수 있습니다.
뿐만 아니라
2.4 장치 모집단
보드가 식별되고 초기 구성 데이터가 구문 분석된 후 커널 초기화가 일반적인 방법으로 진행될 수 있습니다. [...] 이는 ARM의 machine_desc .init_early(), .init_irq() 및 .init_machine() 후크와 같은 시스템별 설정 후크가 호출되는 경우이기도 합니다.
[...]
DT 컨텍스트에서 가장 흥미로운 후크는 플랫폼에 대한 데이터로 Linux 장치 모델을 채우는 일을 주로 담당하는 .init_machine()입니다.
그리고 결국 (Tegra 보드를 사용한 문서 예제를 따르십시오)
.init_machine() 시간에 Tegra 보드 지원 코드는 이 DT를 확인하고 platform_devices를 생성할 노드를 결정해야 합니다.
그리고 물론, arch/arm
[2init_machine
] 장치 트리를 "조회"하는 기능을 찾을 수 있습니다 . 그러나 arm64 아키텍처에는 이 기능이 존재하지 않습니다. 구조체machine_desc
팔 아치에만 존재.
소스 코드를 탐색하면서 장치 트리에서 일부 작업을 찾을 수 있었는데 그 중 setup_machine_fdt에서 발생하는 작업 중 어느 것도 이해하기 쉽지 않았습니다.4] 전화를 걸 early_dt_scan
었지만 그들은장치를 채우지 않는 것 같습니다:
/* Retrieve various information from the /chosen node */
rc = of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line);
/* Initialize {size,address}-cells info */
of_scan_flat_dt(early_init_dt_scan_root, NULL);
/* Setup memory, calling early_init_dt_add_memory_arch */
of_scan_flat_dt(early_init_dt_scan_memory, NULL);
여기서 문제는 부팅 프로세스를 계속 따르면 결국 , 및 을 차례로 do_basic_setup
호출 하게 된다는 것입니다 .driver init
bus_init
platform_bus_init
of_core_init
"devicetree"라는 kset을 생성하는 마지막 항목에 대해 몇 가지 희망이 있었습니다. 그러나 여기서 트리가 실제로 구문 분석되는지는 이해할 수 없습니다.
그 후에 initcalls
호출됩니다. 즉, 드라이버 초기화가 발생하지만 여기서 DT 구문 분석은 어디에 포함되었습니까? "호환" 속성은 실제로 어디에 사용되었나요? 다시 문서에서 :
비결은 커널이 트리의 루트에서 시작하여 '호환' 속성을 가진 노드를 찾는 것입니다. 첫째, 일반적으로 '호환' 속성을 가진 모든 노드는 어떤 종류의 장치를 나타내는 것으로 가정하고, 둘째, 트리 루트에 있는 모든 노드는 프로세서 버스에 직접 연결되거나 프로세서 버스에 연결되어 있다고 가정할 수 있습니다. 다른 방법으로는 설명할 수 없는 기타 시스템 장치입니다. 이들 노드 각각에 대해,Linux는 platform_device를 할당하고 등록하며, 이는 다시 platform_drive에 바인딩될 수 있습니다.
"플랫폼 드라이브에 바인딩" 부분은 드라이버 코드에 정의된 initcall에 의해 수행됩니다. 제가 이해하지 못하는 것은 "플랫폼 장치 할당 및 등록"입니다.