Algoritmos y Estructuras de Datos Herramientas Lenguaje de programación
!Prog C/C++ Rust
Linux Matemáticas
Mates Discretas
Programación Orientada a Objetos Sistemas Operativos

Introducción

[date: 26-12-2023 13:03] [last modification: 11-01-2024 16:52]
[words: 3299] [reading time: 16min] [size: 34656 bytes]

El Sistema Operativo es el software encargado de gestionar los recursos del ordenador y de proporcional una interfaz amigable para su uso. Probablemente sea el software más importante que se ejecuta, dado que da soporte al resto de programas. En este artículo, se comentará brevemente los retos a los que se debe enfrentar.

El Sistema Operativo

El sistema operativo es el software encargado de gestionar los recursos hardware del computador y de proporcionar una interfaz amigable para su uso.

Escribir código para gestionar el disco duro, la memoria, el teclado, el ratón… es una tarea sumamente complicada, y sería muy difícil para un programador realizar una aplicación. Gracias al Sistema Operativo, el programador puede utilizar los recursos que proporciona para construir más fácilmente sus aplicaciones.

Responsabilidades del Sistema Operativo:

El Sistema Operativo se ejecuta directamente sobre el hardware y proporciona la base para las demás aplicaciones. Siempre debe estar disponible en memoria: su código y los datos que necesite para funcionar.

Nota
Nótese que realmente los clientes del Sistema Operativo son los programas que se quieren ejecutar, dado que los usuarios finales utilizan el Shell o la GUI (Graphical User Interface), nunca usan las funcionalidades del sistema directamente.

Tipos de Sistemas Operativos

Ordenados por tamaño:

Modos de ejecución

Figura representando las capas de un ordenador

Capas software de un ordenador

En relación al diagrama:

Traps

Se trata de cualquier salto a una subrutina del Sistema Operativo, es decir, se pasa de modo usuario a modo kernel. Cuando se ha completado dicha subrutina, se regresa a donde estaba en modo usuario. Algunos ejemplos de traps son:

Llamadas al sistema (syscalls)

Los Sistemas Operativos tenían dos funciones: gestionar los recursos hardware, que se hace de forma automática; y proveer un uso simplicado del mismo, para lo que se utilizan las llamadas al sistema.

Existen tres posibles definiciones:

  1. Intrucción en código máquina que ejecuta un procedimiento del kernel.
  2. Función de alto nivel (función en C) que contiene una llamada al sistema (1).
  3. Comando que hace uso de las llamadas al sistema (2).

Estas varían de un sistema a otro: nosotros utilizaremos POSIX (Portable Operating System Interface), el estándar internacional 9945-1 por IEEE, por tanto Unix, Linux, BSD, etc.; y el resto de sistemas tiene llamadas que realizan las mismas funciones.

Ejemplo:

1size_t read(int fd, void buf[.count], size_t count);

Nociones sobre hardware

Como el sistema operativo trabaja directamente sobre el hardware, es necesario comprender con detalle como este funciona.

Conceptualmente, una computadora simple se puede representar con la figura siguiente. Como es de esperar, hoy en día tienen una estructura mucho más compleja, pero esta representación nos servirá.

Procesador

Obtiene y ejecuta instrucciones máquina. Cada procesador tiene un conjunto específico de instrucciones (ISA) que puede ejecutar. Lógicamente, si dos procesadores no comparten estas intrucciones, no se podrá ejecutar el mismo programa en los dos.

Consta de varias partes:

Se accede a los registro de forma explícita: es el programador (realmente el compilador) quien decide qué registros usar, esa información va codificada en la propia instrucción. El resto de la memoria no se gestiona por el programador:

Tamaño de palabra

El tamaño de la palabra es el tamaño de los registros. Además, define:

  • Define el rango de memoria direccionable
  • Define el número de operandos de las instrucciones: hay bits limitados

Con el fin de mejorar el rendimiento de los procesadores, se implementan varias técnicas:

Jerarquía de memoria

El segundo componente más importante en un ordenador es la memoria. Idealmente, esta debe ser más rápida que el procesador, para que no haya cuello de botella. Además, debe ser grande y barata. Sin embargo, en la actualidad no existe la tecnología que cumpla todos estos requisitos.

Como solución, se ideó el concepto de jerarquía de memoria. Las capas superiores son memorias más pequeñas y rápidas (y caras), mientras que las de abajo son mucho más lentas pero permiten almacenar muchos datos.

Adicionalmente: ROM (rápida y económica, solo lectura)

Disco duro

Dos órdenes de magnitud más barato por bit, pero tres órdenes de magnitud más lento en el acceso de forma aleatoria.

Bus

Permite la comunicación entre dispositivos. Para obtener un buen rendimiento, si dicho dispositivo es rápido, el bus también debe serlo: de lo contrario hará cuello de botella.

Sin embargo, a medida que los sistemas mejoraban, tener un solo bus para manejar todo el tráfico era ineficiente. Por eso, los ordenadores actuales incluyen múltiples buses.


Entrada/Salida

La gestión de dispositivos de Entrada/Salida es posiblemente una de las cosas más complejas de las que se debe encargar el Sistema Operativo.

Formas de comprobar que la operación se ha realizado:

Controladoras (device controllers)

Se trata de hardware específico que controla un dispositivo de E/S. Es una electrónica muy sencilla: consta de registros y buffers en los que escribe la CPU para realizar una operación. Resultan particularmente útiles para el sistema operativo porque abstraen la complejidad específica del dispositivo.

Por ejemplo, se escribe en los registros de la controladora que se quiere leer determinado bloque en el disco. Con esta información, la controladora determina cuánto se debe mover el peine del disco para situarlo en la posición deseada y poder leer el dato. Esto resulta complicado porque las pistas exteriores tienen más sectores, dependiendo de donde esté el brazo del peine se debería mover hacia dentro o hacia afuera, etc.

Controladores (drivers)

Software que utiliza el Sistema operativo para comunicarse con el dispositivo. Simplemente lee y escribe datos en buffers específicos para realizar acciones sobre el mismo. Para ello utiliza instrucciones especiales para acceder, dado que la memoria no es la RAM. Y para hacer uso de dichas intrucciones, el driver se debe ejecutar el modo kernel. En otros casos, se relaciona una dirección de memoria virtual con un dispositivo de Entrada/Salida, como si fuese leer/escribir en la memoria RAM.

Para realizar conseguir añadir un driver al modo kernel, exiten tres formas:

Conceptos básicos de un Sistema Operativo

Proceso

Nota
Para más información consultar el artículo dedicado a procesos

Un programa es un fichero ejecutable/binario que se encuentra en el disco y contiene instrucciones máquina. Cuando este programa se quiere ejecutar, se debe cargar el memoria principal.

Un proceso, en cambio, es en esencia un programa en ejecución. Este tiene asociado un espacio de direcciones de cierto rango (0 hasta 0xFF…F, por ejemplo) donde el proceso puede leer y escribir información. Solo puede estar en un único core (se puede cambiar de core, pero nunca más de uno a la vez).

Los sistemas actuales son multiprogramados, por tanto se deben suspender y reaunudar los procesos. Eso implica guardar toda la información relacionada (estado de los registros, archivos abiertos, etc) y recuperarla cuando se reaunude (cambio de contexto). Todo esto se almacena en la tabla de procesos.

Existen las jerarquías de procesos: los procesos hijo son aquellos que ha creado un proceso padre, por lo que se pueden organizar en una estructura de árbol. Los procesos relacionados cooperan y se comunican.

Por otro lado, cada usuario recibe un código de identificación (UID), al igual al grupo al que pertenece (GID). Cada proceso recibe el UID de la persona que lo inició. El superusuario o administrador es un UID especial que puede saltarse las reglas de protección

Espacio de direcciones

Nota
Para más información consultar el artículo dedicado a memoria

Si solo se desea ejecutar un único programa a la vez, simplemente se puede cargar en memoria principal y ejecutarlo directamente. Si se quiere ejecutar un segundo, primero se debe retirar el primero y posterioremente cargar el deseado.

Sin embargo, en los sistemas multiprogramados, esta estrategia no es válida. Para evitar que diferentes procesos interfieran unos con otros se necesita cierto mecanismo de protección.

Una técnica posible es designar a cada proceso un espacio de direcciones virtual, que consiste en abstraer el conjunto de direcciones a las que puede acceder el proceso. De esta forma, la memoria que usa el proceso se desacopla de la memoria física (en caso de que hayan partes que no quepan se almacenan en la zona de swapping del disco), pudiendo tener varios procesos al mismo tiempo, incluso con una memoria física mucho menor.

Archivo

Nota
Para más información consultar el artículo dedicado a archivos

Esta es otra de las grandes abstracciones del sistema operativo. Gracias a llamadas al sistema se pueden crear, eliminar o escribir archivos; lo que implica que toda operación relacionada con archivos debe pasar a través de un proceso.

También existe el concepto de directorio (carpetas) para agruparlos y simplificar su manejo. Los directorios pueden contener otros directorios, por lo que al igual que los procesos, se forma una jerarquía en forma de árbol (las jerarquías de archivos suelen ser más profundas que las jerarquías de procesos). El nodo raíz, la parte superior de la jerarquía de archivos se denomina directorio raíz. En cada instante, un proceso tiene un directorio de trabajo actual.

Para especificar un archivo o ruta dentro de la jerarquía, se indica el nombre de cada directorio hasta llegar al archivo más un separador: / en Unix y \ en MSDOS/Windows.

Existen dos tipos de rutas:

Otro concepto importante en Unix son las monturas. Inicialmente, para acceder a los archivos de un DVD/USB/etc, no se dispone de ninguna ruta para referirse a ellos: se debe hacer uso de la llamada del sistema mount. Esta toma el sistema de archivos indicado y lo monta sobre un directorio ya existente en el sistema de archivos.

Finalmente, existen algunos archivos especiales:

De esta forma, se modelan operaciones de Entrada/Salida o Comunicación como si fuese escribir o leer de un archivo.

Importante
Sin embargo, nada de esto existen para el computador, dado que como ya se ha comentado, el disco se divide en sectores: no sabe qué es eso de un archivo.

Shell

El Sistema Operativo es quien ejecuta las llamadas al sistema. Los editores, compiladores, ensambladores, intérpretes, etc. no forman parte de él, pero aun así son importantes y útiles. El shell, el intérprete de comandos de Unix, tampoco forma parte del sistema, pero utiliza con frecuencia muchas características del mismo y sirve como ejemplo para utilizar las llamadas al sistema.

El intérprete de comandos es la interfaz principal entre un usuario y el Sistema Operativo (salvo casos donde el usuario use la GUI). Existen muchos tipos de shell distintos: sh, csh, bash, fish, etc.

A continuación aparece una versión simplificada del shell. Nótese que se usa escritura en pantalla, lectura de teclado, creación de procesos (fork), esperar por un proceso hijo (waitpid) y ejecutar un archivo (execve).

 1while (1) {
 2    type_prompt();                     // Mostrar el prompt
 3    read_command(command, parameters); // Lee la entrada de terminal
 4
 5    if (fork() != 0) {
 6        // Código del padre: esperar por el hijo
 7        waitpid(-1, &status, 0);
 8    } else {
 9        // Código del hijo: ejecutar el comando
10        execve(command, parameters, 0);
11    }
12}

Historia

Volver a Sistemas Operativos Siguiente: Arranque y Proceso Hardware