← Fundamentos de Sistemas Operativos Bloque 1 · Introducción · Tema 3 de 34

Tema 03

Historia y evolución de los sistemas operativos

Ninguna idea de este curso se inventó por gusto: cada una fue la respuesta a un problema concreto de su época. Recorremos setenta años de sistemas operativos fijándonos en qué problema había, qué solución apareció y qué concepto nos dejó.

1. Por qué mirar hacia atrás

En el tema 2 vimos qué problemas resuelve un sistema operativo. Pero esos problemas no aparecieron todos juntos, ni las soluciones tampoco. Las interrupciones, el modo kernel, los procesos o la memoria virtual pueden parecer una lista arbitraria de mecanismos cuando se estudian por primera vez; vistos en orden histórico, cada uno resulta ser la respuesta razonable a una dificultad que la etapa anterior dejó sin resolver.

Hay un hilo que recorre toda la historia y conviene tenerlo presente desde el principio: qué es lo caro. En los años cincuenta una computadora costaba millones de dólares y el tiempo de las personas, en comparación, casi nada; el objetivo era que la máquina no estuviera ociosa ni un segundo. Hoy la relación se invirtió: el hardware es barato y lo valioso es el tiempo de quien lo usa. Casi todos los cambios de rumbo que veremos se explican por ese desplazamiento.

Para ampliar

Este tema se concentra en la evolución de las ideas. Si quieres conocer cada sistema por separado, con su contexto, sus autores y sus anécdotas, el curso Historia de los Sistemas Operativos dedica un tema a cada uno de los veinte sistemas más influyentes. A lo largo del texto encontrarás enlaces a los que correspondan.

2. Panorama de las etapas

Las fechas son aproximadas y las etapas se superponen, pero la secuencia de problemas y soluciones es clara:

ÉpocaEtapaProblema que resuelveSistemas de referencia
1945–1955Sin sistema operativo—ENIAC, EDSAC, IBM 701
1955–1965Sistemas por lotesLa máquina ociosa entre un trabajo y otroGM-NAA I/O
1960–1970MultiprogramaciónLa CPU ociosa mientras se espera a un dispositivoAtlas, OS/360
1961–1975Tiempo compartidoEl programador espera horas por cada resultadoCTSS, Multics, Unix
1975–1990Computadoras personalesUna máquina para cada persona, barataCP/M, MS-DOS, Mac OS
1990–2005Sistemas modernos en la PCFalta de protección y de multitarea realLinux, Windows NT
2007–hoyMóvilesBatería, pantalla táctil, aplicaciones no confiablesiOS, Android
2005–hoyVirtualización y nubeAprovechar y aislar servidores con muchos núcleosXen, KVM, Docker

3. La máquina sin sistema operativo (1945–1955)

Las primeras computadoras no tenían nada que se pareciera a un sistema operativo. Quien quería ejecutar un programa reservaba un turno en una planilla, llegaba a la sala a la hora asignada con sus tarjetas perforadas o su cinta de papel, cargaba el programa a mano, lo ponía en marcha con los interruptores de la consola y esperaba el resultado. Si el programa fallaba, examinaba las luces del panel para averiguar por qué. Era, literalmente, la situación que imaginamos en el tema 1: un programa a solas con el hardware.

El problema era económico. La máquina, carísima, pasaba la mayor parte del tiempo detenida: mientras un programador cargaba sus tarjetas, mientras pensaba dónde estaba el error, mientras el siguiente todavía no llegaba. Y si alguien terminaba antes de tiempo, el resto de su turno se perdía.

De esta etapa quedó una primera idea, anterior al sistema operativo: guardar en bibliotecas las rutinas que todos necesitaban, sobre todo las de entrada y salida, para no reescribirlas en cada programa.

4. Sistemas por lotes (1955–1965)

La solución fue sacar a las personas de la sala. Los programadores entregaban sus trabajos (en inglés, jobs) a un operador, que los agrupaba en un lote y los cargaba juntos en una cinta. En la memoria de la computadora quedaba instalado de forma permanente un pequeño programa, el monitor residente, que hacía una sola cosa: leer el siguiente trabajo de la cinta, cargarlo, cederle el control y, cuando terminaba, recuperarlo para pasar al siguiente sin intervención humana.

Ese monitor es el primer sistema operativo. El ejemplo más citado es GM-NAA I/O, escrito en 1956 por General Motors y North American Aviation para su computadora IBM 704. Con él aparecen dos conceptos que siguen vigentes:

También apareció la primera necesidad de protección. Si un trabajo con errores sobrescribía el monitor, o entraba en un bucle infinito, o leía por error las tarjetas del trabajo siguiente, el lote entero se perdía. La respuesta vino del hardware, que incorporó tres recursos que hoy damos por sentados: una zona de memoria que los programas no pueden tocar, un temporizador que interrumpe a un trabajo demasiado largo, e instrucciones reservadas al monitor. Son, respectivamente, la protección de memoria, las interrupciones de reloj y el modo kernel.

El costo para el programador

El sistema por lotes aprovechaba mucho mejor la máquina, pero empeoró la vida de quien programaba. Se entregaba el trabajo y el resultado volvía horas después, a veces al día siguiente. Un punto y coma olvidado costaba una jornada.

5. Multiprogramación (años sesenta)

El monitor por lotes eliminó los tiempos muertos entre trabajos, pero quedaba otro dentro de cada trabajo. Los dispositivos de entrada y salida son mecánicos y lentísimos comparados con la CPU: mientras se leía una cinta o se imprimía una línea, el procesador no tenía nada que hacer. En programas comerciales, que leen y escriben mucho, la CPU podía pasar ociosa la mayor parte del tiempo.

La multiprogramación consiste en mantener varios trabajos cargados en memoria a la vez. Cuando el que se está ejecutando necesita esperar a un dispositivo, el sistema operativo entrega la CPU a otro. Cuando el dispositivo termina, avisa con una interrupción y el primer trabajo vuelve a estar listo.

Uso de la CPU con un trabajo por vez frente a la multiprogramación con dos trabajos A y B Un trabajo por vez A espera E/S A B espera E/S B Multiprogramación A B A B ← terminan antes tiempo → los tramos grises son CPU ociosa
Mientras A espera a su dispositivo, la CPU ejecuta B. El mismo trabajo se completa en menos tiempo.

La idea es simple; sus consecuencias, enormes. Con varios programas en memoria al mismo tiempo, el sistema operativo tiene que resolver de golpe casi todos los problemas que hoy definen la materia:

El sistema emblemático de la etapa es OS/360 de IBM, anunciado en 1964. Su ambición era nueva: un único sistema operativo para toda una familia de computadoras, de la más pequeña a la más grande, de modo que un programa escrito para una funcionara en las demás. Resultó tan complejo que su desarrollo se convirtió en el caso de estudio fundacional de la ingeniería de software. Su descendiente MVS (1974) añadió memoria virtual, y esa línea continúa en los mainframes actuales.

6. Tiempo compartido (1961–1975)

La multiprogramación exprimía la máquina, pero el programador seguía esperando horas por su listado. A medida que el hardware se abarataba, ese tiempo humano perdido empezó a pesar más que el tiempo de máquina.

El tiempo compartido es una variante de la multiprogramación pensada para personas. Decenas de usuarios se conectan a la misma computadora, cada uno desde una terminal con teclado. El sistema operativo entrega la CPU a cada programa durante una fracción de segundo y pasa al siguiente, sin esperar a que el programa la ceda. Como una persona tarda mucho en escribir y leer, y la máquina es rápida, cada usuario tiene la impresión de disponer de una computadora para él solo. Es la primera aparición de la «ilusión de la máquina propia» del tema anterior.

El primer sistema de este tipo fue CTSS, presentado en el MIT en 1961. Con él cambió la forma de programar: se podía escribir, ejecutar, ver el error y corregir en minutos. También surgieron necesidades nuevas, porque por primera vez varias personas compartían una máquina al mismo tiempo: cuentas de usuario, contraseñas, archivos con dueño y permisos.

El éxito de CTSS dio origen a un proyecto mucho más ambicioso, Multics (1965), del MIT, General Electric y los Laboratorios Bell. Pretendía ser un servicio de cómputo continuo para toda una ciudad, como la red eléctrica. Tardó años, fue comercialmente modesto y aun así es uno de los sistemas más influyentes de la historia: introdujo el sistema de archivos jerárquico en forma de árbol, los anillos de protección y la idea de escribir el sistema en un lenguaje de alto nivel. Su mayor legado, sin embargo, fue involuntario.

7. Unix (1969)

En 1969 los Laboratorios Bell se retiraron de Multics. Dos de sus investigadores, Ken Thompson y Dennis Ritchie, se quedaron sin el entorno cómodo al que se habían acostumbrado y decidieron construirse uno, mucho más pequeño, sobre una minicomputadora PDP-7 que nadie usaba. Lo llamaron Unix, en un juego de palabras con Multics: donde aquel quería hacerlo todo, este haría pocas cosas y bien.

Unix importa en este curso más que ningún otro sistema, porque casi todo lo que estudiaremos sobre Linux viene de él. Sus decisiones de diseño:

Por razones legales, Bell no podía vender software y entregó Unix a las universidades con su código fuente. Una generación de estudiantes aprendió sistemas operativos leyéndolo y modificándolo. De ahí salieron dos grandes ramas: BSD, de la Universidad de California en Berkeley, que aportó entre otras cosas los sockets de red, y System V, la versión comercial. Sobre ellas se construyeron sistemas como SunOS para estaciones de trabajo y Xenix, el Unix de Microsoft.

Tantas variantes resultaron incompatibles entre sí, y en 1988 se publicó el estándar POSIX, que fija qué llamadas al sistema y qué comandos debe ofrecer un sistema «tipo Unix». Los programas en C de este curso usan esa interfaz; la vemos en el tema 15.

8. Computadoras personales (1975–1990)

El microprocesador hizo posible una computadora que una persona podía comprar. Pero esas primeras máquinas eran mínimas: unos pocos kilobytes de memoria, sin disco rígido y con un procesador que carecía de modo privilegiado y de protección de memoria.

Sus sistemas operativos fueron, en consecuencia, un retroceso de veinte años respecto de lo que ya existía en los equipos grandes. CP/M (1974) y MS-DOS (1981), el sistema de la IBM PC, ejecutaban un solo programa a la vez, para un solo usuario y sin ninguna protección: cualquier programa podía escribir en cualquier dirección de memoria, incluida la del propio sistema, y acceder al hardware directamente. Un error en una aplicación colgaba la máquina entera, y esa misma libertad es la que aprovecharon los primeros virus.

No fue una mala decisión de diseño, sino la única posible. Y deja una lección que repetiremos en todo el curso: lo que un sistema operativo puede garantizar depende de lo que el hardware le permite. Sin un procesador que distinga modo usuario de modo kernel, no hay forma de impedir que un programa haga lo que quiera.

A cambio, estos sistemas trajeron algo nuevo: un mercado de software. Como CP/M y MS-DOS ocultaban las diferencias entre equipos de distintos fabricantes, un mismo programa podía venderse para todos.

9. La interfaz gráfica

Hasta aquí, usar una computadora significaba escribir comandos. En el centro de investigación de Xerox en Palo Alto se desarrolló en 1973 una alternativa: la computadora Alto, con ventanas, iconos y un ratón. Apple llevó esas ideas al mercado con Lisa (1983) y, con éxito masivo, con el Macintosh (1984).

Para el sistema operativo, la interfaz gráfica significó un cambio en el objetivo: ya no se trataba de aprovechar la máquina, sino de responder de inmediato a una persona. El equipo pasa casi todo el tiempo esperando un clic, y cuando llega debe reaccionar al instante. Otros sistemas de la época avanzaron en esa dirección: AmigaOS (1985) ofreció multitarea real en una computadora hogareña, y NeXTSTEP (1989) combinó una base Unix con una interfaz gráfica avanzada.

En el tema 1 dijimos que el escritorio no es la parte esencial de un sistema operativo. La historia lo confirma: la interfaz gráfica llegó décadas después que el kernel, y se montó sobre él como una capa más.

10. Los sistemas modernos llegan a la PC (1985–2005)

En 1985 Intel presentó el procesador 80386, con modo protegido y memoria virtual. Por primera vez una PC tenía el hardware necesario para un sistema operativo como los de los equipos grandes. Faltaba escribirlo, y llegó por dos caminos.

El camino abierto: GNU y Linux

En 1983 Richard Stallman había iniciado el proyecto GNU para construir un sistema tipo Unix completo y libre. Hacia 1990 tenía casi todo —compilador, shell, utilidades— excepto el kernel. Por otro lado, Andrew Tanenbaum había escrito en 1987 MINIX, un Unix pequeño para enseñar sistemas operativos. En 1991 un estudiante finlandés, Linus Torvalds, que usaba MINIX en su 386, empezó a escribir su propio kernel y lo publicó en Internet. Ese kernel, Linux, se combinó con las herramientas de GNU para formar un sistema completo. Es la razón histórica de la distinción entre kernel y distribución que vimos en el tema 1, y de que el compilador que usarás se llame gcc.

El camino comercial: Windows NT

Microsoft, por su parte, encargó un sistema nuevo desde cero. Windows NT (1993) tenía todo lo que le faltaba a MS-DOS: modo kernel, protección de memoria, multitarea real y varios usuarios. Durante años convivió con la línea hogareña de Windows 95, que seguía apoyándose en MS-DOS para mantener la compatibilidad, hasta que Windows XP (2001) unificó ambas sobre el kernel de NT. Todas las versiones actuales de Windows descienden de él.

Apple recorrió un camino parecido: en 2001 reemplazó su sistema clásico por Mac OS X, construido sobre NeXTSTEP y, por lo tanto, sobre Unix.

Hacia 2005, los tres grandes sistemas de escritorio compartían ya los mismos fundamentos, heredados de los años sesenta y setenta. Son los que estudia este curso.

11. Móviles (1996–hoy)

Los primeros dispositivos de mano, como los que usaban Palm OS (1996), repitieron la historia de la PC: hardware limitado y sistemas simples, de una tarea por vez. Cuando los teléfonos tuvieron potencia suficiente, adoptaron directamente kernels de escritorio: iOS (2007) usa el mismo núcleo que macOS, y Android (2008) usa el kernel de Linux.

Lo nuevo no está en el kernel, sino en las restricciones que impone el dispositivo:

12. Multinúcleo, virtualización y nube (2005–hoy)

Alrededor de 2005 los procesadores dejaron de ganar velocidad y empezaron a multiplicar sus núcleos. Para el sistema operativo, eso convirtió en habitual algo que antes era raro: varios programas ejecutándose realmente al mismo tiempo, y no por turnos. La planificación y la sincronización, temas de los cursos 6 y 7, se volvieron bastante más delicadas.

Un servidor con decenas de núcleos, además, casi nunca se aprovecha con una sola carga de trabajo. La respuesta fue volver a una idea de los años sesenta. IBM había demostrado en 1967 que una computadora podía simular varias copias de sí misma, cada una con su propio sistema operativo. Esa técnica, la virtualización, renació en las PC con VMware (1999), Xen (2003) y KVM (2007), y es la base de la computación en la nube: cuando alquilas un servidor, recibes una máquina virtual que comparte el hardware con las de otros clientes.

Los contenedores, popularizados por Docker en 2013, llevan el reparto un paso más allá: en lugar de simular una máquina completa, aíslan grupos de procesos dentro de un mismo kernel de Linux, lo que resulta mucho más liviano.

Conviene notar la simetría. El tiempo compartido repartía una computadora cara entre muchas personas; la nube reparte un centro de datos caro entre muchos clientes. Es el mismo problema y la misma solución, la ilusión de la máquina propia, aplicados una capa más arriba. Los estudiamos en el curso 13 de esta ruta.

13. Patrones que se repiten

Más que las fechas, de este recorrido conviene retener cuatro regularidades, porque ayudan a entender lo que viene y también lo que todavía no existe.

  1. Cambia lo que es caro, y con ello el objetivo. Cuando lo caro era la máquina, el sistema operativo buscaba no desperdiciarla. Cuando lo caro pasó a ser el tiempo de las personas, buscó responder rápido. En un teléfono lo escaso es la batería; en la nube, el costo por cliente.
  2. Cada nueva clase de equipo recorre la historia otra vez. Los mainframes, las minicomputadoras, las PC y los teléfonos empezaron todos con sistemas de un solo programa y sin protección, y fueron incorporando multiprogramación, protección y memoria virtual a medida que su hardware lo permitió. Los microcontroladores actuales están en plena transición.
  3. El hardware habilita; el sistema operativo aprovecha. Las interrupciones hicieron posible la multiprogramación; el temporizador, el tiempo compartido; el modo privilegiado y la unidad de gestión de memoria, la protección. Por eso el bloque 2 de este curso empieza por el hardware.
  4. Las ideas sobreviven a los sistemas. Multics casi no se usó, pero sus ideas viven en Unix; Unix apenas se vende hoy, pero su diseño vive en Linux, Android, macOS e iOS. Estudiar los conceptos rinde más que estudiar un producto.

14. Fósiles en tu terminal

La historia no quedó en los libros: una terminal Linux está llena de restos de cada etapa. Algunos se pueden desenterrar con un comando.

terminal
$ tty                            # ¿a qué terminal estoy conectado?
/dev/pts/0

$ date -u -d @0                  # el instante cero de Unix
jue 01 ene 1970 00:00:00 UTC

$ date +%s                       # segundos transcurridos desde entonces
1791725527

$ who | wc -l                    # una tubería, como en 1973
1

$ ls /var/spool                  # colas de trabajos pendientes
cron  mail  rsyslog

El segundo y el tercer comando muestran una herencia directa de Unix: el kernel no guarda la fecha como día, mes y año, sino como la cantidad de segundos transcurridos desde el 1 de enero de 1970, un instante llamado epoch. Cualquier programa puede pedírsela:

epoch.c
#include <stdio.h>
#include <time.h>

int main(void)
{
    time_t ahora = time(NULL);   /* le pregunta la hora al kernel */

    printf("Segundos desde el 1 de enero de 1970: %ld\n", (long)ahora);
    printf("Equivale a unos %ld anios\n", (long)(ahora / (365.25 * 24 * 3600)));
    return 0;
}
terminal
$ gcc epoch.c -o epoch
$ ./epoch
Segundos desde el 1 de enero de 1970: 1791725527
Equivale a unos 56 anios

Otros fósiles están en el vocabulario que usarás a diario:

Lo que ves hoyDe dónde viene
tty, /dev/ttyDe teletype: los teletipos, máquinas de escribir eléctricas que servían de terminal en el tiempo compartido.
job, el comando jobsLos «trabajos» que se entregaban al operador en los sistemas por lotes.
/var/spool, «cola de impresión»La técnica de spooling de los años sesenta: dejar la salida en disco para enviarla después a un dispositivo lento.
«core dumped»La memoria de núcleos magnéticos (core) de los años cincuenta y sesenta. Volcar el «core» era copiar la memoria para examinarla.
tarTape archive: se creó para guardar archivos en cinta magnética.
Terminales de 80 columnasEl ancho de una tarjeta perforada de IBM.
La unidad C: en WindowsEn CP/M y MS-DOS, A: y B: eran las dos disqueteras; el disco rígido llegó después.

15. Qué nos dejó cada etapa

Esta tabla resume el tema y sirve de índice: indica en qué momento nació cada concepto y dónde lo estudiamos.

ConceptoNace conLo estudiamos en
Programa residente que controla a los demás (kernel)Sistemas por lotesTema 11
Modo privilegiado e instrucciones reservadasSistemas por lotesTema 12
Llamadas al sistemaSistemas por lotesTema 13
Interrupciones de dispositivosMultiprogramaciónTema 17
Temporizador y reparto de la CPU por turnosTiempo compartidoTema 19
Proceso, planificaciónMultiprogramaciónTema 26
Protección de memoria, memoria virtualMultiprogramaciónTema 27
Árbol de directorios, «todo es un archivo»Multics y UnixTema 28
Usuarios, contraseñas y permisosTiempo compartidoTema 30
Shell como programa de usuario, tuberíasUnixTema 32
Estándar POSIXLa diversidad de variantes de UnixTema 15

16. Resumen

17. Preguntas de repaso

Intenta responder cada una antes de abrir la respuesta.

1. ¿Qué problema resolvieron los sistemas por lotes y cuál crearon?

Resolvieron el tiempo muerto entre un programa y el siguiente, al encadenar los trabajos automáticamente. A cambio, el programador perdió el contacto con la máquina y pasó a esperar horas por cada resultado.

2. ¿En qué se diferencian la multiprogramación y el tiempo compartido?

Ambos mantienen varios programas en memoria. En la multiprogramación clásica se cambia de programa cuando el actual debe esperar a un dispositivo; el objetivo es aprovechar la CPU. En el tiempo compartido, además, el sistema quita la CPU cada fracción de segundo aunque el programa no la ceda; el objetivo es que cada usuario reciba respuesta rápida.

3. ¿Por qué fue tan importante que Unix se reescribiera en C?

Porque lo hizo portable. Un sistema escrito en ensamblador solo sirve para un procesador; uno escrito en C puede recompilarse para otro con pocos cambios. Eso permitió que Unix se extendiera a máquinas muy distintas y sobreviviera a todas ellas.

4. MS-DOS apareció quince años después de que existieran sistemas con protección de memoria. ¿Por qué no la tenía?

Porque el procesador de la primera IBM PC no distinguía entre modo usuario y modo kernel ni podía restringir el acceso a la memoria. Sin ese apoyo del hardware, el sistema operativo no tiene manera de impedir que un programa haga lo que quiera.

5. ¿Qué relación hay entre GNU, MINIX y Linux?

GNU aportó las herramientas de un sistema tipo Unix libre (compilador, shell, utilidades), pero no tenía kernel. MINIX fue el sistema de enseñanza que Torvalds usaba y que lo motivó a escribir el suyo. Linux es ese kernel, que combinado con las herramientas de GNU forma un sistema completo.

6. ¿En qué se parecen el tiempo compartido de los años sesenta y la nube actual?

En ambos se reparte un recurso caro entre muchos usuarios, dando a cada uno la ilusión de tenerlo para sí. Antes era una computadora compartida mediante procesos; ahora es un centro de datos compartido mediante máquinas virtuales y contenedores.

7. ¿Qué recurso nuevo debe administrar el sistema operativo de un teléfono que casi no importaba en una PC de escritorio?

La energía. La batería es limitada, de modo que el sistema decide qué aplicaciones pueden seguir ejecutándose y cuáles se suspenden, igual que decide sobre la CPU o la memoria.

Para practicar

  1. Ordena de memoria estas ideas según su aparición y explica qué problema resolvió cada una: tiempo compartido, monitor residente, contenedores, multiprogramación, interfaz gráfica.
  2. Elige uno de los veinte sistemas del curso Historia de los Sistemas Operativos, léelo e identifica a cuál de las etapas de este tema pertenece y qué concepto aportó.
  3. Cuando tengas Linux disponible, ejecuta los comandos de la sección 14 y calcula a mano, a partir de date +%s, cuántos días pasaron desde 1970.
  4. Piensa en un dispositivo reciente (un reloj inteligente, un televisor, un automóvil): ¿en qué etapa de la evolución está su sistema operativo? ¿Tiene multitarea, protección entre aplicaciones, varios usuarios?