Introducción al mecanismo de implementación del subsistema de firmware de Linux

1. Descripción general del subsistema de firmware de Linux

El firmware es una pieza de programa que ejecuta el propio dispositivo de hardware. El firmware generalmente se almacena en la memoria flash del dispositivo. En aras del costo y la conveniencia, el programa operativo del dispositivo de hardware generalmente se empaqueta en un archivo de firmware en un formato específico, se almacena en el sistema terminal y el dispositivo de hardware se actualiza a través del sistema terminal. Durante el proceso de desarrollo del kernel de Linux, los desarrolladores depuran dispositivos de unidades periféricas, como dispositivos táctiles, de carga, motores lineales, dispositivos de almacenamiento, WIFI, etc., y también hay casos en los que es necesario actualizar el firmware. En el sistema Linux, el controlador del dispositivo está en estado kernel y el archivo de firmware está en estado de usuario, por lo que se necesita un mecanismo seguro, estable y confiable para garantizar que el controlador del dispositivo cargue correctamente el archivo de firmware. Para resolver el problema de los controladores de dispositivos que cargan archivos de firmware en modo usuario de manera estable desde el modo kernel, el sistema Linux proporciona un subsistema de firmware.

2. Mecanismo de implementación del subsistema de firmware de Linux

1. Introducción al proceso:

El subsistema de firmware de Linux se implementa en base a sysfs y mecanismo uevent.

Después de que el controlador llama a la interfaz de función del sistema de firmware para solicitar el firmware, el subsistema de firmware usa el método de compilación del kernel para obtener el firmware; si falla la adquisición, usa la caché de firmware para obtener el firmware; si la adquisición sigue fallando , utiliza la ruta predeterminada para buscar directamente la forma del kernel para obtener el firmware. Si la adquisición aún falla, informe el mensaje uevent al proceso de inicio. El proceso init recibe el mensaje uevent y filtra los mensajes cuyo tipo de subsistema es firmware. El proceso de inicio busca el firmware de acuerdo con la información del firmware señalada en el mensaje uevent y escribe el contenido del firmware obtenido desde el estado del usuario hasta el estado del kernel a través de la interfaz de nodo de archivo proporcionada por sysfs, para que el controlador pueda obtener los datos. del archivo de firmware.

El sistema de firmware de Linux proporciona una variedad de métodos para obtener archivos de firmware en diferentes escenarios.

1) El método de compilar directamente al núcleo;

2) La forma de caché de firmware;

3) Especifique directamente la ruta según el kernel:

4) La forma de ayudar en el procesamiento a través del proceso init;

2. Diagrama de flujo:

3. Interfaz de función principal:

Interfaz de función principal: los principales tipos de interfaces de firmware de aplicaciones se dividen en síncronas y asíncronas.

Por lo general, el proceso de solicitud de firmware lleva mucho tiempo, y el proceso de procesamiento de actualizaciones de firmware lleva mucho tiempo, por lo que se puede realizar utilizando una interfaz de función asíncrona o creando una cola de trabajo en el controlador para llamar a una interfaz de función síncrona. . en:

  • El núcleo solicita un archivo de firmware llamando a la función request_firmware.
  • Después de que el kernel obtiene el archivo de firmware, llama a release_firmware para liberar la memoria relacionada.

en:

  • La interfaz request_firmware_direct solo busca firmware en la ruta especificada por el kernel y no utiliza el mecanismo uevent para obtener firmware.
  • La interfaz request_firmware_nowait obtiene firmware a través de una cola de trabajo asíncrona, que puede desempeñar un papel en no bloquear el tiempo de sondeo de conducción.

4. Proceso de implementación:

(1) proceso de implementación de request_firmware:

La función request_firmware llama a la función _request_firmware_prepare para establecer diferentes bits de bandera para realizar diferentes funciones de diferencia.

a. Función _request_firmware_prepare:

Sobre la base de activar el interruptor macro CONFIG_FW_LOADER, primero juzgue si el archivo de firmware está compilado en el núcleo llamando a la función fw_get_builtin_firmware.

Luego llame a la función fw_lookup_and_allocate_buf para determinar si la lista vinculada en la estructura global fw_cache ha registrado el nombre del firmware de solicitud actual. Si el nombre del firmware solicitado actualmente no existe, asigne dinámicamente el espacio de memoria correspondiente y agregue el nombre del firmware solicitado actualmente a la lista vinculada en la estructura global fw_cache.

B. Función fw_get_filesystem_firmware:

Principalmente a través de la ruta predeterminada proporcionada por el kernel para encontrar el archivo de firmware, llame a la función kernel_read_file_from_path. Si no se encuentra el archivo de firmware, juzgue si habilitar el modo USER_HELPER a través del bit de bandera FW_OPT_USERHELPER.

en:

La ruta predeterminada en el sistema de firmware es la siguiente:

La ruta predeterminada puede agregar una ruta a través de la línea de comando del kernel y pasarla a la ruta variable a través de la interfaz module_param_string para personalizar la nueva ruta.

  Información a través del tren: ruta de aprendizaje de la tecnología del código fuente del kernel de Linux + video tutorial del código fuente del kernel

Aprendizaje a través del entrenamiento: código fuente del kernel de Linux, ajuste de memoria, sistema de archivos, gestión de procesos, controlador de dispositivo/pila de protocolo de red

(2) Modo USER_HELPER:

Esta característica solo se admite después de que el kernel abre CONFIG_FW_LOADER_USER_HELPER. La función principal es informar el mensaje uevent al proceso de inicio a través del kernel y obtener la información del firmware a través del proceso de inicio y escribirlo en el nodo sysfs subyacente.

a. función fw_load_from_user_helper:

Primero llame a la función fw_create_instance para crear el dispositivo, el archivo de clase y el archivo de atributos, y asigne la estructura firmware_priv.

A continuación, se creará un directorio en /sys/class/firmware con el nombre del dispositivo como nombre de directorio.

Este directorio contiene tres propiedades:

  • cargando:

Establecido en 1: este atributo se establece en 1 por el espacio de usuario responsable de cargar el firmware;

Establecido en 0: cuando se completa el proceso de carga;

Establecido en -1: finalizará el proceso de carga del firmware.

  • datos:

Se utiliza para recibir datos de firmware Después de configurar la carga, el proceso de espacio de usuario escribe el firmware en este atributo.

  • dispositivo:

Un enlace simbólico a la entrada correspondiente en /sys/devices.

  • se acabó el tiempo:

De forma predeterminada, el período de tiempo de espera máximo para solicitar firmware a través de uevent es 60S y se admite el período de tiempo de espera de escritura de la capa superior. B. Función _request_firmware_load:

Primero, deshabilite los informes de uevent, agregue un dispositivo llamando a la función device_add y active la llamada a la función firmware_uevent. Entre ellos, complete el formato de información informado por uevent, incluido el nombre del firmware, el tiempo de espera y si es asíncrono.

El siguiente paso es habilitar la función de informes uevent y, al mismo tiempo, llamar a la función kobject_uevent para informar el tipo de acción de agregar a la capa superior ueventd.

Luego llame a la función fw_state_wait_timeout para esperar el procesamiento de la capa superior ueventd dentro del período de tiempo de espera preestablecido.

Si se alcanza el período de tiempo de espera o se recibe una activación, se liberará la memoria solicitada anteriormente y se liberará la información de la memoria, como el dispositivo y la clase.

(3) flujo de procesamiento de firmware relacionado con ueventd

Ueventd es un módulo importante en el proceso de inicio. Se ocupa principalmente de selinux, la creación de dispositivos de desarrollo, la escucha del kernel para informar mensajes de uevent, la carga del firmware del firmware, etc.

a. Flujo de procesamiento de FirmwareHandler:

El método HandleUevent en FirmwareHandler maneja principalmente el proceso de interacción entre la carga del firmware y los nodos subyacentes.

En primer lugar, se considera que el tipo de subsistema del mensaje uevent es el campo de firmware antes del procesamiento.Este tipo solo lo informa el módulo de firmware en el kernel.

HandleUevent crea principalmente diferentes subprocesos a través de un subproceso principal y procesa las solicitudes de firmware de diferentes controladores del kernel en paralelo.

B. Función ProcessFirmwareEvent:

El primer paso es hacer un bucle para determinar si el archivo de firmware de búsqueda existe en la ruta admitida por ueventd; si existe, escriba el archivo de atributos de carga subyacente en 1, copie el archivo de firmware obtenido y escríbalo en el archivo de datos subyacente. Una vez finalizado, se escribirá en el archivo de propiedades de carga subyacente como 0.

Hasta ahora, el kernel ha obtenido la información del archivo de firmware escrita por el espacio del usuario.

en:

ueventd admite la ruta para buscar firmware de forma predeterminada:

Desde el firmware_directory especificado en el archivo ueventd.rc.

Autor original: Kernel Craftsman

 

Supongo que te gusta

Origin blog.csdn.net/youzhangjing_/article/details/132211967
Recomendado
Clasificación