El principal propósito de toda computadora es poder correr programas en ella, ya sea procesadores de texto, reproductores de música, reproductores de imágenes fotográficas, reproductores de videos, navegadores browser para Internet, ventanas de chat, o inclusive (todavía) cargar algún programa para llevar a cabo algún tipo de programación en algún lenguaje propio de la máquina como BASIC, FORTRAN, PASCAL, etc. Al nivel más rudimentario, esto requiere cargar en la memoria de la máquina, una memoria rápida pero volátil, la memoria RAM, las combinaciones binarias de unos y ceros que hacen posible que se ejecute cualquier programa. Si el programa que se va a ejecutar es un programa de extensión pequeña, digamos de unos 800 bytes, lo cual representa 6,400 bits en total, es posible mediante la activación de interruptores individuales exteriores ir metiendo cada byte en la localidad que le corresponde en la memoria, lo cual indudablemente llevará tiempo (posiblemente dos o tres días, suponiendo que no se cometa ningún error y que no haya fallos en el suministro de energía eléctrica). De hecho, esto era lo que se acostumbraba hacer cuando aparecieron las primeras computadoras experimentales. Pero si se trata de algún programa que tenga una extensión (muy moderada, para nuestros tiempos actuales) de unos dos megabytes, o sea dos millones de bytes, hacer manualmente este proceso de carga está fuera de toda consideración. Se requiere, primero que nada, tener alguna manera de poder almacenar en una memoria no-volátil los programas cuyo tamaño haga conveniente el poder tenerlos de forma tal que no se borren al apagarse la computadora, en algún medio posiblemente magnético como las cintas de grabadora magnetofónicas (esta tecnología aún está en uso en algunas instalaciones), o bien en discos flexibles o disquetes como los que fueron usados en las primeras computadoras personales, o bien en tambores magnéticos, o bien en discos duros, o bien (de manera actualizada) en dispositivos USB flash. Pero aún teniendo un medio de almacenamiento externo permanente disponible, el problema de pasar la información de la memoria persistente a la memoria RAM de la computadora sigue allí. La forma de solucionar esto es mediante un pequeño programa cargador conocido como loader, y tratándose del caso en el cual la computadora es recién encendida, es usual encontrar el término bootstrap loader, en alusión a las cintillas “bootstrap” usadas para “jalar” hacia arriba las botas -boots- haciendo que toda la bota entre en el pie. El loader bootstrap forma parte integral de la electrónica de la máquina y no es más que una memoria permanente ROM que no se borra cuando la máquina es apagada. Al encenderse la máquina, la primera instrucción en ser ejecutada es precisamente la instrucción con la que empieza el código correspondiente al bootstrap loader. En muchos diseños, y en contra de lo que pudiera suponerse, el código del cargador bootstrap no es puesto al inicio del espacio de la memoria (empezando en una localidad como 00000) sino lo más cercano posible al tope de la memoria (en una localidad como FFF012). Al ejecutarse este código inmediatamente después de haber sido encendida la máquina, se puede invocar un programa ejecutable maestro ubicado externamente en algún dispositivo como el disco duro para empezar a cargarlo en la memoria volátil RAM de la máquina, el cual se encargará a su vez de administrar los programas y archivos que está almacenados en la memoria persistente no-volátil a espera de ser invocados por la memoria RAM. Podemos representar este proceso de la siguiente manera:
Pero esto no es todo lo que podemos esperar que se haga a partir del momento en el que es encendida la máquina. Esperamos también, como mínimo, que se lleve a cabo un chequeo funcional de toda la memoria RAM, para estar satisfechos de que no hay localidad alguna que por cuestión de falla eléctrica tenga algún “bit” atorado en “cero” (esto se conoce en la literatura técnica como stuck-at-zero) o atorado en “uno” (esto se conoce en la literatura técnica como stuck-at-one), teniendo en mente que basta con que un solo bit en todo el espacio de la memoria RAM esté defectuoso para que la computadora se puede venir abajo por completo; aquí la confiabilidad debe ser del cien por ciento. Además de esto, es deseable que se lleve a cabo algún reconocimiento de manera automática de todo el hardware conectado físicamente a la máquina, sobre todo en caso de que se haya reemplazado algún dispositivo ya sea por falla o por actualización. Todo esto de hecho se lleva a cabo, y el componente que lo lleva a cabo es el circuito integrado conocido como el BIOS (del inglés Basic Input-Output System). Todas las computadoras personales tienen un BIOS instalado en ellas, y aún las máquinas de mayor potencia incluyendo las supercomputadoras tienen algo equivalente al BIOS, porque se trata de una necesidad básica, se trata de una serie de tareas que hay que llevar a cabo inmediatamente después del encendido de la computadora. El circuito integrado BIOS no contiene compuertas lógicas para implementar funciones de lógica combinatórica o lógica secuencial, es simple y sencillamente una memoria ROM de lectura únicamente, la cual contiene instrucciones en lenguaje de máquina para ser interpretadas por el procesador CPU y ser llevadas a cabo.
Una vez que el chip BIOS ha hecho lo suyo en lo que corresponde a la verificación de la integridad de la memoria volátil RAM y la comprobación (y actualización) de los recursos de hardware conectados electrónicamente al hardware de la máquina, la secuencia de control es transferida al sub-programa bootstrap loader (el cual es la última porción de código en ser ejecutada por el BIOS, el cual contiene en su parte final al programa bootstrap loader) para que en la memoria RAM de la máquina empiece a ser cargado el primer programa ejecutable que tomará el control de la máquina.
¿Y qué tipo de programa ejecutable habremos de cargar automáticamente en la memoria RAM de una máquina recién encendida? Podemos tratar de cargar un editor de texto para elaborar programas en algún lenguaje de alto nivel como FORTRAN o C, podemos cargar un compilador para obtener un programa ejecutable tras la compilación de algún programa elaborado previamente con un procesador de texto, o podemos cargar cualquier otro programa de aplicación, pero en tal caso la máquina solo servirá para ese propósito desde que es encendida hasta que es apagada, y nosotros no queremos tal cosa, queremos que la computadora sea un instrumento versátil en el que se pueda correr cualquier tipo de programa. En pocas palabras, queremos cargar una especie de “programa maestro” no muy grande que una vez instalado en la memoria RAM nos permita cargar en la misma memoria RAM uno de varios programas ejecutables que tengamos almacenados en la memoria no-volátil, dándonos la opción de poder escoger el programa que queramos cargar en la memoria de acuerdo a su <i>nombre de archivo</i>. El mismo “programa maestro” nos debe permitir descargar de la memoria RAM un programa ejecutable que ya no queremos usar (de preferencia, borrándolo por completo de la memoria volátil RAM, más no de la memoria persistente que puede ser un disco duro o un tambor magnético o algún otro medio) para cargar tras esto otro programa. Pero no es lo único que queremos que haga el programa maestro. Posiblemente en el acto de ejecutar algún programa se generará (o se generarán) algún resultado que queremos guardar en la memoria no-volátil para que el fruto de nuestro trabajo no se pierda al apagarse la computadora, como en el caso de un programa compilador que toma un archivo de texto y genera un programa ejecutable que queremos guardar en algún lado. Y de hecho, queremos que desde la computadora también se puedan borrar en la memoria no-volátil los archivos que ya no necesitamos. Del mismo modo, queremos hacer otras cosas tales como el copiado de archivos, el renombrado de archivos (cambiándoles su nombre original por otro), etc. Estamos hablando, pues, de una serie de cosas que no esperamos que haga el BIOS. Este “programa maestro” es lo que hoy en día conocemos como el sistema operativo. De este modo, después de que el BIOS ha hecho la parte que le corresponde al encenderse la computadora, el bootstrap loader debe cargar el sistema operativo en la memoria RAM de la computadora, y una vez que esto se ha llevado a cabo, desde el sistema operativo podemos invocar algún programa ejecutable que está guardado en el disco duro de la computadora, pasando una copia de dicho programa ejecutable a la memoria RAM de la computadora y echando a andar dicho programa. De este modo, tenemos un proceso como el siguiente (desde que se enciende la máquina hasta que se apaga, todo el funcionamiento consiste en la transferencia interminable de la ejecución de un programa a otro y a otro y a otro, hasta el apagado de la máquina requiere cargar en la memoria RAM un programa que se encargue de los últimos pasos requeridos para cerrar archivos que aún permanezcan abiertos así como actualizar la configuración del sistema en caso de que haya cambiado):
Obsérvese que ese programa maestro conocido como el sistema operativo tiene que tener su propio cargador (loader) para cargar programas y archivos de la memoria persistente a la memoria RAM de la computadora. Este loader no debe ser confundido con el bootstrap loader, el primero es parte del conjunto de sub-programas que forman parte del sistema operativo y que está almacenado en la memoria persistente (el disco duro), mientras que el segundo forma parte integral de la electrónica de la máquina.
El sistema operativo, por su propia naturaleza, puesto que tiene que estar presente todo el tiempo en algún lugar del espacio de la memoria, nos reducirá la cantidad de memoria RAM que tengamos disponible para nuestro uso personal, se trata de un programa en cierto modo parasítico. Pero es un mal necesario, porque las tareas que debe llevar a cabo son algo que tarde o temprano se antojan como algo indispensable. Sin embargo, y a diferencia de lo que ocurría con los sistemas operativos de antaño (como en las primeras computadoras personales IBM y sus clones compatibles), ya no es posible en muchas máquinas tener todo el sistema operativo cargado en la memoria RAM después de haberse encendido la máquina, ya que por su tamaño ello no dejaría espacio útil en la memoria para hacer casi nada. La única opción consiste en cargar la memoria RAM con lo más importante del sistema operativo, volviendo accesibles en forma inmediata las funciones de mayor uso del sistema operativo (empezando por la interfaz gráfica), e invocando otras funciones de la memoria no-volátil (del disco duro) conforme ello se vaya requiriendo.
Cuando aparecieron las primeras computadoras personales IBM y clones compatible, en virtud de que aún no había discos duros para tales máquinas el sistema operativo que era incluído junto con la máquina al momento de venderse estaba proporcionado en discos magnéticos flexibles llamados entonces floppies, los cuales eventualmente fueron reemplazados por diskettes (lo mismo, pero más pequeño). Era necesario tener puesto en la máquina el disco del sistema operativo al momento de que se fuera a encender la máquina, para posibilitarle al BIOS la búsqueda del sistema operativo en los discos floppies.
Como mínimo, esperamos que un sistema operativo, el que sea, sin importar su presentación al usuario o el logo de su fabricante, pueda llevar a cabo las siguientes tareas:
1) Cargar un programa ejecutable en la memoria RAM de la máquina leyéndolo de la memoria persistente (por ejemplo, el disco duro), determinando primero si hay espacio suficiente para poder meter todo el programa ejecutable en la memoria.
2) Guardar en la memoria persistente cualquier archivo nuevo que se haya generado durante la ejecución de un programa (por ejemplo, un archivo de texto).
3) Borrar de la memoria persistente cualquier archivo que ya no se requiera.
4) Cambiarle el nombre a cualquier archivo que esté guardado en la memoria persistente.
5) Hacer una copia (o varias) de cualquier archivo que esté almacenado en la memoria persistente.
Todas estas tareas son comunes a todos los sistemas operativos que existen en la actualidad.
Funcionalmente, podemos clasificar a los sistemas operativos en dos tipos:
a) Sistemas operativos basados en líneas de comandos, cuya interfaz ya sea en UNIX o en MS-DOS o en cualquier otro entorno de este tipo presenta un aspecto como el siguiente:
b) Sistemas operativos basados en una interfaz gráfica GUI (Graphical User Interface) que presenta un aspecto visual como el siguiente:
En realidad, y aunque algunos proveedores no quieran admitirlo, ambos entornos pueden hacer lo mismo, lo único que cambia es la presentación. Sin embargo, en los hechos, la interfaz gráfica ha resultado ser mucho más amigable. El advenimiento de la interfaz gráfica que facilitó la computación para las masas no habría sido posible sin la invención casi simultánea del mouse presentado por vez primera al público en 1968, que con doble clic del botón izquierdo permite echar a andar un programa de aplicación, con un simple clic del botón izquierdo permite decidir cursos de acción, y con un clic del botón derecho permite escoger otras opciones. Cabe agregar que el concepto de las “ventanas” no fue una invención de Microsoft. La idea original para un sistema operativo con un entorno gráfico en lugar de un entorno basado en líneas de texto se originó en el Palo Alto Research Center de Xerox, y tiene una historia interesante que involucró fuertes pleitos legales en una lucha por lo que determinaría el futuro y la predominancia de los sistemas operativos basados en entornos gráficos.
En contra de lo que pudiera creerse, las primeras versiones de Windows no constituían realmente un sistema operativo. Se trataba más bien de una interfaz gráfica que le ofrecía al usuario la comodidad de poder hacer lo mismo que era posible hacer desde una línea de comandos (creación de directorios con el comando dir, borrado de archivos con el comando erase, copiado de archivos con el comando copy, creación de directorios y sub-directorios con el comando makedir, etc.) pero haciéndolo a través de una interfaz gráfica con líneas de menú (estas líneas de menú ofreciendo opciones y sub-opciones solo son posibles en entornos gráficos, aunque aún antes del advenimiento de los entornos gráficos de Windows y Linux fue posible implementar líneas de menú en programas tales como el procesador de palabras WordStar y el paquete de herramientas y utilerías PC Tools mediante programación inteligente usando el conjunto limitado de caracteres gráficos disponibles en el código ASCII). La interfaz gráfica de Windows inclusive era vendida como un producto separado instalable en los discos duros de las computadoras equipadas con el viejo sistema operativo MS-DOS, pero dejando intacto el sistema operativo MS-DOS. Para echar a andar este Windows, había que situarse en el directorio que contenía al programa ejecutable win.exe (localizable desde la línea de comandos como C:\WINDOWS), escribiendo win a continuación del símbolo “prompt” del MS-DOS y presionando la tecla de entrada “Enter”, lo cual echaba a andar la interfaz gráfica. Sin embargo, era posible salir de esta interfaz gráfica con tan solo hacer doble clic sobre el cuadro del menú Control del Administrador de Programas, regresando al sistema operativo MS-DOS. El epítome de este Windows se dió con Windows 3.1.
El parteaguas en Windows ocurre con la introducción de Windows 95, el cual a diferencia de Windows 3.1 no era simplemente una interfaz gráfica; era todo un sistema operativo en toda la extensión de la palabra, el cual tomaba control de la máquina desde que era encendida hasta que era apagada, y el cual requería de un disco duro para su instalación. Se invirtieron los papeles y la ventana de comandos pasó a ser un programa ejecutable invocable desde Windows 95.
De cualquier modo, aunque Windows 3.1 no era un sistema operativo, el refinamiento de la interfaz gráfica trajo consigo varias innovaciones, empezando con las siguientes que empezaron a tomar forma con la introducción de Windows 3.1:
1) La programación visual, la cual había comenzado con la introducción en 1991 de la primera versión de Visual Basic inspirada en el lenguaje BASIC, pero incorporando herramientas para llevar a cabo la creación de programas capaces de interactuar gráficamente con el usuario. Esta versión fue mejorada en 1992 con Visual Basic 2.0 (puesta a la venta en dos versiones, Visual Basic Standard Edition y Visual Basic Professional Edition), la cual fue superada en 1993 de manera simultánea con la introducción de Windows 3.0, para ser reemplazada en 1995 con Visual Basic 4.0 con una versión Visual Basic Enterprise Edition añadida para apoyar la introducción simultánea de Windows 95, el primer sistema operativo basado por completo en la interfaz gráfica de Windows. La programación visual cambia por completo el paradigma de la programación, ya que en vez de empezar con un editor de texto para ir insertando comandos en BASIC se empieza con un entorno visual en el cual se van añadiendo gráficamente controles gráficos generándose en forma automática el código en texto requerido para apoyar los elementos gráficos.
2) La introducción del concepto de los bibliotecas de enlace dinámico o DLLs (del inglés, Dynamic Link Libraries).
3) La Vinculación e Incrustación de Objetos (OLE, Object Linking and Embedding.
4) La definición formal de los Controladores de Dispositivos (device drivers) escritos en Windows como VxD.
5) La introducción de programas accesorios de naturaleza visual que no eran posibles en el sistema basado en una ventana única de líneas de comandos, programas tales como la Calculadora, la Agenda, el Fichero, el Mapa de Caracteres, el Reloj, el Bloc de Notas, el predecesor de Paint conocido como Paintbrush, la grabadora que permitía grabar una secuencia de teclas y acciones del mouse, la grabadora de sonidos, la terminal que permitía conectar una computadora a otra a través de un módem, y el programa Write para elaboración de documentos de texto que precedió al programa WordPad
En el camino, Microsoft introdujo otro elemento para un control más eficiente de nuevos programas ejecutables instalados en el disco duro, el Registro de Windows (en inglés, Registry - Wikipedia), el cual además de imponer una nueva y pesada carga en las responsabilidades de los programadores de sistemas dejaría al sistema operativo Windows expuesto a ataques informáticos de todo tipo, ofreciendo tantas vulnerabilidades ante el acoso de virus informáticos, gusanos, troyanos, y malware de todo tipo, que Microsoft se tendría que ver en la penosa necesidad de tener que estar actualizando constantemente sus sistemas operativos Windows a través de Internet a sus usuarios registrados con parches de seguridad que antes no eran necesarios.
Para el manejo de archivos, el sistema operativo Windows 95 usaba un artificio conocido como la Tabla de Asignación de Archivos o FAT (en inglés, File Allocation Table), adaptada a los microprocesadores Intel de 16 bits bajo el nombre FAT16. El siguiente paso evolutivo ocurrió con Windows 98, un sistema operativo desarrollado para aprovechar las capacidades de los recién introducidos procesadores Intel de 32 bits, lo cual se reflejó en la introducción de la tabla FAT32. Ambas técnicas para la administración de archivos terminarían siendo reemplazadas en el sistema operativo Windows XP con la técnica de administración de archivos Windows NT (las siglas significan New Technology).
Cuando aparecieron las computadoras de primera generación, las memorias RAM basadas en núcleos de ferritas eran tan pequeñas que solo había espacio suficiente para correr un programa a la vez en la máquina, por ejemplo, un programa compilador del lenguaje FORTRAN. Si se quería correr otro programa, por ejemplo un programa de contabilidad para el pago de nóminas, era necesario sacar de la memoria RAM el compilador FORTRAN para meter el programa contable. Sin embargo, al ir aumentando la capacidad de las memorias RAM, sobre todo con la introducción de memorias basadas en la tecnología de transistores y semiconductores, se volvió posible considerar la posibilidad de tener en una misma máquina dos o más programas diferentes, sin necesidad de tener que estar sacando un programa para meter otro. El usuario moderno de computadoras personales ya está acostumbrado a esto, está acostumbrado a que su máquina pueda, por ejemplo, tenerle abierto un procesador de documentos y permitirle escuchar música al mismo tiempo. El poder tener dos o más programas diferentes ejecutándose al mismo tiempo en una computadora es lo que conocemos como multiprogramación. Pero aquí puede surgir una duda. Sabiendo que una computadora con una unidad central de procesamiento CPU solo puede ejecutar una instrucción de máquina a la vez, ¿cómo es posible que una computadora pueda ejecutar al mismo tiempo dos instrucciones diferentes que corresponden a programas completamente diferentes, ya no se diga los programas completos? La respuesta es: la máquina no puede hacer tal cosa. Lo que ocurre en realidad es que la máquina le dedica una porción pequeña de tiempo (digamos, dos milisegundos) a la ejecución de una porción de código que corresponde a un programa ejecutable que llamaremos A, tras lo cual dedica otra porción pequeña de tiempo (digamos, también de dos milisegundos) a la ejecución de una porción de código que corresponde a un programa ejecutable que llamaremos B, tras lo cual regresa al programa A repitiéndose el proceso una y otra vez. De este modo, la máquina le está dedicando la mitad de su tiempo a cada programa ejecutable, pero lo hace tan rápidamente que se crea la ilusión (y en realidad no es más que esto, una ilusión) de que ambos programas se están ejecutando simultáneamente de forma continua sin interrupción alguna. La multiprogramación es algo que está bajo todo el tiempo bajo el control del sistema operativo, el cual es responsable de adjudicarle a cada programa el tiempo que le corresponda. El siguiente gráfico animado nos muestra cómo se ejerce tal control:
Hay una técnica que se apoya en la idea de los hilos de ejecución y mediante la cual es posible llevar a cabo la multiprogramación, la cual se conoce como multihilo (en inglés, multithreading).
Otra cosa que hoy esperamos que cualquier sistema operativo moderno esté llevando a cabo en forma continua es lo que se conoce como la recolección de basura (en inglés, garbage collection) para la cual se elabora para cada sistema un programa conocido como el recolector de basura. Se genera “basura” cuando, en una sesión de multiprogramación, ya no requerimos de un programa y salimos del mismo, lo cual libera la porción de memoria RAM que estaba utilizando el programa. El problema es que conforme se va saliendo de un programa tras otro, la memoria RAM se va fragmentando, y es muy posible que ya no haya espacio suficiente en la memoria RAM para abrir otro programa ejecutable aunque en apariencia lo haya. A modo de ejemplo, supóngase que se tiene una computadora con 640 Megabytes de memoria RAM. Supóngase que el sistema operativo ya está consumiendo 120 Megabytes, lo cual nos deja 520 Megabytes disponibles. Supóngase que vamos cargando en la memoria RAM, uno tras otro, varios programas ejecutables de 150 Megabytes cada uno, hasta tener tres programas en total en la memoria RAM, consumiendo 450 Megabytes, localizados uno tras otro en forma contigua (sin brechas de espacio en el mapa de la memoria RAM) . Nos quedan entonces 70 Megabytes de RAM disponibles para otros propósitos. En cierto punto, salimos del programa número dos, lo cual nos libera 150 Megabytes, y tenemos ya con esto 220 Megabytes libres en la memoria RAM. Aparentemente, podemos cargar en la memoria RAM otro programa ejecutable (por ejemplo, un procesador de imágenes) cuyo tamaño sea 200 Megabytes. Sin embargo, no se puede hacer tal cosa, ya que los 220 Megabytes en el espacio de la memoria están fragmentados en dos pedazos, uno de 70 Megabytes, y el otro de 150 Megabytes, los cuales no son contiguos. No podemos meter un programa de 200 Megabytes ni en una porción de memoria RAM de 70 Megabytes ni en una porción de memoria RAM de 150 Megabytes, simple y sencillamente el programa no cabe en ninguna de las dos porciones. Aunque podemos tratar de solventar esto mediante algún truco tal como fraccionar el programa de 200 Megabytes en varias páginas, digamos de 50 Megabytes cada página, para ir ejecutando página tras página mediante saltos continuos de una página a otra, lo cual ciertamente será un proceso que puede ser exasperantemente tardado, existe una alternativa mucho mejor, la cual consiste en compactar la memoria RAM eliminando las brechas vacías. En esto consiste precisamente la recolección de basura. El siguiente gráfico animado nos muestra un ejemplo de cómo el recolector de basura del sistema operativo va funcionando de manera automática conforme se va saliendo de programas que ya no serán usados:
El proceso de fragmentación del espacio disponible no es algo que ocurra únicamente con la memoria volátil RAM. También ocurre en el medio de almacenamiento persistente (el disco duro), de modo tal que aunque el sistema operativo nos diga que en un disco duro de 320 Gigabytes nos quedan 50 Gigabytes disponibles, en realidad tal vez no queden ni siquiera 100 Megabytes disponibles a causa de la fragmentación. Se vuelve necesario en tales casos desfragmentar el disco duro, y esto es algo que tarde o temprano ocurrirá conforme se vayan guardando y se vayan borrando archivos en la memoria persistente hasta el límite de su capacidad. La práctica moderna es que sea el mismo sistema operativo el que le de la voz de alerta al usuario recomendándole la desfragmentación de su disco duro cuando ello se considere necesario. Cualquiera que haya llevado a cabo la desfragmentación de su disco duro sabe que esto puede ser un proceso bastante tardado. El programa de desfragmentación del disco duro no es algo que el sistema operativo lleve consigo todo el tiempo cuando está instalado en la memoria RAM de la computadora tras el encendido de la máquina, es uno de esos varios sub-programas del sistema operativo que con la finalidad de no agotar la capacidad de la memoria RAM disponible es invocado únicamente cuando se le necesita.
Siendo el sistema operativo a fin de cuentas un programa como cualquier otro, y tomando en cuenta el incremento continuo en las capacidades de las memorias ROM, memorias de lectura únicamente que una vez grabadas electrónicamente ya no pueden ser alteradas por nadie (se requiere un programador PROM para programarlas), cabe formularse la siguiente pregunta: ¿por qué no grabar todo un sistema operativo (por ejemplo, Windows, o Linux) en un circuito integrado ROM instalado en la misma máquina al momento de su venta? De este modo, el sistema operativo sería completamente invulnerable a cualquier tipo de ataque, cada vez que se encendiera la máquina el sistema operativo despertaría intacto. La idea de hecho ha sido considerada seriamente en varias ocasiones por expertos de informática. Sin embargo, ofrece varias dificultades. La primera gran dificultad es que conforme van apareciendo nuevas tecnologías como ha ido ocurriendo con las impresoras ink-jet que sustituyeron a las impresoras mecánicas de cartuchos de cintas de tinta y los monitores de colores de alta calidad SVGA que reemplazaron a los monitores monocromáticos siendo a su vez reemplazados por las pantallas planas, no es posible incorporar tales mejoras tecnológicas a una máquina cuyo sistema operativo está sellado y cerrado. Esto se puede compensar con circuitos integrados ROM removibles de un socket en el tablero de la electrónica de la máquina, de modo tal que cada vez que hubiera una mejora digna de ser asimilada en un sistema operativo se podría reemplazar el sistema operativo en ROM removiendo el chip anterior e instalando un ROM nuevo con el sistema operativo actualizado. Sin embargo, los circuitos integrados actualizados y el costo de instalación de los mismos en la máquina llevada a cabo por técnicos especializados implicaría un costo adicional en cada mejora o actualización, lo cual no es muy agradable en contraste con la actualización gratuita proporcionada en-línea vía Internet. Pero aún suponiendo que se adoptara esta estrategia, volviendo al sistema operativo invulnerable e invencible, queda como problema irresoluble el que le corresponde a la memoria persistente (el disco duro), en donde se guardan los programas ejecutables, una memoria en la cual es posible leer, alterar, y borrar no sólo desde el mismo teclado de la máquina sino inclusive a control remoto, como lo han demostrado algunos hackers ingeniosos. No hay garantía alguna de que todos los programas ejecutables que se vayan instalando en el disco duro estarán libres de infecciones informáticas, y el sistema operativo no tiene manera de saber cuáles programas están libres de intrusos y cuáles no. Hasta los programas antivirus que supuestamente deben proteger a una máquina de infecciones informáticas han sido objeto de ataques. Sin embargo, y en respuesta a la pregunta sobre si es posible “grabar” todo un sistema operativo en una memoria ROM para hacerlo parte integral de la electrónica de la máquina, tal cosa es posible hoy mismo, y hasta podría incorporar dentro de sí las instrucciones en lenguaje de máquina y las tareas especificadas actualmente especificadas por el BIOS, poniéndolo todo dentro de un mismo circuito integrado.