Windows 8: análisis a fondo de la UEFI

¿Qué es UEFI?

Mientras escribo esto, se está llevando a cabo el lanzamiento comercial de Windows 8. Para acompañar este hito, es que decidí escribir este artículo versante con las tecnologías de aceleración de arranque y apagado que se encuentra en el nuevo sistema operativo. Este documento es un survey y tiene como fuente páginas web de Intel, Microsoft y otros blogs de tecnología, y las imágenes han sido en su mayoría generadas ad-hoc para esta página, a excepción de las figuras 2 y 5.

Este documento intentará explicar cómo Windows 8 toma ventaja de UEFI para alcanzar tiempos de arranque muy cortos. UEFI es el acrónimo de Unified Extensible Firmware Interface. Es una especificación creada por Intel, que reemplazaría a la vieja BIOS (Basic Input-Output System). Tanto la BIOS como la nueva UEFI tienen como objetivo hacer que el sistema operativo “se entienda” con el hardware de base, manejado habitualmente por un firmware. Esta nueva forma de arranque del equipo tiene por un lado componentes nuevos en el arranque de la plataforma (hardware y su firmware), que luego monta el sistema operativo. Windows 8 da soporte a UEFI para alcanzar tiempos de arranque muy cortos.

El viejo proceso de la BIOS.

A grandes rasgos, el proceso de arranque de la BIOS es el siguiente:

Fig. 1: Secuencia de arranque de una BIOS convencional

 

Este esquema de arranque tiene más de 30 años, y a lo largo de la evolución de la PC, se han tenido que “emparchar” ciertas funcionalidades. Por ejemplo, el video debe ser lo primero que esté disponible al iniciar la máquina, pero desde la BIOS se puede levantar un controlador de video muy básico. Esto limita severamente la posibilidad de ofrecer una interfaz amigable. Tampoco se tiene compatibilidad con drivers de 32 o de 64 en muchos casos, los cuales deben ser levantados por el sistema operativo en el arranque. Pero el principal problema es que su código de manejadores es de 16 bits, por norma. Si bien con los años le fueron agregadas características más avanzadas como ACPI y SMBIOS, gestión de energía y administración de la BIOS respectivamente, en realidad, desde hace algún tiempo la BIOS comenzó a mostrarse obsoleta y que los años le pesaban, sobre todo por la adopción de los nuevos sistemas operativos de 64 bits.

Características de la nueva UEFI

La UEFI viene a subsanar varios de esos inconvenientes. Sin embargo, no tiende a reemplazar la BIOS y “borrarla del mapa”, ya que lo primero que asegura es un modo de emulación de BIOS por si fuese necesario. Pero esencialmente, agrega funcionalidad adecuada a la realidad tecnológica actual. Contempla dos grandes grupos de servicios o procesos: (a) proceso de arranque, y (b) servicios de runtime, proveyendo una interfaz distinta y única para cada uno. Durante el arranque, gestionará el inicio de los dispositivos del equipo, y cargará el sistema operativo eligiendo una de varias formas posibles. Durante el proceso de arranque, a su vez, se distinguen dos grandes grupos de operaciones: (1) el inicio de la plataforma o PI, y luego (2) el arranque del sistema operativo, en modo transitorio o en modo estable o principal. Los servicios de runtime pasan por proveer al sistema operativo de un conjunto de interfaces por si éste necesita “dialogar” con el firmware subyacente del equipo.

Proceso de arranque

Aqui se especifica cómo el hardware invocará el inicio del software, o de un sistema operativo, para que comience a cargarse. Sin embargo, el arranque ya no depende de un cargador de sistema operativo como hasta ahora. UEFI puede cargar múltiples sistemas operativos sin la necesidad de un cargador como NTLDR (Windows) o LILO (Linux). UEFI selecciona la partición con el sistema operativo y lo carga desde allí. Para que esto suceda, tanto el hardware como el software deberían ser UEFI-compatibles.

En el proceso de arranque, UEFI tiene menús que son mucho más amigables que los viejos menús de la BIOS, y permite que ciertas tareas de configuración del equipo se puedan hacer sin cargar el sistema operativo principal. Esto no tiene nada que ver con las actuales capacidades de ciertas máquinas de cargar un browser sin tener que arrancar el SO principal, ya que estos equipos lo logran cargando un mini-sistema operativo desde la BIOS que permite hacer estas tareas. Por el contrario, con la nueva especificación, no se carga un mini-sistema operativo sino que se selecciona qué drivers cargar para lograr que se ejecute una aplicación determinada. De esta forma, con la carga selectiva, se podrán iniciar navegadores de internet, o clientes de correo, que arrancarán mucho más rápidamente que si se tuviese que lanzar todo un OS completo. Estas aplicaciones se denominan “aplicaciones con sistema operativo ausente”. Por el contrario, una vez que arranca el sistema operativo y se usan las aplicaciones en forma habitual, estas aplicaciones se denominan “aplicaciones con sistema operativo presente”.

Para comprender mejor esto, debemos ver la siguiente imagen, donde se muestran los bloques constitutivos de una PC genérica o universal. En la parte de abajo de la figura, en la capa inferior, se acomoda el hardware. Por sobre el hardware, alguna porción de éste se puede acceder desde código fijo llamado firmware, y otra porción se puede acceder directamente del sistema operativo. Aquí termina lo que se denominaría “plataforma”, delimitada en la figura 2 por la línea punteada. Luego, por sobre esta capa, va el sistema operativo, y por sobre él, las aplicaciones que solemos utilizar diariamente:

Figura 2: Bloques constitutivos de una PC genérica

Evolución de UEFI en el tiempo

Veamos sucintamente el camino recorrido.

En principio, hacia 2010 podemos reconocer la existencia de dos pasos en el arranque.

1. El primer paso se denomina PI (platform initialization), que incluye el arranque de la plataforma subyacente: lo primero que se ejecutaba era el protocolo de seguridad de arranque, si esto daba positivo se procedía en secuencia a iniciar el procesador, luego el chipset, luego la placa madre. Una vez que esto estaba funcionando, se procedía a cargar el sistema operativo. En este punto se proponían dos caminos: la carga de un sistema operativo de respuesta transitoria, para alojar aplicaciones como navegadores de internet y clientes de correo, y la carga del sistema operativo de elección, que resultaba de elegir previamente qué dispositivo iba a ejecutar el arranque (disco, tarjeta de memoria, etc.).

2. Una vez terminado el arranque, y estando ya levantado el sistema operativo, es posible que éste desee interactuar con el firmware de forma directa. Esto lo debería hacer exclusivamente por interfaces UEFI, siempre que sea posible. En este apartado, recordemos que Windows históricamente optó por no dialogar con la BIOS directamente, sino utilizar el concepto de drivers de alta velocidad en vez de acceder al firmware subyacente, en todas las versiones de Windows modernas.

Para entrar a tratar el tema de fondo, digamos que podemos describir, prima facie, cuatro tiempos principales en el ciclo de uso de un equipo PC:

  1. Encendido
  2. Inicialización de la Plataforma
  3. Arranque del sistema operativo
  4. Apagado

El siguiente diagrama muestra dónde encajaba cada grupo en 2010. Nótese la decisión que toma el gestor de arranque del OS si desea cargar sólo el soporte para una aplicación con OS ausente (un browser, un lector de noticias) o bien el sistema operativo completo (para correr una aplicación con OS presente):


Figura 3: Esquema de arranque con PI y UEFI en grupos separados (2010)

Los bloques constitutivos de UEFI en 2010 incluían a PI (inicialización de plataforma) como un gran grupo que se ejecutaba ANTES que el arranque del sistema operativo. Pero las limitaciones que tenía la inicialización de la plataforma PI, heredadas de la BIOS, pasaron a constituir un problema: la plataforma de desarrollo elegida fué una PC-AT, luego se estaba atado al procesador Intel x86 compatible, la existencia de elementos propios de la norma PC-AT como el Real Time Clock, el circuito 8254 (temporizador) y el 8259 (controlador de interrupciones), el límite máximo del registro maestro de arranque para un disco (2,2 Terabytes), la cantidad de particiones de disco limitada a un máximo de cuatro (4), etc. Estaba claro que UEFI quedaba atada a una plataforma cuyo presente era muy robusto, pero que en el futuro cercano deberá hacer frente a los millones de dispositivos móviles equipados con otras plataformas (ARM).


La idea fué entonces fusionar la inicialización de plataforma PI junto con UEFI, y para 2011 el modelo estaba terminado. Justo a tiempo para utilizarlo en Windows 8.

Figura 4: Esquema de arranque con PI + UEFI integrados en un solo conjunto (2011)

Esto mejoró significativamente las prestaciones en el arranque, por ejemplo en el soporte de multiprocesadores, modo de gestión del sistema, etc. mediante la técnica de representar los componentes lo más genericamente posible. Ahora veremos qué consideraciones se tuvieron para acelerar el tiempo de arranque.

¿De dónde proviene la demora en el tiempo de arranque?

La respuesta corta es: es el precio a pagar por la gran cantidad de fabricantes alrededor de la norma PC-AT.

Para comprender esto, debemos considerar que el punto principal de la nueva estructura PI es el llamado DXE, el entorno de ejecución de drivers. Permite que los drivers de un fabricante interactúen de una forma mucho más sencilla con los drivers de otro (modelo business to business). Por ejemplo, supongamos que tenemos tres grandes grupos de fabricantes:

Tipo de fabricante Empresas
Consumidor final de la cadena

Fabricante de placas madre

  • Apple
  • Dell
  • IBM
  • HP
  • Lenovo
  • etc.
Proveedor intermedio

Fabricantes de circuitos de infraestructura (BIOS)

  • AMI
  • Insyde
  • Phoenix
  • etc.
Proveedor de base

Fabricantes de chipsets y microprocesadores

  • AMD
  • Intel
  • ARM
  • etc.

Lo que se pretende conseguir con esto es que los productos de cada fabricante interactúe de la mejor forma posible con los de otro proveedor. Para que esto ocurra, el inicializador de plataforma debe tomarse un tiempo para “descubrir” las APIs, preparar los mensajes de entrada y salida con su adecuación entre emisor y receptor, descubrir y enviar el código correcto, etc. Todo esto lleva tiempo, que sería menor si existiese un sólo proveedor monopólico de todo esto, que controlase todo sin necesidad de ser compatible con nadie más que consigo mismo.

En realidad, se tomó una decisión de negocios: a mayor apertura e interacción para más fabricantes, tanto más lento será el proceso de arranque porque se tiene un enlace dinámico entre los componentes, cuya combinación puede ser arbitraria (procesador de AMD, chipset de AMD, BIOS DE Phoenix, placa madre de IBM). Si existiese un solo proveedor que tuviese acceso a toda la propiedad intelectual para construir una plataforma, entonces se podría implementar un enlace fijo o estático entre estos componentes, reduciendo significativamente los tiempos de arranque. Pero la realidad a futuro es justo la contraria.

Entonces UEFI deberá ser esencialmente dinámico en el momento del arranque para permitir esa mezcla de drivers de diversos fabricantes. Para ello, dispone de una lista de drivers que le permiten actuar selectivamente al momento del arranque a través de una etiqueta que especifica algo asó como: “si usted desea correr tal cosa, debe cargar en el arranque estos drivers“. Por ello, UEFI da soporte a DOS tipos de arranque, desde el punto de vista del sistema operativo: un arranque estándar o normal, y uno optimizado. El optimizado se basa en el concepto de que existe un target que uno desea ejecutar (es decir, un target binario), y entonces siempre será posible determinar cuál es el conjunto mínimo de drivers necesario para ejecutar ese target.

La optimización se ejecuta en la fase PEFI (Pre EFI initalization) y en la fase de ejecución de drivers DXE y selección de dispositivos de arranque BDS. En esas fases, si el arranque es normal, se cargan todos los drivers y no existe optimización. Si el arranque es optimizado, se carga el conjunto mínimo de drivers necesario para arrancar el target (lo que se desea correr).

Carga rápida = evitar drivers innecesarios con el boot-target

En definitiva, el secreto para lograr una carga rápida de sistema operativo consiste en evitar ejecutar drivers que no sean necesarios. Para ello se introdujo, como dijimos anteriormente, el concepto de boot-target, que no es otra cosa que una etiqueta conocida como “camino de dispositivos” (device path), que indica una secuencia de carga y locación de los drivers que se necesitan cargar. Por ejemplo

Acpi(PNP0A30,0)/Pci(1F|1)/Ata(Primary,Master)/HD(Part3,Sig00110011)/”EFIBoot”/”OSLoader.efi”

En un arranque normal se llamaría a todas las rutinas que intentarán conectar todos los drivers a todos los dispositivos en forma recursiva, dando una combinatoria muy grande.

En el arranque optimizado , se lee el boot target anterior, y se cargan y conectan sólo los dispositivos asociados a dicho boot target. Para el caso anterior, el proceso sería:

Secuencia Boot Target Acción en el arranque
Conectar puente raíz PCI
Conectar consolas
Ejecutar diagnósticos
Arranque (BOOT) Acpi(PNP0A30,0) Inicializa el puente raíz PCI
Pci(1F|1) Inicializa el dispositivo PCI
Ata(Primary,Master) Inicializa el dispositivo ATA
HD(Part3,Sig00110011) Inicializa el driver de particionado
“EFIBoot” Inicializa el driver del sistema de archivos
“OSLoader.efi” Carga el sistema operativo.
Sistema listo

Al evitar la combinatoria “todos los drivers contra todos los dispositivos” el tiempo de arranque es muy rápido y lineal, y no geométrico.

Aspectos clave tomados para acelerar la carga

Podemos enumerar entonces las características que aceleran el inicio del sistema operativo:

1. Utilizar el caché de la CPU. El sistema deberá intentar siempre copiar al caché de la CPU los segmentos de códigos almacenado en memoria Flash. El caché de la CPU es la memoria más rápida existente en todo sistema, y la Flash es la más lenta. Una vez transferido el contenido al caché de la CPU, el proceso podrá acceder a este código a la máxima velocidad posible. Este punto va de la mano con el siguiente:

2. Utilizar el concepto de acceso eficiente a la memoria Flash. En las BIOS que tienen la especificación PI se tiene catalogada la lista de drivers de la propia BIOS, en grupos llamados firmware volumes (FV). El problema es que una BIOS puede tener varios bancos de FV. Si éstas no están ordenadas eficientemente, el proceso de arranque deberá leer varias veces los datos desde la memoria Flash, que es sumamente lenta. La idea es organizar estos bancos de drivers en una forma inteligente, para minimizar el acceso a la memoria Flash.

3. Evitar la carga de drivers innecesarios. Al arrancar una PC, existen dos niveles de inicialización del hardware.

  • Primer nivel: inicializar todo lo necesario para cumplir con lo que el sistema operativo espera. Por ejemplo, ajustar el controlador SATA al modo deseado (AHCI, nativo, heredado).
  • Segundo nivel: consiste en inicializar en la fase pre-OS, y sólo “por las dudas” a dispositivos que en la fase pre-OS pueden no ser necesarios para ese momento. Por ejemplo, intentar montar sistemas de archivos de pendrives USB, aunque éstos no contengan ningun archivo necesario para que el sistema operativo arranque, es uno de los peores escenarios, ya que al montar un dispositivo USB, la cantidad de conexiones en la etapa de selección de dispositivo de arranque (BSD) es excesiva.

Entonces, para acelerar el arranque del sistema operativo, se pueden saltear drivers en el segundo nivel: si no se necesita arrancar desde USB, no se lo inicializa. El sistema operativo, para colmo, invariablemente lo vuelve a inicializar, con lo cual sobreescribe lo hecho en la fase de inicialización de hardware, con lo cual no se pierde nada al no inicializar un dispositivo que no se necesite en el arranque pre-OS.

4. Evitar reinicio innecesario de hardware. Algunos drivers suelen reiniciar el dispositivo, y espera que éste le devuelva una señal de “estoy listo”. Algunos periféricos son sumamente lentos en reiniciar, como por ejemplo, los teclados PS/2, que demoran 1 segundo en el reset, o para un disco de estado sólido SSD que suele demorar 0,8 segundos. Evitando estos dos reinicios innecesarios daría una ganancia de casi dos segundos en el tiempo de arranque.

5. Releer datos grabados. Si el hardware del equipo no se ha cambiado, se podrían leer los datos almacenados en memoria RAM no volátil que se grabaron en el último arranque exitoso del equipo. Esto evitaría tener que leer los dispositivos PCI uno por uno desde el hardware directamente, y los datos necesarios se recuperarían de una memoria que es muchísimo más rápida.

6. Intentar paralelismo cuando sea posible. El firmware no permite ejecución en paralelo, sus tareas son siempre secuenciales. Sin embargo, es posible lograr algo similar al iniciar antes procesos que sean sumamente lentos. Por ejemplo, se podría dar la orden de rotación al disco rígido apenas comienza el inicializado, y acto seguido proseguir con el inicializado de otras tareas. El disco rígido tardará varios segundos en alcanzar la velocidad estándar de rotación estabilizada, tiempo en que se podría inicializar otros dispositivos.

Utilizando estos lineamientos, el fabricante de equipos Lenovo fué el primero en el mundo Windows en lograr un tiempo de incio inferior a 10 segundos. El iniciar selectivamente el equipo también tiene dos efectos beneficiosos: disminuir drásticamente el consumo de ciclos de CPU, y limitar el acceso al disco, como se puede comprobar en estos gráficos:

Inicio regular
Inicio optimizado

Figura 5: Consumo de CPU en arranque normal y arranque optimizado

Arranque híbrido en Windows 8

Para entender lo que es el arranque híbrido, debemos recordar que existe en Windows y posteriores, una sesión llamada “sesión 0″, que corresponde al sistema y no a un usuario humano. Sin embargo, desde el punto de vista del sistema operativo, es una sesión más.

Al apagar un equipo Windows 7, se tiene esta secuencia de apagado:

Figura 6: Proceso de apagado de Windows 7

El arranque híbrido consiste en cambiar el destino de los datos al apagarse. En efecto, al apagar Windows 8 se llega sólo hasta el punto 3, y luego se “hiberna” en el disco el estado del kernel y datos ya cargados de los drivers de dispositivos, es decir, no se hiberna el estado de los usuarios, pero los pasos 4 a 7 no se ejecutan nunca, sino que el estado de la memoria del kernel y el sector de RAM que aloja los drivers se almacenan en un archivo especial.

Figura 7: Proceso de apagado en Windows 8 que permitirá el arranque hibrido.

Al reiniciarse, se arranca el sistema, pero en vez de recorrer todo el proceso de arranque, se recupera el estado del kernel y de los manejadores de dispositivos desde el archivo de hibernación. Las ventajas son amplias: se acelera tanto el apagado (que no recorre los 8 puntos como en Windows 7) como el encendido (que no ejecuta el escaneo de drivers, etc. sino que aprovecha el estado guardado del mismo desde la última sesión de trabajo.

CONCLUSIONES

Este artículo es probablemente el más técnico en lo referente al sistema operativo de los que hemos escrito hasta el momento. En este documento hemos explorado las tecnologías y procedimientos que están detrás de los tiempos de encendido y apagado tan cortos que exhibe Windows 8 a través de la tecnología EFI (UEFI), que permitirá entender las ventajas del nuevo sistema operativo, y su proyección a futuro para los nuevos dispositivos móviles que utilizarán Windows 8 , Windows 8 RT y sus sucesores.

 

Por Ingeniero Carlos Perez – Polo IT Chaco

  1. Geniall información!! =D

    Reply
  2. Es una de las informaciones mas completas encontradas. Muchas gracias

    Reply
  3. Muy interesante y completo post. Se agradece.

    Reply
  4. muy Buena informacion sabes tengo una Toshiba y no encuentro las opsiones que dices me gustaria platicar con Ud. mi nombre es luis y mi cuenta en el face
    http://www.facebook.com/luiz.ramosramos

    Reply

Deja tu comentario

Tu correo no será publicado..

WP-Backgrounds Lite by InoPlugs Web Design and Juwelier Schönmann 1010 Wien