
platform device
Esta pregunta surge de mis intentos de comprender cómo se inicializa un controlador integrado en el momento del arranque.
Estoy usando una distribución de Linux integrada (Yocto) en un SoC (ARM + FPGA). El controlador del dispositivo está escrito para a platform device
y la IP se puede encontrar en el árbol de dispositivos, descrito como dispositivo de plataforma. La propiedad "compatible" coincide con el controlador C, todo bien hasta ahora.
Citando los documentos del kernel para dispositivos de plataforma[1],
Generalmente se supone que cualquier nodo con una propiedad "compatible" representa un dispositivo de algún tipo y, en segundo lugar, se puede suponer que cualquier nodo en la raíz del árbol está conectado directamente al bus del procesador o es un sistema misceláneo. dispositivo que no se puede describir de otra manera.Para cada uno de estos nodos, Linux asigna y registra un dispositivo_plataforma, que a su vez puede estar vinculado a un controlador_plataforma.
pero también
2.4 Población de dispositivos
Una vez que se ha identificado la placa y después de que se han analizado los datos de configuración iniciales, la inicialización del kernel puede continuar de la manera normal. [...] Aquí también es cuando se llamarán los ganchos de configuración específicos de la máquina, como los ganchos machine_desc .init_early(), .init_irq() y .init_machine() en ARM.
[...]
El gancho más interesante en el contexto de DT es .init_machine(), que es el principal responsable de completar el modelo de dispositivo Linux con datos sobre la plataforma.
y finalmente (siguiendo el ejemplo de los documentos con la placa Tegra)
En el momento .init_machine(), el código de soporte de la placa Tegra deberá mirar este DT y decidir para qué nodos crear platform_devices.
Y efectivamente, investigando arch/arm
[2] Puedo encontrar la init_machine
función que "busca" en el árbol de dispositivos. Sin embargo, esta función no existe para la arquitectura arm64. la machine_desc
estructurasolo existe para arco de brazo.
Navegando por el código fuente pude localizar algunas operaciones en el árbol de dispositivos, ninguna de ellas fácil de entender, sucediendo en setup_machine_fdt [4] que llama early_dt_scan
pero ellosno parece poblar los dispositivos:
/* 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);
El problema aquí es que si sigo siguiendo el proceso de arranque llego a do_basic_setup
lo que a su vez llama a driver init
, bus_init
y platform_bus_init
eventualmente a of_core_init
.
Tenía algunas esperanzas con el último, que crea un kset llamado "devicetree". Sin embargo, no entiendo si el árbol realmente se analiza aquí.
Después de esto, initcalls
se llaman, lo que significa que se producirá la inicialización del controlador, pero ¿dónde estuvo involucrado el análisis de DT aquí? ¿Dónde se utilizó realmente la propiedad "compatible"? Nuevamente de los documentos:
El truco es que el kernel comienza en la raíz del árbol y busca nodos que tengan una propiedad "compatible". En primer lugar, generalmente se supone que cualquier nodo con una propiedad "compatible" representa un dispositivo de algún tipo y, en segundo lugar, se puede suponer que cualquier nodo en la raíz del árbol está conectado directamente al bus del procesador o es un dispositivo de sistema diverso que no se puede describir de otra manera. Para cada uno de estos nodos,Linux asigna y registra un dispositivo_plataforma, que a su vez puede vincularse a una unidad_plataforma.
La parte "vinculada a la unidad de plataforma" se realiza mediante la llamada inicial definida por el código del controlador, lo que no entiendo es "asigna y registra un dispositivo de plataforma".
[1]Linux y el árbol de dispositivos