Una computadora sin software no presta ninguna utilidad. El software
puede clasificarse en dos grandes grupos:
En un sistema de computación se reconocen los siguientes niveles, yendo desde el usuario hacia la máquina física:
Microprogramación: control directo de dispositivos. En memoria de sólo lectura, o a veces en el propio hardware; interpreta el lenguaje de máquina.
Dispositivos físicos: chips, barras, cables, fuentes de potencia, conectores, etc.
El sistema operativo ejecuta en modo superusuario, con plenos poderes; no puede ser alterado por el usuario. Los compiladores y editores se ejecutan en modo usuario, con poderes limitados. Cada usuario podría escribir su propio editor, compilador u otro utilitario. Los programas de aplicación son escritos por los usuarios para resolver problemas particulares.
Como controlador de recursos. Permite la asignación ordenada de procesadores, memoria y dispositivos de entrada/salida para los varios programas que compiten por el uso de estos recursos.
Segunda generación (1955-1965): transistores y sistemas de procesamiento por lotes. Los programas y datos se entregaban en tarjetas, se acumulaban y luego eran procesados todos juntos por la máquina, buscando minimizar los tiempos muertos.
Tercera generación (1965-1980): circuitos integrados y multiprogramación. El sistema 360 de IBM unifica computadoras comerciales y científicas en una sola línea de máquinas con software compatible. Se introduce la multiprogramación, que divide la memoria en partes y ejecuta un programa distinto en cada una. El spooling permite la operación simultánea y en línea de periféricos. El tiempo compartido es una variante de multiprogramación que habilita a cada usuario una terminal en línea. MULTICS, un gigantesco sistema operativo, fracasa en su construcción pero aporta muchas ideas que hacen surgir UNIX.
Cuarta generación (1980-1990): estaciones de trabajo y computadoras personales. Sistemas operativos DOS y UNIX. Software "amigable con el usuario". Sistemas operativos de red, con varias computadoras interconectadas que pueden ser accedidas por un mismo usuario. Sistemas operativos distribuídos, compuestos por varios procesadores que se presentan al usuario como un sistema único.
Cada usuario tiene asignado un identificador de usuario (uid), y grupos de usuarios tienen un identificador de grupo (gid). Un proceso tiene asignado el uid y gid del usuario que lo inició. Ambos identificadores se utilizan para proteger la información manejada por el proceso.
En un sistema multiusuario, es preciso dar privacidad a los archivos de cada persona. UNIX utiliza un código de 9 bits en 3 grupos de 3 bits. Estos grupos correspondientes al dueño, el grupo y el resto del mundo. Cada conjunto de 3 bits corresponde a permiso de lectura, escritura y ejecución. Se presentan como rwx (Read, Write, eXecute); cuando uno de estos permisos está denegado se sustituye la letra por -, como en r-- o en rw-.
Para acceder a un archivo, se verifican primero sus permisos; si son correctos, el sistema devuelve un descriptor de archivo o "entrada de manejo", un número entero que se utiliza en todas las operaciones subsiguientes. Al cerrarse el archivo, el descriptor es desasignado y el número entero queda disponible para otro acceso.
UNIX maneja los dispositivos de entrada y salida con un artificio que los presenta como archivos especiales, lo que permite escribir y leer en ellos con las mismas llamadas al sistema que se usan para los archivos. Los archivos especiales de bloque se usan para dispositivos que organizan los datos en bloques de tamaño fijo y acceso aleatorio, como los discos. Los archivos especiales de caracteres modelan los dispositivos formados con flujos de caracteres como las terminales, impresoras e interfaces de red.
En UNIX y DOS, al iniciar un proceso se establece el descriptor de archivo 0 como entrada estándar para recibir datos desde el teclado y el descriptor de archivo 1 como salida estándar para presentar información en la pantalla. El descriptor de archivo 2 es el de error estándar; se usa para mensajes de error y se asigna normalmente a la pantalla.
La interconexión de procesos se realiza a través de una tubería, entubamiento, tubo o secuencia de comandos, indicado por el caracter | (barra vertical). Un tubo es un seudoarchivo en el cual un primer proceso escribe su salida para ser leída por un segundo proceso; la salida del primero es la entrada del segundo.