Problemas y características de la implementación de UEFI en varias plataformas

Han pasado unos diecinueve años desde el lanzamiento de la primera especificación EFI en el año 2000. La interfaz tardó diez años en ingresar al mercado de usuarios y obtener un punto de apoyo. Por el momento, rara vez se puede ver una computadora moderna sin UEFI en el firmware de la placa base. El estándar de interfaz ha aumentado la "carne" y varios miles de páginas en la documentación oficial. Para el usuario promedio, nada ha cambiado, excepto las colisiones ocasionales con el arranque seguro habilitado. Pero si el plano del trabajo cambia al desarrollo, todo se vuelve más interesante.



El concepto mismo de la arquitectura modular de UEFI implica que estos módulos no solo se pueden usar en la configuración estándar, sino que también descargan algo propio. El controlador del sistema de archivos (no limitado a la FAT nativa tímida), controladores periféricos, aplicaciones, cargadores de arranque: puede cargar todo a mano, sería bueno cargar un poco de Shell. Puede dar un paso "más profundo" y mirar el contenido del firmware, evitando bailar con SecureBoot y la necesidad de escribir una capa de scripts (hay suficientes artículos en las páginas del hub).

Sobre esta base, la idea nació de la creación de módulos funcionales que realicen varias funciones de seguridad antes de cargar el sistema operativo, lo que puede unir aún más y convertirse en una especie de entorno de arranque confiable integrado que afecta tanto a los servicios de la interfaz de arranque como a la de tiempo de ejecución para que entre los módulos en el firmware y los módulos en el disco nada podría ser "empujado" sin una intervención de bajo nivel, y después de ellos, solo con el permiso del administrador de seguridad.

La implementación de esta idea nos presentó una gran cantidad de matices y sutilezas de UEFI, comenzando con muchas características, errores no documentados o mal documentados, y terminando con el comportamiento indefinido tan querido por todos los desarrolladores. Comencemos en orden.

Dependencia de plataforma




Lo primero que debe saber al integrarse en la plataforma es si podemos trabajar con ella. La versión de la especificación UEFI es importante, y en la mayoría de los dispositivos se presenta en el rango entre 2.1 y 2.7. El más nuevo aún no ha llegado al puesto de investigación. Se encuentra el anterior, y su rendimiento puede verse limitado debido a la falta de los protocolos necesarios o los controladores grabados de forma incorrecta para su implementación. Por ejemplo, UnicodeCollation a menudo no es suficiente, al acceder a smbios hay errores no documentados, las funciones de cambio de idioma a través de SetVariable () no funcionan. Cualquier cosa puede suceder, dependiendo del proveedor y la frescura, porque a veces tienes que poner tus protocolos incluso en tableros relativamente nuevos.

Incluso en nuestra práctica, tuve la suerte de encontrar dos mini computadoras con Intel Bay Trail D y firmware de 32 bits a bordo. El caso es raro, pero en algún momento hizo necesario recompilar urgentemente los módulos. En realidad, como la pregunta: ¿nos encontraremos con una plataforma más moderna de la misma capacidad en el futuro? Y si nos encontramos, entonces ¿dónde?

El siguiente paso es determinar cómo integrar. Los módulos están integrados en el firmware, el firmware se encuentra en el chip SPI de la placa y PCH con Intel ME se encuentra cerca. Y aquí surge la pregunta más interesante: ¿cómo llegar? Buen viejo programador con un "cocodrilo": esto es bueno, es confiable. Incluso si no alcanza el final, siempre puede mirar los LED encendidos en el tablero, tienen suficiente potencia del programador. Funciona casi a la perfección, con la excepción de algunos modelos HP más antiguos, donde el mikruha SOIC-16 con firmware es tan accesible que es más fácil idear y soldar el adaptador a sus piernas que apretar el clip.



Sé que hay personas en Habré que han contribuido a la escritura de flashrom, gracias a ellos por separado.

Pero, a pesar de la fiabilidad y la fiabilidad de la eliminación de volcados por parte del programador, este método no es adecuado si necesita instalar algo en UEFI en varias máquinas, o si la plataforma de destino para la instalación no está en su escritorio. Afortunadamente para nosotros, los fabricantes dejaron atrás las utilidades de firmware nativas: FPT (herramienta de programación Flash) del kit de herramientas del sistema Intel (CS) ME y AFU (Actualización de firmware AMI) para Aptio de American Megatrends. Estas utilidades se lanzan tanto desde el entorno EFI como desde los sistemas operativos Windows, Linux y DOS. Las utilidades son algo intercambiables, ambas le permiten considerar la imagen, si no la totalidad, entonces ciertas regiones con seguridad. Y a veces incluso te dejan escribir de nuevo.



El escribe y no escribe

Aquí es donde aparece el primer obstáculo serio en el camino de la integración. No todas las placas base le permiten leer todo el firmware, lo que prohíbe el acceso a la región ME (ME es casi sagrado, Intel no permitirá que se lea de una buena manera, pero de una mala manera que no siempre queremos). Aún menos: vierta algo incluso en la región del BIOS, a menos que sea una cápsula firmada. La probabilidad de éxito varía mucho según el fabricante y la frescura del chipset. En algunos modelos de placas base, se puede observar una imagen divertida: lo que no se grabó en las placas de los vendedores antiguos, vuela en los nuevos tiempos.

A veces, el analizador IFR ayuda a combatir la protección contra escritura, que abre el telón sobre configuraciones y variables ocultas. Y, a veces, solo un puente hardcore ayuda, lo que permite el acceso a la grabación o "apagar" ME (si se proporciona uno, por supuesto).

La naturaleza compleja de los sistemas.


Las placas Acer, Asus, AsRock y Gigabyte en la mayoría de los casos están escritas sin dificultades innecesarias. Intel, HP y el hardware del servidor se distinguen. HP no solo no permite escribir en sí mismo mediante programación, sino que también jura ante cualquier intento de modificar el firmware (enCodeRush hay artículos sobre cómo encontrar y deshabilitar la comprobación de integridad). Intel registró más o menos hasta el 87 ° chipset, luego se volvió sordo a las solicitudes para abrir las puertas de la región del BIOS.

Con Intel, la primera vez fue divertida. Los módulos se importaron al firmware utilizando la utilidad UEFITool, y encontramos un error interesante: si inserta módulos ffs al final del volumen DXE, después de todas las formas libres, la imagen ensamblada "bloqueó" la placa. La solución fue agregar módulos después de cualquier controlador DXE nativo. No llegamos a esto de inmediato, y al principio parecía que Intel estaba monitoreando la integridad del firmware, como HP. Más tarde se hizo evidente que no se podía prescindir de una utilidad automática para importar módulos, y el problema quedó en nada después de escribirlo.

El hardware del lado del servidor es más simple y más complejo al mismo tiempo. Por un lado, siempre hay formas adicionales de actualizar y modificar los BIOS en los servidores, por otro lado, el volumen de personalización en estos mismos BIOS es abrumador, ya que no escatiman en los servidores e instalan chips de memoria flash bastante potentes, a menudo también los respaldan.

Al instalar en un servidor, siempre es bueno poder actualizar remotamente el BIOS a través de IPMI. Es cierto que para esto, en el buen sentido, necesita una licencia, por supuesto, pagada. Si no aparece en el momento adecuado, es muy posible entrar en una situación divertida similar a la que tuvimos al introducir módulos en el BIOS del servidor Supermicro.

Después de la introducción de los módulos, la carga se congela fuertemente debido al bloqueo por parte de uno de los módulos de seguridad (¡no tuvieron en cuenta la cautela de los BIOS del servidor, con los que no sucede!). En ausencia de la capacidad de obligar al BIOS a retroceder a través de IPMI, la mano misma alcanzó al programador, pero fue una mala suerte: ¡el clip SOIC-8 estándar no era suficiente para un chip SOIC-16! Bueno, está bien, porque en teoría la placa del servidor tiene la capacidad de hacer una copia de seguridad de los medios conectados, recogiendo la imagen SUPER.ROM en la raíz. Pero este mecanismo no se inicia porque, según el sistema, todo está bien, todo funciona, por lo tanto, ¡no se necesita la reversión del BIOS! ¿Qué hacer?! .. La historia terminó corriendo por la ciudad en busca del clip correcto, una re-soldadura de cables de emergencia, manchada por los chinos en un orden incomprensible para nosotros y, finalmente, un parpadeo.

Lenovo salió aún más interesante. En los interruptores recibidos del proveedor, bajo la tapa de la caja, se encontró una placa de control con dos "mikruhs" para firmware, con un SSD para sistemas operativos y con una batería fija. El BIOS resultó ser un hueso duro, no quería comer una imagen modificada de ninguna manera, sucumbiendo solo al programador. En uno de los intentos de escribir algo, insertaron una unidad flash con la consola ubuntu en el conmutador (el terminal no daba gráficos) y arrancaron con bastante seguridad. Habiendo hecho lo que se requería, apagaron el sistema usando el comando halt -p de la memoria anterior. El interruptor, por su naturaleza no adaptado para ningún apagado, excepto por la falta de energía, no estaba listo para esto y no quería comenzar más. El enlace en la cara se quemó una vez, los ventiladores susurraron en silencio y todos los puertos no dieron nada. Volver a flashear no ayudó,la batería se sentó como un guante; teníamos miedo de romper el soporte. Como resultado, una delgada placa dieléctrica se arrastró bajo la fuerza de la perseverancia y la inspiración verbal debajo de los contactos, la memoria volátil se borró, el cambio se hizo realidad.

El estudio de los vertederos tomados de dos chips mostró muchas cosas interesantes. En particular, una gran cantidad de entradas "inválidas" en la NVRAM del firmware principal y varias similares en la copia de seguridad. Bueno, y no un hash de datos encontrado anteriormente en el volumen con controladores DXE. Uno solo podría adivinar la causa exacta del problema de iniciar el cambio.

En general, la parte del software rara vez se ve privada de sus matices inesperados. Muchas placas base que nos llegaron antes del 87º chipset (de diferentes fabricantes) tienen una característica desagradable para producir un flujo interminable de errores al ingresar el comando "dh -v" en la consola del shell. Con la entrada manual, esto no es crítico, pero al recopilar datos en un archivo, termina en un desafortunado bloqueo. En ambos casos, debe reiniciar la máquina. Me alegro de que, al mismo tiempo, el archivo de datos no aumente a un tamaño inmenso.



El BIOS Kraftway con placa ASRock H81M-DGS demostró ser muy descarriado. Entonces, responde a Ctrl Alt Del Del colgando, desde el cual solo Reset puede generarlo. Hubo problemas al omitir el script de inicio <startup.nsh> en Shell'e, una fracción de segundo para elegir en lugar de los cinco predeterminados. Tal vez estos problemas sean causados ​​por la modificación de los módulos patentados de KSS, tal vez el asunto sea inexactamente "desenroscado" ME.

En la placa Asus H97-PLUS, el firmware tiene la siguiente característica: BootOrder se desborda con el tiempo. Lo más probable es que la razón radique en los errores en el código. Aunque, tal vez, el fabricante quería mantener todos los dispositivos de arranque que alguna vez estuvieron conectados en la placa, pero no calculó que podría haber más de una docena en un día. Entonces, cuando BootOrder se desborda, el sistema se bloquea durante el proceso de arranque. Para limpiarlo, debe apagar todos los dispositivos de arranque y encender el sistema. El firmware se borra solo y el sistema se inicia directamente en el shell de configuración del BIOS. El rendimiento permanece hasta el próximo desbordamiento.

Resumiendo la experiencia de trabajar con juntas de varios proveedores, llega a la conclusión de que es casi imposible descubrir qué sorpresas a nivel EFI enfrentará en la próxima junta, incluso si ya tiene un modelo bien conocido. Este es un tipo de lotería, porque a veces pueden surgir dificultades en la etapa de recopilación de información sobre el sistema. Quizás esto tenga una cuota de idealismo de investigación inquebrantable y fe en el fabricante, porque ¿de qué otra manera podrían colgar algunas de las placas base más recientes con ME v11 y v12 cuando se ejecutan FPT o MEInfo de versiones anteriores en ellas?

Problemas de trabajo con protocolos de hardware.




Aparecen algunos problemas cuando comenzamos a trabajar con dispositivos USB: unidades y tokens. Esto sucede a menudo porque el código del BIOS para trabajar con periféricos es un cóctel peligroso de controladores y aplicaciones del Proveedor de hardware independiente (IHV) para un periférico específico, código del fabricante del chipset (en nuestro caso, de Intel), código del fabricante del BIOS y código del fabricante de la placa base. Surgieron las

siguientes situaciones "interesantes":

Token "no detectado". Al mismo tiempo, se enciende un LED. Lo más probable es que el controlador host no pase por el procedimiento de reinicio inicial del dispositivo USB, es decir, la alimentación se suministre, pero el reinicio al cambiar las líneas D + y D- no funciona correctamente, y sin él, cualquier otra manipulación con el token no tiene sentido.

La computadora se congela antes de cargar el shell (nuevamente, con un token conectado). En este caso, sin un token, la PC se inicia normalmente. En vivo, se ve así: la computadora parece fallar justo después del inicio, mientras que el token sobresale en el conector. Lo sacas, la carga continúa de repente. Conectar - colgando de nuevo. El problema obvio está en UEFI, y uno solo puede especular sobre las razones.

La situación cuando no es posible abrir la interfaz USB_IO. Quizás esté conectado solo con la interfaz para trabajar con tarjetas inteligentes: USB CCID. Algunos controladores AMI ya han abierto USB_IO con el parámetro EFI_OPEN_PROTOCOL_BY_DRIVER. El controlador tiene un protocolo con un 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
	 );
 }

Sin embargo, BindingStop () no se llamará, es decir el evento de extracción del dispositivo no se supervisa y el controlador intentará utilizar un controlador no válido. Esto se observó con la PC HP Compaq Elite 8300 SFF y algunas otras. Este es un tipo de protección del proveedor contra controladores no deseados o un error de desarrollo regular. Tal vez AMI esté constantemente haciendo algo en la dirección de USB CCID, pero el controlador que interfiere no se puede descargar, ya que está ubicado en el mismo módulo AMI UHCI junto con USB HID, USB MassStorage. Con UninstallInterface (), las cosas son similares.

U otra característica interesante. En uno de los UEFI BIOS, donde no se detectó el token, USB_IO permitió leer los descriptores del dispositivo, pero EFI_INVALID_PARAMETER regresó al siguiente UsbBulkTransfer (). Además, esto sucedió solo con algunos tipos de tokens, con absolutamente los mismos parámetros, otros funcionaron perfectamente.

En general, el protocolo UsbBulkTransfer () se implementa de manera interesante en el protocolo EFI_USB_IO_PROTOCOL. Está destinado a la entrega garantizada de paquetes por tiempo ilimitado, o por el tiempo especificado en el parámetro Timeout. Pero se realizó un experimento con un dispositivo MassStorage: al copiar un archivo grande en una unidad flash USB, se eliminó. La PC se cuelga apretadamente. Al conectar la unidad flash USB, la PC se hundió y continuó escribiendo el archivo como si nada hubiera pasado. La misma situación fue con los tokens, pero con sus propios detalles. Este es un problema arquitectónico, en EFI no hay interrupciones, excepto un temporizador, y los dispositivos funcionan de acuerdo con una encuesta. Es decir, el sistema se bloqueó en algún lugar de la encuesta USB, pero no alcanzó el tiempo de espera, cuando reapareció el dispositivo, simplemente continuó y completó la operación.

Virtualización


También deberíamos decir sobre entornos virtuales. Actualmente hay dos plataformas principales en el mercado que admiten la emulación del entorno EFI: VMware y VirtualBox. Ambos tienen sus ventajas y desventajas cuando interactúan con ellos como con los sistemas "reales". El entorno VMware proporciona adecuadamente el trabajo con variables NVRAM, pero se tambalea cuando se muestran mensajes visualmente durante la inicialización de los módulos DXE: en el mejor de los casos, se dará preferencia a los mensajes nativos sobre la búsqueda de medios de arranque, dejando atrás lo que necesitamos. VirtualBox, por el contrario, representa perfectamente todo lo requerido, pero no quiere recordar variables largas.

Otra pequeña piedra en el jardín VMware: el controlador FAT32 integrado en él admite la creación y edición de archivos solo en notación 8.3. No está claro por qué se hizo esto, pero esta es una limitación que claramente requiere atención. Es probable que se pueda observar una implementación similar del controlador en plataformas reales, pero hasta ahora no hemos encontrado esas.

Por otro lado, en las máquinas virtuales no hay bailes con utilidades de firmware, programadores, puentes, chips incómodos. Un archivo ROM separado, UEFITool y una línea en el archivo de configuración. Casi un idilio.

En el final



Una porción de la solicitud de CHIPSEC. ¿Dónde enseñan tales sacramentos?

Como ya se mencionó, el desarrollo e implementación en el shell UEFI es un proceso fascinante y creativo. Siempre puedes encontrar algo nuevo incluso en un campo famoso. Por un lado, es alentador que el estándar se esté desarrollando, por otro lado, es triste que las implementaciones concretas del mismo sean demasiado "creativas".

Los principales problemas fueron y siguen siendo:

  1. Salida de proveedores de la especificación UEFI al desarrollar firmware.
  2. Errores en el código durante la implementación.
  3. NDV en código, emergente durante la integración.

Y por último, pero no menos importante, la ausencia de muchas cosas en la documentación oficial (leída, abierta), como, por ejemplo, descripciones del protocolo para comunicarse con ME a través de dispositivos PCI como MEI, HECI. Puede encontrar una descripción de los registros, pero no los comandos. Encuentre un GUID, pero no su propósito. Lo que una vez más devuelve el trabajo a un largo análisis, recolectando datos y estadísticas en plataformas y usando el desensamblador.

Cabe señalar que la situación se está corrigiendo lenta pero seguramente, y quiero creer que el momento no está muy lejos cuando el desarrollo del estándar se convertirá en un proceso bastante predecible y muy agradable.

Vladimir Onipchuk,
jefe del grupo de productos de protección de hardware y software de
Gazinformservice LLC

All Articles