Las implementaciones de BIOS proporcionan interrupciones que pueden ser invocadas por sistemas operativos y programas de aplicación para utilizar las facilidades del firmware en computadoras compatibles con IBM PC [a] . Tradicionalmente, las llamadas de BIOS son utilizadas principalmente por programas DOS y algún otro software como cargadores de arranque (incluyendo, históricamente en su mayoría, software de aplicación relativamente simple que arranca directamente y se ejecuta sin un sistema operativo, especialmente software de juegos). BIOS se ejecuta en el modo de dirección real (Modo Real) de la CPU x86, por lo que los programas que llaman a BIOS también deben ejecutarse en modo real o deben cambiar del modo protegido al modo real antes de llamar a BIOS y luego volver a cambiar. Por esta razón, los sistemas operativos modernos que usan la CPU en modo protegido o modo largo generalmente no usan las llamadas de interrupción de BIOS para soportar funciones del sistema, aunque usan las llamadas de interrupción de BIOS para sondear e inicializar el hardware durante el arranque . [1] El modo real tiene una limitación de memoria de 1 MB, los cargadores de arranque modernos (por ejemplo, GRUB2 , Windows Boot Manager ) utilizan el modo irreal o el modo protegido (y ejecutan las llamadas de interrupción del BIOS en el modo Virtual 8086 , pero solo para el arranque del sistema operativo) para acceder hasta 4 GB de memoria. [2]
En todas las computadoras, las instrucciones de software controlan el hardware físico (pantalla, disco, teclado, etc.) desde el momento en que se enciende la energía. En una PC, el BIOS, precargado en ROM en la placa base, toma el control inmediatamente después de que se reinicia la CPU, incluso durante el encendido, cuando se presiona un botón de reinicio de hardware o cuando una falla crítica del software (una falla triple ) hace que los circuitos de la placa base activen automáticamente un reinicio de hardware. El BIOS prueba el hardware e inicializa su estado; encuentra, carga y ejecuta el programa de arranque (generalmente, un cargador de arranque del SO y ROM BASIC histórica ); y proporciona control básico del hardware al software que se ejecuta en la máquina, que generalmente es un sistema operativo (con programas de aplicación) pero puede ser una aplicación de software única que se inicia directamente.
Por su parte, IBM proporcionó toda la información necesaria para utilizar su BIOS en su totalidad o para utilizar directamente el hardware y evitar el BIOS por completo, al programar los primeros modelos de IBM PC (anteriores al PS/2). Desde el principio, los programadores tenían la opción de utilizar el BIOS o no, en función del hardware y el periférico. IBM promovió enérgicamente la creación de programas "de buen comportamiento" que accedieran al hardware sólo a través de llamadas INT del BIOS (y llamadas de servicio DOS), para respaldar la compatibilidad del software con los modelos de PC actuales y futuros que tuvieran hardware periférico diferente, pero IBM comprendió que para algunos desarrolladores de software y clientes de hardware, la capacidad del software de usuario para controlar directamente el hardware era un requisito. En parte, esto se debió a que un subconjunto significativo de todas las características y funciones del hardware no estaba expuesto por los servicios del BIOS. En dos ejemplos (entre muchos), los adaptadores MDA y CGA son capaces de desplazarse por hardware, y el adaptador serial del PC es capaz de transferir datos impulsados por interrupciones, pero el BIOS de IBM no admite ninguna de estas útiles características técnicas.
En la actualidad, la BIOS de una PC nueva aún admite la mayoría, si no todas, de las llamadas a funciones de interrupción de la BIOS definidas por IBM para la IBM AT (introducida en 1984), junto con muchas más nuevas, además de extensiones a algunas de las originales (por ejemplo, rangos de parámetros expandidos) promulgadas por varias otras organizaciones y grupos de colaboración de la industria. Esto, combinado con un grado similar de compatibilidad de hardware, significa que la mayoría de los programas escritos para una IBM AT todavía pueden ejecutarse correctamente en una PC nueva hoy, suponiendo que la velocidad de ejecución más rápida sea aceptable (lo que suele ser así para todos, excepto para los juegos que utilizan tiempos basados en la CPU). A pesar de las considerables limitaciones de los servicios a los que se accede a través de las interrupciones de la BIOS, han demostrado ser extremadamente útiles y resistentes al cambio tecnológico.
Las llamadas de interrupción del BIOS realizan funciones de control de hardware o de E/S solicitadas por un programa, devuelven información del sistema al programa o ambas cosas. Un elemento clave del propósito de las llamadas del BIOS es la abstracción: las llamadas del BIOS realizan funciones definidas de manera general y los detalles específicos de cómo se ejecutan esas funciones en el hardware particular del sistema están encapsulados en el BIOS y ocultos al programa. Por lo tanto, por ejemplo, un programa que desea leer desde un disco duro no necesita saber si el disco duro es una unidad ATA , SCSI o SATA (o en épocas anteriores, una unidad ESDI , o una unidad MFM o RLL con quizás un controlador Seagate ST-506 , quizás uno de los varios tipos de controladores Western Digital , o con un controlador propietario diferente de otra marca). El programa solo necesita identificar el número definido por el BIOS de la unidad a la que desea acceder y la dirección del sector que necesita leer o escribir, y el BIOS se encargará de traducir esta solicitud general en la secuencia específica de operaciones elementales requeridas para completar la tarea a través del hardware del controlador de disco particular que está conectado a esa unidad. El programa se libera de la necesidad de saber cómo controlar a bajo nivel cada tipo de disco duro (o adaptador de pantalla, o interfaz de puerto, o periférico de reloj en tiempo real) al que pueda necesitar acceder. Esto facilita la programación de sistemas operativos y aplicaciones y hace que los programas sean más pequeños, reduciendo la duplicación del código de programa, ya que la funcionalidad que está incluida en el BIOS no necesita estar incluida en cada programa que la necesita; en su lugar, se incluyen en los programas llamadas relativamente cortas al BIOS. (En los sistemas operativos donde no se utiliza el BIOS, las llamadas de servicio proporcionadas por el propio sistema operativo generalmente cumplen la misma función y propósito).
El BIOS también libera a los diseñadores de hardware de computadoras (en la medida en que los programas se escriben para usar exclusivamente el BIOS) de estar limitados a mantener una compatibilidad exacta del hardware con los sistemas antiguos cuando diseñan sistemas nuevos, con el fin de mantener la compatibilidad con el software existente. Por ejemplo, el hardware del teclado en el IBM PCjr funciona de manera muy diferente al hardware del teclado en los modelos IBM PC anteriores, pero para los programas que utilizan el teclado solo a través del BIOS, esta diferencia es casi invisible. (Como buen ejemplo del otro lado de esta cuestión, una parte significativa de los programas de PC en uso en el momento en que se introdujo el PCjr no usaban el teclado a través del BIOS exclusivamente, por lo que IBM también incluyó características de hardware en el PCjr para emular la forma en que funciona el hardware del teclado del IBM PC y del IBM PC XT original . La emulación del hardware no es exacta, por lo que no todos los programas que intentan usar el hardware del teclado directamente funcionarán correctamente en el PCjr, pero sí todos los programas que usan solo los servicios del teclado del BIOS).
Además de brindar acceso a las funciones de hardware, la BIOS proporciona funciones adicionales que se implementan en el software de la BIOS. Por ejemplo, la BIOS mantiene posiciones de cursor separadas para hasta ocho páginas de visualización de texto y proporciona una salida similar a TTY con ajuste automático de línea e interpretación de caracteres de control básicos como retorno de carro y avance de línea, mientras que el hardware de visualización de texto compatible con CGA tiene solo un cursor de visualización global y no puede avanzar automáticamente el cursor, usar la posición del cursor para direccionar la memoria de visualización (para determinar qué celda de carácter se cambiará o examinará) o interpretar caracteres de control. Otro ejemplo: la interfaz del teclado del BIOS interpreta muchas pulsaciones y combinaciones de teclas para llevar un registro de los distintos estados de las teclas ( Shift izquierda y derecha , Ctrl y Alt ), para llamar al servicio de impresión de pantalla cuando se pulsa Shift + PrtScrn , para reiniciar el sistema cuando se pulsa Ctrl + Alt + Supr , para llevar un registro de los estados de bloqueo (Caps Lock, Num Lock y Scroll Lock) y, en las máquinas de clase AT, para controlar las luces indicadoras de estado de bloqueo correspondientes en el teclado y para realizar otras funciones de interpretación y gestión similares para el teclado. En contraste, las capacidades ordinarias del hardware del teclado estándar de PC y PC-AT se limitan a informar al sistema de cada evento primitivo de una tecla individual que se pulsa o se suelta (es decir, hacer una transición del estado "soltado" al estado "presionado" o viceversa), realizar un reinicio ordenado y una autoprueba de la unidad del teclado y, para los teclados de clase AT, ejecutar un comando desde el sistema host para establecer los estados absolutos de los indicadores de estado de bloqueo (LED).
Los sistemas operativos y otros programas se comunican con el software BIOS para controlar el hardware instalado a través de interrupciones de software. Una interrupción de software es una variedad específica del concepto general de interrupción. Una interrupción es un mecanismo por el cual se puede ordenar a la CPU que deje de ejecutar el programa principal y ejecute inmediatamente un programa especial, llamado Rutina de Servicio de Interrupción (ISR, por sus siglas en inglés). Una vez que la ISR termina, la CPU continúa con el programa principal. En las CPU x86, cuando se produce una interrupción, la ISR a llamar se encuentra buscándola en una tabla de direcciones de punto de inicio de ISR (llamadas "vectores de interrupción") en la memoria: la tabla de vectores de interrupción (IVT, por sus siglas en inglés). Una interrupción se invoca por su número de tipo, de 0 a 255, y el número de tipo se usa como índice en la Tabla de vectores de interrupción, y en ese índice de la tabla se encuentra la dirección de la ISR que se ejecutará en respuesta a la interrupción. Una interrupción de software es simplemente una interrupción que se activa mediante un comando de software; Por lo tanto, las interrupciones de software funcionan como subrutinas, con la principal diferencia de que el programa que realiza una llamada de interrupción de software no necesita conocer la dirección del ISR, solo su número de interrupción. Esto tiene ventajas en cuanto a modularidad, compatibilidad y flexibilidad en la configuración del sistema.
Las llamadas de interrupción del BIOS pueden considerarse un mecanismo para pasar mensajes entre el BIOS y el software cliente del BIOS, como un sistema operativo. Los mensajes solicitan datos o acciones del BIOS y devuelven los datos solicitados, la información de estado y/o el producto de la acción solicitada al autor de la llamada. Los mensajes se dividen en categorías, cada una con su propio número de interrupción, y la mayoría de las categorías contienen subcategorías, llamadas "funciones" e identificadas por "números de función". Un cliente del BIOS pasa la mayor parte de la información al BIOS en los registros de la CPU y recibe la mayor parte de la información de vuelta de la misma manera, pero los datos demasiado grandes para caber en los registros, como las tablas de parámetros de control o los datos del sector del disco para las transferencias de disco, se pasan asignando un búfer (es decir, algo de espacio) en la memoria y pasando la dirección del búfer en los registros. (A veces, se pueden pasar varias direcciones de elementos de datos en la memoria en una estructura de datos en la memoria, con la dirección de esa estructura pasada al BIOS en los registros). El número de interrupción se especifica como el parámetro de la instrucción de interrupción del software (en el lenguaje ensamblador de Intel, una instrucción "INT"), y el número de función se especifica en el registro AH; es decir, el llamador establece el registro AH en el número de la función deseada. En general, los servicios de BIOS correspondientes a cada número de interrupción funcionan independientemente unos de otros, pero las funciones dentro de un servicio de interrupción son manejadas por el mismo programa de BIOS y no son independientes. (Este último punto es relevante para la reentrada ).
El software del BIOS suele devolver al usuario un código de error si no se ha ejecutado correctamente, o un código de estado y/o los datos solicitados si se ha ejecutado correctamente. Los datos en sí pueden ser tan pequeños como un bit o tan grandes como 65.536 bytes de sectores de disco completos (el máximo que cabe en un segmento de memoria en modo real). El BIOS se ha ampliado y mejorado muchas veces a lo largo de los años por muchas entidades corporativas diferentes y, lamentablemente, el resultado de esta evolución es que no todas las funciones del BIOS a las que se puede llamar utilizan convenciones consistentes para formatear y comunicar datos o para informar resultados. Algunas funciones del BIOS informan sobre información detallada del estado, mientras que otras pueden ni siquiera informar sobre el éxito o el fracaso, sino que simplemente regresan en silencio, dejando que el usuario asuma el éxito (o pruebe el resultado de alguna otra manera). A veces también puede ser difícil determinar si una determinada llamada a una función del BIOS es compatible con el BIOS en una determinada computadora o cuáles son los límites de los parámetros de una llamada en esa computadora. (Para algunos números de función no válidos, o números de función válidos con valores no válidos de parámetros clave—particularmente con una versión temprana del BIOS de IBM—el BIOS puede no hacer nada y regresar sin código de error; entonces es responsabilidad [inconveniente pero inevitable] del llamador evitar este caso al no hacer tales llamadas, o probar positivamente un efecto esperado de la llamada en lugar de asumir que la llamada fue efectiva. Debido a que el BIOS ha evolucionado ampliamente en muchos pasos a lo largo de su historia, una función que es válida en una versión del BIOS de un cierto proveedor puede no ser válida en una versión del BIOS anterior o divergente del mismo proveedor o en una versión del BIOS—de cualquier edad relativa—de un proveedor diferente.)
Debido a que las llamadas de interrupción del BIOS utilizan el paso de parámetros basado en registros de la CPU, las llamadas están orientadas a ser realizadas desde lenguaje ensamblador y no pueden realizarse directamente desde la mayoría de los lenguajes de alto nivel (HLL). Sin embargo, un lenguaje de alto nivel puede proporcionar una biblioteca de rutinas contenedoras que traducen los parámetros desde la forma (generalmente basada en pila) utilizada por el lenguaje de alto nivel a la forma basada en registros requerida por el BIOS, y luego de vuelta a la convención de llamada HLL después de que el BIOS regrese. En algunas variantes de C, las llamadas del BIOS se pueden realizar utilizando lenguaje ensamblador en línea dentro de un módulo C. (La compatibilidad con lenguaje ensamblador en línea no es parte del estándar ANSI C, sino una extensión del lenguaje; por lo tanto, los módulos C que utilizan lenguaje ensamblador en línea son menos portables que los módulos C estándar ANSI puros).
Se puede invocar una interrupción mediante la instrucción INT en lenguaje ensamblador x86 . Por ejemplo, para imprimir un carácter en la pantalla mediante la interrupción 0x10 del BIOS, se pueden ejecutar las siguientes instrucciones en lenguaje ensamblador x86:
mov ah , 0x0e ; número de función = 0Eh: Carácter a mostrar mov al , '!' ; AL = código del carácter a mostrar int 0x10 ; llamar a INT 10h, servicio de video del BIOS
A continuación, se incluye una lista de las clases de interrupción más comunes del BIOS. Algunas BIOS (en particular, las antiguas) no implementan todas estas clases de interrupción.
El BIOS también utiliza algunas interrupciones para transmitir interrupciones de eventos de hardware a programas que eligen recibirlas o para enrutar mensajes para su propio uso.
INT 18h
Tradicionalmente, se saltaba a una implementación de Cassette BASIC (proporcionada por Microsoft) almacenada en ROM opcionales . Esta llamada se invocaba normalmente si el BIOS no podía identificar ningún volumen de disco de arranque al iniciarse.
En el momento en que se lanzó el IBM PC original (IBM machine type 5150) en 1981, el BASIC en ROM era una característica clave. Los ordenadores personales populares contemporáneos como el Commodore 64 y la línea Apple II también tenían Microsoft Cassette BASIC en ROM (aunque Commodore renombró su versión con licencia Commodore BASIC), por lo que en una parte sustancial de su mercado objetivo, el IBM PC necesitaba BASIC para competir. Al igual que en esos otros sistemas, el ROM BASIC del IBM PC sirvió como un sistema operativo primitivo sin disco, que permitía al usuario cargar, guardar y ejecutar programas, así como escribirlos y refinarlos. (El IBM PC original también fue el único modelo de PC de IBM que, al igual que sus dos competidores antes mencionados, incluía hardware de interfaz de casete. Un modelo básico de IBM PC tenía solo 16 KiB de RAM y ninguna unidad de disco de ningún tipo, por lo que la interfaz de casete y BASIC en ROM eran esenciales para hacer que el modelo base fuera utilizable. Un IBM PC con menos de 32 KiB de RAM es incapaz de arrancar desde el disco. De los cinco chips ROM de 8 KiB en un IBM PC original, que suman un total de 40 KiB, cuatro contienen BASIC y solo uno contiene el BIOS; cuando solo se instalan 16 KiB de RAM, el ROM BASIC representa 4/7 de la memoria total del sistema).
A medida que pasó el tiempo y BASIC ya no se incluía en todas las PC, esta interrupción simplemente mostraba un mensaje de error que indicaba que no se había encontrado ningún volumen de arranque (como "No ROM BASIC" o mensajes más explicativos en versiones posteriores del BIOS); en otras versiones del BIOS, solicitaba al usuario que insertara un volumen de arranque y presionara una tecla, y luego de que el usuario presionara una tecla, volvía al cargador de arranque (INT 19h) para intentar arrancar nuevamente.
Rainbow 100 B de Digital solía INT 18h
llamar a su BIOS, lo cual era incompatible con el BIOS de IBM. Turbo Pascal , Turbo C y Turbo C++ reutilizaron INT 18 para la asignación de memoria y paginación. Otros programas también reutilizaron este vector para sus propios fines.
En sistemas DOS, IO.SYS o IBMBIO.COM conecta INT 13 para detectar cambios de disquete, rastrear llamadas de formato, corregir errores de límites de DMA y solucionar problemas en el BIOS ROM de IBM "01/10/84" con el código de modelo 0xFC antes de la primera llamada.
Muchos sistemas operativos modernos (como Linux y Windows ) no utilizan ninguna llamada de interrupción del BIOS después del inicio, sino que eligen interactuar directamente con el hardware. Para ello, se basan en controladores que forman parte del propio núcleo del sistema operativo , se incluyen con el sistema operativo o son proporcionados por los proveedores de hardware.
Existen varias razones para esta práctica. La más importante es que los sistemas operativos modernos se ejecutan con el procesador en modo protegido (o largo ), mientras que el código de la BIOS solo se ejecutará en modo real . Esto significa que si un sistema operativo que se ejecuta en modo protegido quisiera hacer una llamada a la BIOS, primero tendría que cambiar al modo real, luego ejecutar la llamada y esperar a que regrese, y finalmente volver al modo protegido. Esto sería terriblemente lento e ineficiente. El código que se ejecuta en modo real (incluido el BIOS) está limitado a acceder a poco más de 1 MiB de memoria, debido al uso de direccionamiento de memoria segmentada de 16 bits . Además, la BIOS generalmente no es la forma más rápida de llevar a cabo ninguna tarea en particular. De hecho, las limitaciones de velocidad de la BIOS hicieron que fuera común incluso en la era DOS que los programas lo eludieran para evitar sus limitaciones de rendimiento, especialmente para la visualización de gráficos de video y la comunicación serial rápida.
Además de los factores mencionados anteriormente, los problemas con la funcionalidad del BIOS incluyen limitaciones en el rango de funciones definidas, inconsistencia en los subconjuntos de esas funciones soportadas en diferentes computadoras y variaciones en la calidad de los BIOS (es decir, algunos BIOS son completos y confiables, otros son abreviados y llenos de errores). Al tomar el asunto en sus propias manos y evitar depender del BIOS, los desarrolladores de sistemas operativos pueden eliminar algunos de los riesgos y complicaciones que enfrentan al escribir y soportar software de sistema. Por otro lado, al hacerlo, esos desarrolladores se vuelven responsables de proporcionar software de controlador "bare metal" para cada sistema o dispositivo periférico diferente con el que pretenden que funcione su sistema operativo (o de inducir a los productores de hardware a proporcionar esos controladores).
Por lo tanto, debería ser evidente que los sistemas operativos compactos desarrollados con presupuestos pequeños tenderían a utilizar intensamente el BIOS, mientras que los sistemas operativos grandes creados por grandes grupos de ingenieros de software con grandes presupuestos optarían con mayor frecuencia por escribir sus propios controladores en lugar de utilizar el BIOS, es decir, incluso sin considerar los problemas de compatibilidad del BIOS y el modo protegido.