Problemas e recursos da implementação UEFI em várias plataformas

Aproximadamente dezenove anos se passaram desde o lançamento da primeira especificação EFI no ano 2000. A interface levou dez anos para entrar no mercado de usuários e ganhar uma posição nele. No momento, raramente você vê um computador moderno sem UEFI no firmware da placa-mãe. O padrão de interface aumentou a "carne" e vários milhares de páginas na documentação oficial. Para o usuário médio, nada mudou, exceto colisões ocasionais com o Secure Boot ativado. Mas se o plano de trabalho muda para o desenvolvimento, tudo se torna mais interessante.



O próprio conceito da arquitetura modular da UEFI implica que esses módulos não podem ser usados ​​apenas na configuração padrão, mas também fazer o download de algo próprio. O driver do sistema de arquivos (não limitado ao nativo eFi-shy FAT?), Drivers periféricos, aplicativos, gerenciadores de inicialização - você pode carregar tudo manualmente, seria bom carregar um pouco do Shell. Você pode dar um passo "mais profundo" e observar o conteúdo do firmware, evitando dançar com o SecureBoot e a necessidade de escrever uma camada de scripts (há artigos suficientes nas páginas do hub).

Nesta base, nasceu a ideia de criar módulos funcionais que executam várias funções de segurança antes de carregar o sistema operacional, o que pode unir-se e se tornar um tipo de ambiente de inicialização confiável integrado, afetando os serviços da interface de inicialização e tempo de execução, de forma que entre os módulos no firmware e os módulos no disco nada poderia ser "empurrado" sem intervenção de baixo nível e depois deles - somente com a permissão do administrador de segurança.

A implementação dessa idéia nos apresentou um grande número de nuances e sutilezas do UEFI - começando com muitos recursos, bugs e documentos não documentados ou mal documentados e terminando com o comportamento indefinido tão amado por todos os desenvolvedores. Vamos começar em ordem.

Dependência de plataforma




A primeira coisa que você precisa descobrir ao se integrar à plataforma é se podemos trabalhar com ela? A versão da especificação UEFI é importante e, na maioria dos dispositivos, é apresentada na faixa entre 2,1 e 2,7. O mais novo ainda não chegou ao suporte de pesquisa. O mais antigo é encontrado e seu desempenho pode ser limitado devido à falta dos protocolos necessários ou dos drivers escritos de forma incorreta para sua implementação. Por exemplo, UnicodeCollation geralmente não é suficiente. Ao acessar smbios, existem erros não documentados, as funções de alteração de idioma por meio de SetVariable () não funcionam. Tudo pode acontecer, dependendo do fornecedor e da atualização, porque às vezes você precisa colocar seus protocolos até em placas relativamente novas.

Mesmo em nossa prática, tive a sorte de encontrar dois mini-computadores com Intel Bay Trail D e firmware de 32 bits a bordo. O caso é raro, mas ao mesmo tempo tornou necessário recompilar urgentemente os módulos. Na verdade, como a pergunta: encontraremos uma plataforma mais moderna com a mesma capacidade no futuro? E se nos encontrarmos, então onde?

O próximo passo é determinar como integrar. Os módulos estão embutidos no firmware, o firmware está localizado no chip SPI na placa e o PCH com Intel ME está localizado nas proximidades. E aqui surge a pergunta mais interessante - como chegar lá? Bom programador antigo com um "crocodilo" - isso é bom, é confiável. Mesmo se você não entender o que está acontecendo, sempre poderá observar os LEDs em chamas na placa, pois eles têm energia suficiente do programador. Funciona quase perfeitamente, com exceção de alguns modelos antigos da HP, onde o mikruha SOIC-16 com firmware é tão acessível que é mais fácil fabricar e soldar o adaptador nas pernas do que apertar o clipe.



Eu sei que há pessoas em Habré que contribuíram para a escrita do flashrom, graças a elas separadamente.

Mas, apesar da confiabilidade e confiabilidade da remoção de despejo pelo programador, esse método não é adequado se você precisar instalar algo no UEFI em várias máquinas ou se a plataforma de destino para instalação não estiver em sua mesa. Felizmente para nós, os fabricantes deixaram para trás utilitários de firmware nativos: FPT (ferramenta de programação Flash) do kit Intel (CS) ME System Tools e AFU (AMI Firmware Update) para Aptio da American Megatrends. Esses utilitários são iniciados no ambiente EFI e nos sistemas operacionais Windows, Linux e DOS. Os utilitários são um tanto intercambiáveis, ambos permitem que você considere a imagem, se não o todo, e certas regiões com certeza. E às vezes até deixam você escrever de volta.



Ele escreve e não escreve

É aqui que o primeiro obstáculo sério no caminho da integração aparece. Nem todas as placas-mãe permitem a leitura de todo o firmware, proibindo o acesso à região ME (ME é quase sagrado, a Intel não permitirá que seja lida de uma maneira boa, mas de uma maneira ruim nem sempre queremos). Menos ainda - coloque algo uniforme na região do BIOS, a menos que seja uma cápsula assinada. A probabilidade de sucesso varia muito, dependendo do fabricante e da atualização do chipset. Em alguns modelos de placas-mãe, é possível observar uma imagem engraçada: a que não foi registrada nas placas de fornecedores antigos voa em novos momentos.

Às vezes, o analisador IFR ajuda a combater a proteção contra gravação, que abre a cortina em configurações e variáveis ​​ocultas. E, às vezes, apenas um jumper hardcore ajuda, permitindo o acesso à gravação ou "desligando" o ME (se houver, é claro).

A natureza complexa dos sistemas


As placas Acer, Asus, AsRock e Gigabyte na maioria dos casos são escritas sem dificuldades desnecessárias. Intel, HP e hardware de servidor se destacam. A HP não apenas permite escrever em si de forma programática, como também jura em qualquer tentativa de modificar o firmware (emCodeRush existem artigos sobre como encontrar e desativar a verificação de integridade). A Intel registrou mais ou menos até o 87º chipset, depois ficou surda as solicitações para abrir os portões da região do BIOS.

Com a Intel, a primeira vez foi engraçada. Os módulos foram importados para o firmware usando o utilitário UEFITool, e encontramos um bug interessante: se inserirmos módulos ffs no final do volume DXE, depois de todas as formas livres, a imagem montada "bloqueou" a placa. A solução foi adicionar módulos após qualquer driver DXE nativo. Não chegamos a isso imediatamente e, a princípio, parecia que a Intel estava monitorando a integridade do firmware, como a HP. Mais tarde, ficou claro que não se poderia prescindir de um utilitário automático para importação de módulos, e o problema acabou em nada depois de escrevê-lo.

O hardware do servidor é mais simples e mais complexo ao mesmo tempo. Por um lado, sempre existem maneiras adicionais de atualizar e modificar BIOSs em servidores, por outro lado, o volume de personalização nesses mesmos BIOS é esmagador, pois eles não economizam nos servidores e instalam chips de memória flash bastante espaçosos, geralmente também fazendo backup deles.

Ao instalar em um servidor, é sempre bom poder atualizar remotamente o BIOS via IPMI. É verdade que, para isso, você precisa de uma licença, é claro, paga. Se não aparecer no momento certo, é bem possível entrar em uma situação engraçada semelhante à que tivemos ao introduzir módulos no BIOS do servidor Supermicro.

Após a introdução dos módulos, a carga congela fortemente devido ao bloqueio por um dos módulos de segurança (eles não levaram em conta a desobediência dos BIOSs do servidor, com quem isso não acontece!). Na ausência da capacidade de forçar o BIOS a ser revertido via IPMI, a mão procurou o programador, mas foi uma má sorte - o clipe SOIC-8 padrão não era suficiente para um chip SOIC-16! Bem, tudo bem, porque em teoria a placa do servidor tem a capacidade de fazer backup da mídia conectada, captando a imagem SUPER.ROM na raiz. Mas esse mecanismo não inicia, porque de acordo com o sistema tudo está OK, tudo funciona, portanto, a reversão do BIOS não é necessária! O que fazer ?! A história acabou circulando pela cidade em busca do clipe certo, uma soldagem de emergência de fios, manchada pelos chineses em uma ordem incompreensível para nós e, finalmente - um piscar de olhos.

A Lenovo saiu ainda mais interessante. Nos comutadores recebidos do fornecedor, sob a capa do gabinete, foi encontrada uma placa de controle com dois "mikruhs" para firmware, com um SSD para sistemas operacionais e com uma bateria fixa. O BIOS acabou por ser um osso duro de roer, eu não queria comer uma imagem modificada de forma alguma, sucumbindo apenas ao programador. Em uma das tentativas de escrever algo, eles inseriram uma unidade flash com o console ubuntu no switch (o terminal não exibiu gráficos) e inicializaram com bastante segurança. Depois de fazer o que era necessário, eles desligaram o sistema usando o comando halt -p da memória antiga. O interruptor, por sua natureza não adaptado a nenhum desligamento, exceto pela falta de energia, não estava pronto para isso e não queria mais começar. O link no rosto queimou uma vez, os ventiladores farfalharam silenciosamente, e todos os portos não deram nada. Re-piscar não ajudou,a bateria parecia uma luva - tínhamos medo de quebrar o suporte. Como resultado, uma fina placa dielétrica se arrastou sob a força da perseverança e inspiração verbal sob os contatos, a memória volátil foi apagada e a chave voltou à vida.

O estudo de lixões retirados de dois chips mostrou muitas coisas interessantes. Em particular, um grande número de entradas "Inválidas" na NVRAM do firmware principal e várias similares no backup. Bem, e não um hash de dados encontrado anteriormente no volume com drivers DXE. Só se podia adivinhar a causa exata do problema de iniciar a troca.

Em geral, a parte do software raramente é privada de nuances inesperadas. Muitas placas-mãe que chegaram antes do 87º chipset (de diferentes fabricantes) possuem um recurso desagradável para produzir um fluxo interminável de erros ao inserir o comando "dh -v" no console do shell. Com a entrada manual, isso não é crítico, mas ao coletar dados em um arquivo, ele termina em um travamento infeliz. Nos dois casos, você precisa reiniciar a máquina. Fico feliz que, ao mesmo tempo, o arquivo de dados não inche a tamanhos imensos.



O BIOS Kraftway com placa ASRock H81M-DGS provou ser muito instável. Portanto, ele responde ao Ctrl Alt Del Del pendurado, no qual somente o Reset pode produzi-lo. Ocorreu um problema ao ignorar o script de inicialização <startup.nsh> no Shell'e - uma fração de segundo para escolher em vez de cinco padrão. Talvez esses problemas sejam causados ​​pela modificação dos módulos proprietários do KSS, talvez o assunto seja incorretamente "desaparafusado" ME.

Na placa Asus H97-PLUS, o firmware possui o seguinte recurso - o BootOrder transborda com o tempo. Provavelmente, o motivo está nos erros no código. Embora, talvez, o fabricante desejasse manter todos os dispositivos de inicialização já conectados na placa, mas não calculou que poderia haver mais de uma dúzia em um dia. Portanto, quando o BootOrder estourar, o sistema trava durante o processo de inicialização. Para limpá-lo, você deve desligar todos os dispositivos de inicialização e ligar o sistema. O firmware se limpa e o sistema inicializa diretamente no shell de configuração do BIOS. O desempenho permanece até o próximo estouro.

Resumindo a experiência de trabalhar com conselhos de vários fornecedores, você conclui que é quase impossível descobrir quais surpresas no nível EFI você irá lidar no próximo quadro, mesmo que ele já tenha um modelo conhecido. Esse é um tipo de loteria, porque às vezes podem surgir dificuldades no estágio de coleta de informações sobre o sistema. Talvez isso tenha uma parcela de idealismo inesgotável de pesquisa e fé no fabricante, porque de que outra forma algumas das placas-mãe mais recentes com ME v11 e v12 podem ser interrompidas ao executar o FPT ou MEInfo de versões mais antigas?

Problemas de trabalho com protocolos de hardware




Alguns problemas aparecem quando começamos a trabalhar com dispositivos USB - unidades e tokens. Isso acontece muitas vezes porque o código do BIOS para trabalhar com periféricos é um perigoso coquetel de drivers e aplicativos do Independent Hardware Vendor (IHV) para um periférico específico, código do fabricante do chipset (no nosso caso, da Intel), código do fabricante e código do BIOS do fabricante da placa-mãe. Surgiram as

seguintes situações "interessantes":

Token "não detectado". Ao mesmo tempo, um LED acende nele. Provavelmente, o controlador host não realiza o procedimento de redefinição inicial do dispositivo USB, ou seja, a energia é fornecida, mas a redefinição através da alteração das linhas D + e D- não funciona corretamente e, sem ela, outras manipulações com o token não fazem sentido.

O computador congela antes de carregar o shell (novamente, com um token conectado). Nesse caso, sem um token, o PC inicia normalmente. Ao vivo, fica assim: o computador parece travar logo após o início, enquanto o token permanece no conector. Você remove - o carregamento continua repentinamente. Conecte - desligando novamente. O problema óbvio está na UEFI, e só se pode especular sobre os motivos.

A situação em que não é possível abrir a interface USB_IO. Talvez ele esteja conectado apenas à interface para trabalhar com cartões inteligentes - USB CCID. Alguns drivers AMI já abriram o USB_IO com o parâmetro EFI_OPEN_PROTOCOL_BY_DRIVER. O driver possui um protocolo com um GUID:

#define EFI_AMI_USB_CCID_PROTOCOL_GUID	 { 0x5FDEE00D, 0xDA40, 0x405A, { 0xB9, 0x2E, 0xCF, 0x4A, 0x80, 0xEA, 0x8F, 0x76} }
 // Workaround.      EFI_OPEN_PROTOCOL_BY_DRIVER,  ,     EFI_OPEN_PROTOCOL_GET_PROTOCOL.
 //
 // Open USB I/O Protocol
 //
 Status = gBS->OpenProtocol (
 ControllerHandle,
 &gEfiUsbIoProtocolGuid,
 (VOID **) &UsbIo,
 This->DriverBindingHandle,
 ControllerHandle,
 EFI_OPEN_PROTOCOL_BY_DRIVER
 );

 if (EFI_ACCESS_DENIED == Status)
 {		// AMI BIOS workaround (BindingStop will not be invoked)
	 Status = gBS->OpenProtocol(
		 ControllerHandle,
		 &gEfiUsbIoProtocolGuid,
		 (VOID **)&UsbIo,
		 This->DriverBindingHandle,
		 ControllerHandle,
		 EFI_OPEN_PROTOCOL_GET_PROTOCOL
	 );
 }

No entanto, BindingStop () não será chamado, ou seja, o evento de extração do dispositivo não é monitorado e o driver tentará usar um identificador inválido. Isso foi observado no PC HP Compaq Elite 8300 SFF e em alguns outros. Esse é um tipo de proteção do fornecedor contra drivers indesejados ou um bug de desenvolvimento regular. Talvez a AMI esteja constantemente fazendo algo na direção do USB CCID, mas o driver interferente não pode ser descarregado, pois está localizado no mesmo módulo AMI UHCI junto com o USB HID, USB MassStorage. Com UninstallInterface (), as coisas são semelhantes.

Ou outro recurso interessante. Em um dos UEFI BIOS, onde o token não foi detectado, USB_IO permitiu a leitura dos descritores do dispositivo, mas EFI_INVALID_PARAMETER retornou ao próximo UsbBulkTransfer (). Além disso, isso aconteceu apenas com alguns tipos de tokens, com absolutamente os mesmos parâmetros, outros funcionaram perfeitamente.

Em geral, o protocolo UsbBulkTransfer () é interessante de implementar no protocolo EFI_USB_IO_PROTOCOL. Destina-se à entrega garantida do pacote por um tempo ilimitado ou pelo tempo especificado no parâmetro Timeout. Mas um experimento foi realizado com um dispositivo MassStorage: ao copiar um arquivo grande para uma unidade flash USB, ele foi removido. O PC está travado. Ao conectar a unidade flash USB, o PC cedeu e continuou a gravar o arquivo como se nada tivesse acontecido. A mesma situação ocorreu com os tokens, mas com suas próprias especificidades. Esse é um problema de arquitetura, na EFI não há interrupções, exceto um temporizador, e os dispositivos operam de acordo com uma pesquisa. Ou seja, o sistema travou em algum lugar da pesquisa USB, mas não atingiu o tempo limite; quando o dispositivo reapareceu, ele simplesmente continuou e concluiu a operação.

Virtualização


Também devemos dizer sobre ambientes virtuais. Atualmente, existem duas plataformas principais no mercado que oferecem suporte à emulação do ambiente EFI: VMware e VirtualBox. Ambos têm suas vantagens e desvantagens ao interagir com eles e com sistemas "reais". O ambiente VMware fornece trabalho adequadamente com variáveis ​​da NVRAM, mas tropeça ao exibir mensagens visualmente durante a inicialização dos módulos DXE: na melhor das hipóteses, será dada preferência às mensagens nativas sobre como encontrar mídia inicializável, deixando para trás o que precisamos. Pelo contrário, o VirtualBox processa perfeitamente tudo o que é necessário, mas não deseja se lembrar de variáveis ​​longas.

Outra pequena pedra no jardim do VMware - o driver FAT32 embutido suporta a criação e edição de arquivos apenas na notação 8.3. Não está claro por que isso foi feito, mas essa é uma limitação que claramente requer atenção. É provável que uma implementação semelhante do driver possa ser observada em plataformas reais, mas até agora não encontramos nenhuma.

Por outro lado, em máquinas virtuais, não há danças com utilitários de firmware, programadores, jumpers, chips desconfortáveis. Um arquivo ROM separado, UEFITool e uma linha no arquivo de configuração. Quase um idílio.

No final



Uma fatia da solicitação do CHIPSEC. Onde eles ensinam esses sacramentos?

Como já mencionado, o desenvolvimento e implementação no shell UEFI é um processo fascinante e criativo. Você sempre pode encontrar algo novo, mesmo em um campo famoso. Por um lado, é encorajador que o padrão esteja se desenvolvendo; por outro, é triste que implementações concretas dele pelos produtores sejam muito "criativas".

Os principais problemas foram e permanecem:

  1. Partida de fornecedores da especificação UEFI ao desenvolver firmware.
  2. Erros no código durante a implementação.
  3. NDV no código, pop-up durante a integração.

E por último, mas não menos importante, a ausência de muitas coisas na documentação oficial (leitura, abertura), como, por exemplo, descrições do protocolo para comunicação comigo através de dispositivos PCI como MEI, HECI. Você pode encontrar uma descrição dos registradores, mas não dos comandos. Encontre um GUID, mas não seu objetivo. Que mais uma vez retorna o trabalho a uma longa análise, coletando dados e estatísticas em plataformas e usando o desmontador.

Note-se que a situação está lenta mas seguramente corrigindo, e eu quero acreditar que não está longe o momento em que o desenvolvimento do padrão se tornará um processo bastante previsível e muito agradável.

Vladimir Onipchuk,
chefe do grupo de produtos de proteção de hardware e software da
Gazinformservice LLC

All Articles