Introdução ao Mecanismo de Implementação do Subsistema de Firmware Linux

1. Visão geral do subsistema de firmware do Linux

Firmware é um pedaço de programa que o próprio dispositivo de hardware executa. O firmware geralmente é armazenado no flash do dispositivo. Por uma questão de custo e conveniência, o programa operacional do dispositivo de hardware geralmente é empacotado em um arquivo de firmware em um formato específico, armazenado no sistema do terminal, e o dispositivo de hardware é atualizado por meio do sistema do terminal. Durante o processo de desenvolvimento do kernel do Linux, os desenvolvedores depuram os dispositivos periféricos, como toque, carregamento, motores lineares, armazenamento, dispositivos WIFI, etc., e também há casos em que o firmware precisa ser atualizado. No sistema Linux, o driver do dispositivo está no estado do kernel e o arquivo do firmware está no estado do usuário, portanto, é necessário um mecanismo seguro, estável e confiável para garantir que o driver do dispositivo carregue com êxito o arquivo do firmware. Para resolver o problema dos drivers de dispositivo que carregam arquivos de firmware do modo de usuário de forma estável a partir do modo kernel, o sistema Linux fornece um subsistema de firmware.

2. Mecanismo de implementação do subsistema de firmware do Linux

1. Introdução ao processo:

O subsistema de firmware do Linux é implementado com base no mecanismo sysfs e uevent.

Depois que o driver chama a interface de função do sistema de firmware para solicitar o firmware, o subsistema de firmware usa o método de compilação do kernel para obter o firmware; se a aquisição falhar, ele usa o cache do firmware para obter o firmware; se a aquisição ainda falhar , ele usa o caminho padrão para procurar diretamente a maneira do kernel de obter o firmware. Se a aquisição ainda falhar, reporte a mensagem uevent ao processo init. O processo init recebe a mensagem uevent e filtra as mensagens cujo tipo de subsistema é firmware. O processo init procura o firmware de acordo com as informações do firmware apontadas na mensagem uevent e grava o conteúdo do firmware obtido do estado do usuário para o estado do kernel através da interface do nó de arquivo fornecida pelo sysfs, para que o driver possa obter os dados do arquivo de firmware.

O sistema de firmware Linux fornece uma variedade de métodos para obter arquivos de firmware em diferentes cenários.

1) O método de compilar diretamente para o kernel;

2) O modo de cache do firmware;

3) Especifique diretamente o caminho de acordo com o kernel:

4) A forma de auxiliar no processamento através do processo init;

2. Fluxograma:

3. Interface de função principal:

Interface de função principal: Os principais tipos de interfaces de firmware de aplicativo são divididos em síncrono e assíncrono.

Normalmente, o processo de solicitação de firmware é demorado e o processo de processamento de atualizações de firmware é demorado, portanto, pode ser realizado usando uma interface de função assíncrona ou criando uma fila de trabalho no driver para chamar uma interface de função síncrona . em:

  • O kernel aplica-se a um arquivo de firmware chamando a função request_firmware.
  • Depois que o kernel obtém o arquivo de firmware, ele chama release_firmware para liberar a memória relacionada.

em:

  • A interface request_firmware_direct apenas procura firmware no caminho especificado pelo kernel e não usa o mecanismo uevent para obter firmware.
  • A interface request_firmware_nowait obtém o firmware por meio de uma fila de trabalho assíncrona, que pode desempenhar um papel em não bloquear o tempo de investigação de condução.

4. Processo de implementação:

(1) processo de implementação request_firmware:

A função request_firmware define diferentes bits de sinalizador chamando a função _request_firmware_prepare para realizar diferentes funções de diferença.

a. função _request_firmware_prepare:

Com base na ativação da chave de macro CONFIG_FW_LOADER, primeiro verifique se o arquivo de firmware está compilado no kernel chamando a função fw_get_builtin_firmware.

Em seguida, chame a função fw_lookup_and_allocate_buf para determinar se a lista vinculada na estrutura global fw_cache registrou o nome do firmware de solicitação atual. Se o nome do firmware solicitado atualmente não existir, aloque dinamicamente o espaço de memória correspondente e adicione o nome do firmware solicitado atualmente à lista vinculada na estrutura fw_cache global.

b. função fw_get_filesystem_firmware:

Principalmente através do caminho padrão fornecido pelo kernel para encontrar o arquivo de firmware, chame a função kernel_read_file_from_path. Se o arquivo de firmware não for encontrado, julgue se deseja ativar o modo USER_HELPER por meio do bit de sinalização FW_OPT_USERHELPER.

em:

O caminho padrão no sistema de firmware é o seguinte:

O caminho padrão pode adicionar um caminho por meio da linha de comando do kernel e passá-lo para o caminho variável por meio da interface module_param_string para personalizar o novo caminho.

  Informações por meio do trem: rota de aprendizado da tecnologia de código-fonte do kernel do Linux + tutorial em vídeo do código-fonte do kernel

Learning through train: Linux kernel code memory tuning file system process management device driver/network protocol stack

(2) Modo USER_HELPER:

Este recurso só é suportado depois que o kernel abre CONFIG_FW_LOADER_USER_HELPER. A função principal é relatar a mensagem uevent para o processo init por meio do kernel e obter as informações do firmware por meio do processo init e gravá-las no nó sysfs subjacente.

a. função fw_load_from_user_helper:

Primeiro, chame a função fw_create_instance para criar o dispositivo, o arquivo de classe e o arquivo de atributo e aloque a estrutura firmware_priv.

Um diretório será então criado em /sys/class/firmware com o nome do dispositivo como seu nome de diretório.

Este diretório contém três propriedades:

  • carregando:

Definido como 1: Este atributo é definido como 1 pelo espaço do usuário responsável por carregar o firmware;

Defina como 0: quando o processo de carregamento estiver concluído;

Definido como -1: encerrará o processo de carregamento do firmware.

  • dados:

É usado para receber dados de firmware. Após o carregamento ser definido, o processo de espaço do usuário grava o firmware neste atributo.

  • dispositivo:

Um link simbólico para a entrada correspondente em /sys/devices.

  • tempo esgotado:

Por padrão, o período de tempo limite máximo de solicitação de firmware por meio do uevent é 60S, e o período de tempo limite de gravação da camada superior é suportado. b. Função _request_firmware_load:

Primeiro, desabilite o relatório uevent, adicione um dispositivo chamando a função device_add e dispare a chamada para a função firmware_uevent. Entre eles, preencha o formato das informações informadas pelo uevent, incluindo o nome do firmware, tempo limite e se é assíncrono.

A próxima etapa é ativar a função de relatório uevent e, ao mesmo tempo, chamar a função kobject_uevent para relatar o tipo de ação de adição à camada superior ueventd.

Em seguida, chame a função fw_state_wait_timeout para aguardar o processamento do ueventd da camada superior dentro do período de tempo limite predefinido.

Se o período de tempo limite for atingido ou o despertar for recebido, a memória solicitada anteriormente será liberada e as informações de memória, como dispositivo e classe, serão liberadas.

(3) fluxo de processamento de firmware relacionado a ueventd

Ueventd é um módulo importante no processo init. Ele lida principalmente com selinux, criação de dispositivos de desenvolvimento, ouvindo o kernel para relatar mensagens uevent, carregamento de firmware, etc.

a. Fluxo de processamento do FirmwareHandler:

O método HandleUevent em FirmwareHandler lida principalmente com o processo de interação entre o carregamento do firmware e os nós subjacentes.

Em primeiro lugar, julga-se que o tipo de subsistema da mensagem uevent é o campo de firmware antes do processamento.Este tipo é relatado apenas pelo módulo de firmware no kernel.

HandleUevent cria principalmente diferentes sub-threads por meio de um thread principal e processa solicitações de firmware de diferentes drivers do kernel em paralelo.

b. Função ProcessFirmwareEvent:

A primeira etapa é fazer um loop para determinar se o arquivo de firmware de pesquisa existe no caminho suportado por ueventd; se existir, grave o arquivo de atributo de carregamento subjacente em 1, copie o arquivo de firmware obtido e grave-o no arquivo de dados subjacente. Após a conclusão, ele será gravado no arquivo de propriedade de carregamento subjacente como 0.

Até agora, o kernel obteve as informações do arquivo de firmware gravadas pelo espaço do usuário.

em:

O ueventd suporta o caminho para procurar firmware por padrão:

Do firmware_directory especificado no arquivo ueventd.rc.

Autor Original: Kernel Craftsman

 

Acho que você gosta

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