Descargar

Sistemas Informáticos

Enviado por banfieldcritico


    1. Introducción a los sistemas informáticos. Repaso de arquitectura de computadores
    2. Conceptos fundamentales sobre sistemas operativos
    3. Procesos
    4. Concurrencia: exclusión mutua y sincronización
    5. Concurrencia. Interbloqueo (Deadlock) e inanición (Starvation)
    6. Gestión de memoria
    7. Memoria virtual
    8. Planificación de monoprocesadores
    9. Planificación de multiprocesadores
    10. Gestión de e/s. Planificación de discos
    11. Gestión de archivos
    12. File system en Unix. I-nodos
    13. Redes y proceso distribuido

    CAPITULO 1: INTRODUCCIÓN A LOS SISTEMAS INFORMÁTICOS

    REPASO DE ARQUITECTURA DE COMPUTADORES

    1.1. Elementos básicos

    En un alto nivel, un sistema informático consta:

    1. Procesador
    2. Memoria
    3. Módulos de E/S
    4. Interconexión de sistemas: mecanismos y estructuras que permiten la comunicación entre procesadores, memoria principal y los módulos de E/S.

    El procesador es normalmente quien lleva el control. Una de sus funciones es intercambiar los datos con la memoria. Para este propósito, hace uso de dos registros internos:

    MAR: Memory Adress Register. Especifica la dirección en memoria de la próxima lectura o escritura.

    MBR / MDR: Memory Buffer/Data Register. Contiene los datos que van a ser escritos a memoria o que fueron leídos desde ella.

    IOAR: Input Output Adress Register. Especifica un dispositivo particular de E/S.

    IOBR: Input Output Buffer Register. Permite intercambiar datos entre un módulo de E/S y el procesador.

    1.2. Conceptos varios

    Definiciones varias

    Byte: equivale a un término binario (Binary termin) generalmente compuesto por 8 bits.

    Carácter: es el conjunto de bits necesarios para representar un símbolo de un código (alfabético, numérico, especial, etc.)

    Palabra: es una unidad lógica de información. Generalmente está compuesto por un número entero de bytes o caracteres.

    Frecuencia / Período

    El tiempo de transmisión de estados o tiempos de cada ciclo de un computador es el tiempo que se requiere para modificar los valores de un conjunto de registros y está determinado por la frecuencia del reloj. El período se calcula como la inversa de la frecuencia:

    Período * Frecuencia = 1

    [ Período ] = s (segundo)

    [ Frecuencia ] = Hz (Hertz).

    Equivalencia de unidades

    1 KB (kilobyte) = 210 bytes = 1024 bytes

    1 MB (megabyte) = 220 bytes = 1024 KB

    1 GB (gigabyte) = 230 bytes = 1024 MB

    1 TB (terabyte) = 240 bytes = 1024 GB

    1 ms (milisegundo) = 10-3 segundos

    1 m s (microsegundo) = 10-6 segundos

    1 ns (nanosegundo) = 10-9 segundos

    1 ps (picosegundo) = 10-12 segundos

    1.3. Registros del procesador

    Dentro del procesador, hay un conjunto de registros que ofrecen un nivel de memoria que es más rápido y pequeño que la memoria principal. Los registros del procesador sirven para dos funciones:

    1. Registros visibles del usuario (o Registros para el programador de sistemas)
    2. Registros de control y de estado (o Registros para el programador de sistemas)

    1.4. Ejecución de instrucciones

    Un ciclo para la ejecución de instrucciones posee cuatro etapas:

    1. Búsqueda de la instrucción (BI) (fase fetch)
    2. Decodificación (D)
    3. Búsqueda de operandos (BO)
    4. Ejecución (E)

    Los microprocesadores de INTEL trabajan con un sistema llamado Cascada o Pipeline que consiste en poder trabajar con cuatro instrucciones en forma simultánea. Cuando se ejecuta una serie de instrucciones al ritmo de los impulsos de un reloj, con el primero de dichos impulsos se realiza la BI de la primera instrucción (11). Con el segundo impulso, 11 pasa a la fase D y 12 pasa a BI. Y así sucesivamente.

    Ejemplo de ejecución de instrucciones

    A continuación veremos la ejecución de instrucciones de un fragmento de programa que suma el contenido de la dirección 940 al contenido de la dirección 941 y almacena el resultado en esta última dirección.

    Conociendo el siguiente mapeo de memoria:

    1. 1940
    2. 5941
    3. 2941

    …… …….

    1. 0003
    2. 0002

    Conociendo los siguientes códigos de operación (que serán cargados en el Registro de Instrucciones IR) :

    0001 : Cargar de la memoria al AX

    0010 : Almacenar el AX en memoria

    0101 : Sumar al AX el contenido de la memoria

    Y sabiendo que IP = 0300. Entonces la secuencia de ejecución de las instrucciones es la siguiente:

    1. Se carga el contenido de la ubicación 300 en el IR. ( IR = 1940 )

      O sea, el valor que está en 940 se carga en AX. ( AX = 3 )

    2. Los primeros 4 bits del IR indican la operación a realizar (Código de operación 0001 – Cargar de memoria al AX). Los 12 bits restantes indican la dirección de memoria.
    3. Se incrementa el IP y se lee la instrucción siguiente. ( IP = 0301 )
    4. Se carga el contenido de la ubicación 301 en el IR. ( IR = 5941 )

      O sea, al valor de AX se le suma el que está en 941. ( AX = 5 )

    5. Los primeros 4 bits del IR indican la operación a realizar (Código de operación 0101 – Sumar al AX el contenido de la memoria). Los 12 bits restantes indican la dirección de memoria.
    6. Se incrementa el IP y se lee la instrucción siguiente. ( IP = 0302 )
    7. Los primeros 4 bits del IR indican la operación a realizar (Código de operación 0010 – Almacenar el AX en memoria). Los 12 bits restantes indican la dirección de memoria.

    O sea, el valor de AX se carga en la dirección 941. ( [941] = 0005)

    El registro IP (Instruction Pointer) también puede ser llamado PC (Program Counter).

    1.5. Interrupciones

    Existen cuatro clases de interrupciones:

    1. De programa: generadas por alguna condición que se produce como resultado de la ejecución de una instrucción, como el desbordamiento aritmético, división por cero o una referencia a un espacio de memoria no accesible al usuario.
    2. De reloj: generadas por un reloj interno del procesador. Permite al S.O. llevar a cabo ciertas funciones con determinada regularidad.
    3. De E/S: generadas por un controlador de E/S para indicar que una operación ha terminado normalmente o para indicar diversas condiciones de error.
    4. Por fallo del hardware: generadas por fallos tales como un corte de energía o un error de paridad de la memoria.

    Tratamiento de Interrupciones

    El acontecimiento de una interrupción desencadena una serie de sucesos, tanto en el HW del procesador como en el SW. Cuando un dispositivo de E/S completa una operación de E/S, se produce en el HW la siguiente secuencia de sucesos (aunque deberá tenerse en cuenta si la interrupción es enmascarable, no enmascarable o una excepción):

    1. El dispositivo emite una señal de interrupción al procesador.
    2. El procesador finaliza la ejecución de la instrucción en curso.
    3. El procesador pregunta por la interrupción, comprueba que ésta existe y envía una señal de reconocimiento al dispositivo que generó dicha interrupción.
    4. El procesador se prepara para transferir el control a la rutina de interrupción. Para ello, salva la información necesaria para reanudar la ejecución del programa en curso en el punto de la interrupción.
    5. El procesador carga en el contador de programa la ubicación de entrada del programa de tratamiento de la interrupción.
    6. Se transfiere el control a la rutina que tratará la interrupción. Dicha rutina procederá a procesar la interrupción.
    7. Cuando se completa la ejecución de la rutina de interrupción, se recuperan de la pila los valores de los registros que se salvaron y se restauran los registros. Luego, se continúa con la normal ejecución del programa.

    1.6. Sistemas de transmisión de datos

    Clasificación de las transferencias de datos

    1. Monodireccional o Simplex: se efectúa en un solo sentido.
    2. Bidireccional Duplex o Full Duplex: se efectúa en ambos sentidos al mismo tiempo.
    3. Bidireccional Half Duplex: se efectúa en ambos sentidos, pero no al mismo tiempo.

    Operaciones en una transferencia de datos

    1. Codificación: vuelco de la información al código apropiado para transmisión.
    2. Emisión: se envía a la línea de comunicación los impulsos correspondientes a las señales preparadas y codificadas por el elemento transmisor.
    3. Registración: memorización de los impulsos recibidos.
    4. Traducción o Descodificación: la inversa de la codificación.

    Velocidades de transmisión

    Las velocidades en la transmisión se miden en Baudios. En algunos casos, esta unidad coincide con los bits que se envían en la unidad de tiempo, pero generalmente incluye la información de control.

    Sistemas de transmisión

    Los sistemas de transmisión pueden ser sincrónicos (los bits se transmiten a un ritmo determinado por un reloj) o asincrónicos (no tiene ritmo determinado). La transmisión de bits puede hacerse en paralelo o en serie.

    Con respecto a la alimentación de los sistemas de transmisión, ésta puede realizarse de las siguientes formas:

    1. Corriente continua simple: la corriente se transmite en un solo sentido. Los estados se representan con emisión / reposo.
    2. Corriente continua doble: los estados son representados con el sentido en que circula la corriente.
    3. Corriente alternada: la corriente invierte el sentido tantas veces como sea su frecuencia en un segundo.

    1.7. Jerarquía de memoria

    Las limitaciones de diseño de la memoria de un computador se resumen en tres conceptos: capacidad, coste y velocidad.

    El dilema que se plantea el diseñador es evidente. El diseñador desearía usar tecnologías de memoria que le ofrezcan una gran capacidad (buscando que el coste por bit sea bajo). Sin embargo, para cumplir con los requisitos de rendimiento puede necesitar una memoria cara, de capacidad relativamente menor y con tiempos de acceso rápidos.

    La salida a este dilema es emplear una jerarquía de memoria. A medida que se desciende por la jerarquía se tienen las siguientes condiciones:

    1. Disminución del coste por bit
    2. Aumento de la capacidad
    3. Aumento del tiempo de acceso
    4. Disminución de la frecuencia de acceso a la memoria por parte del procesador

    Jerarquía tradicional de memoria

    Registros

    Memoria caché

    Memoria principal

    Disco magnético

    Cinta magnética

    Jerarquía moderna de memoria

    Registros

    Memoria caché

    Memoria principal

    Caché de disco

    Disco magnético

    Cinta magnética y Disco óptico

    Mencionamos como uno de los niveles a la caché de disco. Ésta es una parte de la memoria principal que se utiliza como un buffer para guardar temporalmente los datos transferidos con el disco. La caché de disco mejora el rendimiento de dos formas:

    • Las escrituras a disco se agrupan. En lugar de muchas transferencias pequeñas de datos, se tienen unas pocas transferencias grandes de datos. Esto mejora el rendimiento del disco y reduce la utilización del procesador.
    • Algunos datos destinados a la salida pueden ser referenciados por un programa antes del próximo volcado a disco.

    Se pueden incluir otras formas de memoria en la jerarquía. Por ejemplo, los grandes computadores centrales (mainframe) de IBM incluyen una forma de memoria conocida como memoria expandida. Realmente, esta tecnología no pertenece a la jerarquía de memoria sino que constituye una rama paralela.

    1.8. Memoria caché

    La memoria caché intenta obtener una velocidad cercana a la de las memorias más rápidas y, al mismo tiempo, aportar una memoria grande al precio de las memorias de semiconductores, que son menos costosas.

    Hay una memoria principal más lenta y relativamente grande, junto a una memoria caché más pequeña y rápida. La caché contiene una copia de parte de la memoria principal.

    El diseño de una memoria caché debe abordar algunas cuestiones:

    • Tipo de conexión de la memoria caché con respecto a la memoria principal. Pueden encontrarse en serie o en paralelo.
    • Tamaño de caché. Cuanto mayor sea el tamaño de la caché, mayor será la probabilidad de presencia, pero almacenar gran cantidad de códigos y datos que no están próximos a los referenciados recientemente no mejoras el rendimiento, ya que sale fuera del entorno de vecindad y no es probable que sean requeridos. El tamaño ideal de una memoria caché es de 4 a 256 KB.
    • Tamaño del bloque. Un bloque es la unidad de intercambio de datos entre la caché y la MP. A medida que el tamaño del bloque crece, pasan a la caché más datos útiles; sin embargo, la tasa de aciertos comenzará a bajar.
    • Algoritmos de anticipación. Caching. La caché se actualiza desde la RAM utilizando los principios de:
      • Vecindad espacial: los programas solicitan datos o instrucciones ubicados en posiciones de memoria cercanas a los datos o instrucciones últimos direccionados. Suele cumplirse debido a que los programas se escriben y ejecutan en forma secuencial.
      • Vecindad temporal: los programas tienden a usar los datos más reciente. Cuanto más antigua es la información, más improbable es que se la solicite.
    • Algoritmos de reemplazo. Cuando se produce ausencia en la caché y debe actualizarse ésta, surge el problema de qué posición de la caché sustituir. Para ello se utilizan algunos algoritmos, siendo los más usados RANDOM, FIFO y LRU.
    • Políticas de escritura y actualización de la memoria principal. Existen tres métodos:
      • Escritura inmediata (Write Through): se actualiza la memoria caché y la memoria principal al mismo tiempo.
      • Escritura diferida (Post Write Through): la caché incorpora algunos registros. Las escrituras en caché se envían a estos registros, liberando el procesador. La memoria principal va siendo actualizada desde los registros.
      • Escritura obligada (Write Back): las escrituras se realizan en la memoria caché y sólo se hacen en memoria principal si resulta estrictamente necesario.

    1.9. Técnicas de comunicación de E/S

    Entrada / Salida Programada

    Cuando el procesador está ejecutando un programa y encuentra una instrucción de E/S ejecuta dicha instrucción, enviando una orden al módulo apropiado de E/S.

    Con esta técnica, el procesador es el responsable de extraer los datos de la memoria principal cuando va a hacer una salida o poner los datos en la memoria principal cuando se hace una entrada. El SW de E/S se escribe de manera que el procesador ejecute unas instrucciones que le otorguen el control directo sobre la operación de E/S.

    Entrada / Salida dirigida por interrupciones

    El problema de E/S programada es que el procesador tiene que esperar un largo rato a que el módulo de E/S en cuestión esté listo para recibir o transmitir más datos.

    Una alternativa es que el procesador envíe una orden de E/S al módulo y se dedique a hacer alguna otra tarea útil. El módulo de E/S interrumpirá entonces al procesador para requerir sus servicios cuando esté listo para intercambiar los datos. El procesador ejecuta entonces la transferencia de datos y reanuda el procesamiento anterior.

    Acceso Directo a Memoria

    La E/S dirigida por interrupciones, aunque es más eficiente que la E/S programada, todavía requiere de la intervención activa del procesador para transferir los datos entre la memoria y un módulo de E/S y, además, cualquier transferencia de datos debe recorrer un camino que pasa por el procesador.

    Cuando se tienen que mover grandes volúmenes de datos se utiliza la técnica de DMA, que se puede llevar a cabo por medio de un módulo separado sobre el bus del sistema o puede estar incorporada dentro de un módulo de E/S.

    Cuando el procesador desea leer o escribir un bloque de datos, emite una orden hacia el módulo de DMA enviándole la información necesaria:

    • Si lo que se solicita es una lectura o escritura
    • La dirección del dispositivo de E/S involucrado
    • La dirección inicial de memoria desde/a la que se va a leer/escribir
    • El número de palabras a leer o escribir

    El procesador continúa entonces con otro trabajo. Habrá delegado la operación de E/S en el módulo de DMA. El módulo de DMA transfiere un bloque entero, una palabra cada vez, directamente hacia/desde la memoria, sin pasar por el procesador. Cuando se completa la transferencia, el módulo de DMA envía una señal de interrupción al procesador. De esta manera, el procesador se ve involucrado sólo al inicio y al final de la transferencia.

    CAPITULO 2: CONCEPTOS FUNDAMENTALES SOBRE SISTEMAS OPERATIVOS

    2.1. EVOLUCION DE LOS SISTEMAS OPERATIVOS

    Proceso en serie

    En los primeros computadores, a fines de los 40 hasta mediados de los 50, el programador interactuaba directamente con el hardware; no había sistema operativo. La operación con estas máquinas se efectuaba desde una consola consistente en unos indicadores luminosos, unos conmutadores, algún dispositivo de entrada y una impresora. Los programas en código de máquina se cargaban a través del dispositivo de entrada. Si se detenía el programa por un error, la condición de error se indicaba mediante los indicadores luminosos. El programador podía examinar los registros y la memoria principal para determinar la causa del error. Si el programa continuaba hasta su culminación normal, la salida aparecería en la impresora.

    Estos sistemas presentaban dos problemas principales:

    • Planificación: la mayoría de las instalaciones empleaban un formulario de reserva de tiempo de máquina. Un usuario podía reservar una hora y terminar a los 45 minutos (produciendo un desperdicio del tiempo de computador) o, bien no alcanzarle el tiempo reservado (dejando trabajos inconclusos).
    • Tiempo de preparación: un programa sencillo cargaba un compilador y un programa fuente, salvaba el programa compilado (programa objeto) y luego montaba y cargaba el programa objeto junto con las funciones comunes. Cada uno de estos pasos podía implicar montar y desmontar cintas o preparar paquetes de tarjetas.

    Este modo de operación podría denominarse proceso en serie porque refleja el hecho de que los usuarios tenían que acceder al computador en serie.

    Sistemas sencillos de proceso por lotes

    Para mejorar el uso, se desarrolló el concepto de sistema operativo por lotes (batch). El primer S.O. por lotes fue desarrollado a mediados de los 50 por General Motors.

    La idea central que está detrás del esquema sencillo de proceso por lotes es el uso de un elemento SW conocido como monitor. Para entender cómo funciona este esquema, se va a ver desde dos puntos de vista: el del monitor y el del procesador.

    Desde el punto de vista del monitor, él es quien controla la secuencia de sucesos. Para que esto sea posible, gran parte del monitor debe estar siempre en memoria principal y disponible para su ejecución. Esta parte del monitor se conoce como monitor residente. El resto del monitor consta de utilidades y funciones comunes que se cargan como subrutinas en los programas de los usuarios al comienzo de cualquier trabajo que las necesite.

    El monitor lee los trabajos uno a uno del dispositivo de entrada y, a medida que los lee, el trabajo actual se ubica en la zona del programa de usuario y toma el control. Cuando el trabajo termina, se devuelve el control al monitor, quien lee el siguiente trabajo. Los resultados de cada trabajo se imprimen y entregan al usuario.

    Consideremos ahora desde el punto de vista del procesador. El procesador ejecuta las instrucciones del programa de usuario hasta que encuentre una condición de finalización o de error, tras lo cual va en búsqueda de la instrucción siguiente del programa monitor.

    Debe quedar claro que es el monitor el que gestiona el problema de la planificación. Con respecto a la preparación de los trabajos, también el monitor se encarga de ello. Con cada trabajo se incluyen instrucciones de una forma primitiva de lenguaje de control de trabajos (JCL – Job Control Language), que es un tipo especial de lenguaje de programación empleado para dar instrucciones al monitor.

    Durante la ejecución del programa de usuario, cada instrucción de entrada origina la lectura de una tarjeta de datos. La instrucción de entrada en el programa del usuario hace que se invoque una rutina de entrada, que forma parte del sistema operativo. La rutina de entrada se asegura de que el programa de usuario no ha leído accidentalmente una tarjeta JCL; si esto sucede, se produce un error y el control se transfiere al monitor.

    Los sistemas sencillos por lotes también poseen las siguientes características:

    • Protección de memoria: mientras el programa del usuario esté ejecutándose, no debe modificar la zona de memoria en la que está el monitor. Si se hace un intento tal, el HW del procesador deberá detectar el error y transferir el control al monitor, quien abortará entonces el trabajo, imprimirá el mensaje de error y cargará el siguiente trabajo.
    • Uso de temporizador: impide que un solo trabajo monopolice el sistema. El temporizador se larga al comenzar cada trabajo y si expira el tiempo, se producirá una interrupción y el control volverá al monitor.
    • Instrucciones privilegiadas: ciertas instrucciones son designadas como privilegiadas y pueden ser ejecutadas sólo por el monitor. Si el procesador, al ejecutar el programa del usuario, encuentra una instrucción tal, entonces se produce una interrupción de error.

    En un S.O. por lotes, el tiempo de máquina se reparte entre la ejecución de programas de usuario y la ejecución del monitor. Así se tienen dos pérdidas: se entrega al monitor cierta cantidad de memoria principal y éste consume cierto tiempo de máquina.

    Sistemas por lotes con multiprogramación

    Aún con el secuenciamiento automático de los trabajos ofrecido por un S.O. por lotes, el procesador está desocupado a menudo. El problema es que los dispositivos de E/S son lentos comparados con el procesador.

    Esta ineficiencia no es necesaria. Se sabe que hay memoria suficiente para almacenar el S.O. (el monitor residente) y un programa de usuario. Supóngase que hay espacio suficiente para el sistema operativo y dos programas usuarios. Ahora, cuando un trabajo necesite esperar una E/S, el procesador puede cambiar al otro trabajo que probablemente no estará esperando a la E/S. Además se podría ampliar la memoria para almacenar tres, cuatro o más programas y conmutar entre todos ellos. Este proceso es conocido como multiprogramación o multitarea. Éste es el punto central de los sistemas operativos modernos.

    Sistemas de tiempo compartido

    Con el uso de la multiprogramación, el tratamiento por lotes puede llegar a ser bastante eficiente. Sin embargo, para muchas tareas, es conveniente suministrar un modo en que el usuario interactúe directamente con el computador.

    Al igual que la multiprogramación permite al procesador manejar varias tareas por lotes al mismo tiempo, la multiprogramación puede también utilizarse para manejar varias tareas interactivas. En este último caso, la técnica se conoce como tiempo compartido, porque refleja el hecho de que el tiempo del procesador es compartido entre los diversos usuario. La técnica básica de un sistema de tiempo compartido es tener a varios usuarios utilizando simultáneamente el sistema mediante terminales, mientras que el sistema operativo intercala la ejecución de cada programa de usuario en ráfagas cortas de cómputo (quantum). De esta manera si hay n usuario que solicitan el servicio a la vez, cada usuario sólo dispondrá, en promedio, de 1 / n de la atención efectiva del computador, sin contar con la sobrecarga del sistema operativo.

    Uno de los primeros sistemas de tiempo compartido que se desarrollaron fue el Sistema Compatible de Tiempo Compartido (CTSS, Compatible Time-Sharing System) en 1961. Su funcionamiento básico es fácil de explicar. El sistema se ejecutaba en una máquina con una memoria de 32 K palabras de 36 bits, con un monitor residente que consumía 5 K del total. Cuando había que asignar el control a un usuario interactivo, el programa del usuario y los datos eran cargados en los restantes 27 K de la memoria principal. Un reloj del sistema generaba interrupciones a razón de aprox. una cada 0,2 segundos. En cada interrupción del reloj, el S.O. se adueñaba del control y le podía asignar el procesador a otro usuario. De esta manera, a intervalos regulares, el usuario en curso era expulsado y se cargaba otro usuario en su lugar. Para conservar el estado del usuario anterior, para su reanudación posterior, los programas del usuario anterior y sus datos eran escritos en el disco antes de leer los programas del nuevo usuario y sus datos. En consecuencia, el espacio de memoria del usuario anterior debía ser restaurado cuando le llegara de nuevo su turno.

    Sistemas distribuidos

    Un sistema de procesamiento de datos en que todas las funciones están centralizadas en una CPU y un S.O. se llama procesamiento centralizado.

    En cambio, un procesamiento distribuido es aquel en que se ejecutan los datos en distintos nodos, dispersos geográficamente, interconectados mediante una red. Las características principales de un sistema distribuido son:

    • Fragmentación de los elementos que componen una aplicación, en dos o más sistemas interconectados, de igual o diferente arquitectura operativa.
    • Los recursos de los sistemas se controlan y administran en forma independiente
    • La relación entre ambos sistemas puede tomas diferentes formas. Por ejemplo: Client-Server y Peer to Peer (Un nodo es par de otro y ambos nodos ofrecen los mismos servicios).

    2.2. DEFINICIONES PREVIAS

    • Software: es la parte lógica. Se refiere a programas y a la gestión del computador.
    • Hardware: todo lo referente a la computadora que pueda ser "tocado"
    • Firmware: programa grabado sobre un componente del sistema y que está integrado a él en su funcionamiento.
    • Orgware: todo lo relacionado con la organización, ya sea lógica, física o sobre su uso.
    • Peopleware: se refiere a lo relacionado con los usuarios.

    2.3. DEFINICION DE SISTEMA OPERATIVO

    • Según sus procedimientos: "Un S.O. es un conjunto de programas, rutinas y procedimientos manuales y automáticos que administran los recursos de un sistema de cómputo"
    • Según sus funciones: "Un programa o conjunto de programas es llamado S.O. si cumple las funciones de:

    . Inicialización de la máquina

    . Servir de interfase hombre-máquina (máquina extendida)

    . Administración de recursos del sistema "

    2.4. CLASIFICACION DE LOS SISTEMAS OPERATIVOS

    Según la cantidad de usuarios que soporta, un S.O. se clasifica en Monousuario o Multiusuario. Y según las aplicaciones que ejecutan, en S.O. de Propósito General y S.O. de Propósito Especial.

    Según la cantidad de usuarios que soporta

    S.O. Mono-Usuario

    Son sistemas que se basan en máquinas virtuales que admiten a un solo usuario, el cual utiliza todos los recursos sin compartirlos con otros. Éste es el caso de las computadoras personales (PC) o estaciones de trabajos específicas (Workstation). El énfasis de su diseño está puesto en una interfase amigable entre el usuario y el equipo, un lenguaje de control sencillo y periféricos.

    S.O. Multi-Usuarios

    Los S.O. Multiusuarios son aquellos que aceptan más de un usuario trabajando simultáneamente con el computador.

    Según las aplicaciones que ejecutan

    S.O. de Propósito General

    Están diseñados para mantener un flujo constante de trabajo (Work-flow) en forma de tareas a ser ejecutadas por la máquina. Debido al gran número (y diversidad) de trabajos, el Sistema debe proveer soportes utilitarios y facilidades para soportar una gran cantidad de unidades periféricas.

    Se clasifican en Sistemas Batch y Sistemas de accesos múltiples (Multiaccess). Los Sistemas Batch se caracterizan por el hecho de que una vez introducida una tarea en la máquina, el usuario no mantiene contacto con la misma hasta que concluye su ejecución. Hay dos modos de trabajar proponiendo las tareas al sistema:

    • A través del operador: el operador recibe el trabajo y lo pone a ejecutar. Al finalizar la ejecución, devuelve los resultados al usuario.
    • Remote Job Entry: permite ordenar ejecución de trabajos mediante dispositivos E/S.

    En los Sistemas Multiaccess el usuario puede iniciar, vigilar, controlar o suspender la ejecución de su programa desde cualquier terminal del sistema.

    S.O. de Propósito Especial

    Están diseñados para aplicaciones y/o arquitecturas especiales. Se clasifican en: Tiempo real, Fault Tolerance (Tolerancia de Fallas) y Virtuales.

    Características de los S.O. de tiempo real:

    • Usados como dispositivos de control de aplicaciones que deben realizarse en un tiempo determinado.
    • Realiza la respuestas a eventos en tiempo preestablecidos.
    • Sus parámetros más importantes son los tiempos de espera, procesamiento y almacenamiento.
    • Pueden tener un tiempo de respuesta crítico (Ej: control de procesos industriales) o no crítico (Ej: reserva de pasajes).

    Características de los S.O. con tolerancia de fallas:

    • Usado en aplicaciones donde se debe proveer un servicio continuo o cuyo mantenimiento es dificultoso o muy costoso.
    • Detecta y corrige errores, y recupera el sistema habilitando reemplazos de los componentes en mal funcionamiento o vuelve atrás operaciones que motivaron pérdidas de datos.

    Características de los S.O. virtuales:

    • Especialmente diseñados para ejecutar varios S.O. (o distintas versiones de uno mismo) concurrentemente en una máquina creando la ilusión de varias máquinas virtuales idénticas.
    • Todos los S.O. trabajan en modo usuario respecto S.O. virtual, pero están en modo privilegiado con respecto a los programas que corren bajos ese S.O.

    2.5. COMPONENTES DE UN SISTEMA OPERATIVO

    Planificador de Trabajos (Job Scheduler) o Shell

    Sus funciones principales son:

    • Se encarga de hacer de interfase hombre-máquina
    • Administra pedidos de recursos
    • Carga los programas
    • Crea procesos
    • Controla accesos de usuarios
    • Controla protecciones del sistema

    Existen dos tipos de Shell:

    • Uno provee una interfase basada en comandos u órdenes llamadas C.L.I. (Command Line Interface) que permite ingresar un conjunto de caracteres que el S.O. interpretará como comandos u órdenes
    • Conocido como G.I.U. (Graphical User Interface) que permite accesos a través de iconos o gráficos.

    Núcleo o Kernel

    Es un conjunto de códigos usados por todos los programas en el más bajo nivel. Está compuesto por:

    1. Una extensión del set de instrucciones del procesador
    2. Una extensión del mecanismo de secuenciamiento del HW (Switcher o Dispatcher)
    3. Un manejador de Interrupciones (Interrupt Handler)
    4. Un manejador de errores (Error Handler)
    5. Un manejador de E/S (I/O Handler)
    6. Un mecanismo de acceso a memoria central (Direccionamiento)
    7. Un Clock (Timer)
    8. Comunicación entre procesos (IPC)

    Se encarga de:

    1. Interfases con HW
    2. Administración de interrupciones y excepciones
    3. Multiprogramación (Low Scheduler)
    4. Comunicación entre procesos
    5. Gestión del HW

    Las características de sus funciones (del nivel cero de la estructura de un S.O.) son:

    1. Residentes en Memoria Principal
    2. Deben ejecutarse en el mayor nivel de prioridad (Nivel Supervisor)
    3. Escritas en lenguaje ensamblador

    Administradores

    1. Administración del procesador: consta de dos módulos: Dispatcher (decide a qué procesador asignar el proceso que tiene que ser ejecutado) y Controlador de Tráfico (se encarga de crear, modificar y actualizar el contexto asociado a un proceso)
    2. Administración de memoria (Memory Manager): se encarga de asignar a los procesos la memoria necesaria para su ejecución.
    3. Administración de periféricos (I/O System): posee todos los módulos necesarios para la utilización de los periféricos.
    4. Administración de información (File System): rutinas que permite manipular y manejar el sistema de archivos.
    5. Administración de comunicaciones (Communication Manager): responsable de compartir los recursos distribuidos mediante una red de computadoras.

    2.6. FUNCIONES DE UN SISTEMA OPERATIVO

    Inicialización

    Esta tarea es llevada a cabo por el Kernel, con rutinas residentes en memoria más otras residentes en el disco del sistema. La inicialización tiene por objetivo preparar la máquina real y llevarla a un estado tal que pueda ejecutar el primer trabajo.

    Hay dos tipo de inicialización:

    1. Inicialización Total: es un proceso que se ejecuta al encender la máquina. Los pasos en que se realiza son los siguientes:
    • Verificación de los recursos del sistema
    • Creación de las tablas de recursos
    • Almacenamiento de la dirección del procesador
    • Búsqueda del código de la rutina de inicialización
    • El I.P.L. carga el núcleo del S.O. en memoria
    • El programa cargador (Loader) carga el S.O. completo
    • Finalización del booteo
    • Máquina preparada para ejecución de primer trabajo
    • Prompt en pantalla
    • Máquina utilizable
    1. Inicialización Parcial: no crea ni localiza las tablas generadas por el proceso de Verificación de Recursos en el instante del "booteo".

    Máquina extendida (Interfase hombre – máquina)

    Las funciones principales de la máquina extendida son:

    1. Separar la complejidad de la máquina. Una parte del S.O. se ocupa de separar la complejidad de HW y lo transforma en una máquina virtual mas fácil de usar
    2. Actuar como interfase de E/S y controlar el manejo de los dispositivos E/S
    3. Facilitar la comunicación con el usuario
    4. Aceptar entradas de nuevos trabajos.

    La comunicación con el usuario es a través de algún lenguaje de comandos. Esta interfase con el usuario presenta dos visiones del S.O.:

    1. Visión del usuario: para el usuario común. Provee una interfase que proporciona el ocultamiento de HW, cuyos objetivos principales son la abstracción (para ocultar la complejidad) y seguridad (proteger uso de recursos entre los usuarios y el sistema)
    2. Visión del System Manager: para el administrador del sistema de cómputo (super usuario). El System Manager es el responsable de que el Sistema de Cómputos funcione en forma adecuada y configura el S.O. para que los usuarios compartan los recursos en forma eficiente.

    Administración de recursos

    Sus funciones principales son:

    1. Facilitar al usuario la creación, recuperación y eliminación de objetos
    2. Facilitar al usuario compartir y proteger recursos
    3. Crear ambiente necesario para ejecución de programas
    4. Optimizar el uso de recursos

    Para ello, el S.O. controla todos los objetos de un sistema de cómputos en cuanto a quién usa cuál recurso y su respectiva planificación del reparto. De esta forma va asignando y desasignando recursos según considere conveniente, transformándose en un árbitro imparcial en los conflictos generados entre programas o usuarios. Para ser un arbitro imparcial, el S.O. implementa:

    • Política: asigna prioridades
    • Estrategia: ordena accesos y conflictos
    • Autoridad: debe recuperar los recursos otorgados a los procesos y ordenar su uso.
    • Protección: brinda seguridad a los usuarios entre sí y preserva la integridad de los recursos.
    • Contabilidad: lleva el control del uso y disponibilidad de los recursos.

    2.7. REQUERIMIENTOS PARA EL DISEÑO DE UN SISTEMA OPERATIVO

    • Eficiencia en los siguientes puntos:

    . Tiempo transcurrido entre tareas y procesos

    . Tiempo ocioso del procesador central

    . Tiempo de ejecución utilizado por procesos

    . Tiempo de respuesta en los accesos de los recursos

    . Grado de utilización de recursos

    . Rendimiento ® Trabajos ejecutados por hora

    • Modularidad: estructurado en módulos
    • Documentación de interfases
    • Portabilidad
    • Confiable: debe resolver todos los conflictos que se generan y debe estar libre de errores y fallas
    • Soporte de múltiples usuarios o procesos y de red
    • Tamaño reducido: el objetivo es que no utilice o monopolice grandes cantidades de recursos restándolos a los requerimientos de la producción debido a su condición de competidor privilegiado frente a los demás.

    2.8. ARQUITECTURA DE UN SISTEMA OPERATIVO

    Estructura tradicional o monolítica

    • Constituido por un solo programa compuestos de un conjunto de rutinas entrelazadas de tal forma que cada una puede llamar a cualquier otra.
    • Estructura interna indefinida. Los niveles de funcionalidad no están bien separados.
    • Estos S.O. tienen difícil configuración y actualización y falta de protecciones y privilegios.

    Estructura en estratos o jerárquica

    • El S.O. está compuesto por módulos organizados en niveles.
    • Cada módulo no conoce la implementación de los otros módulos, sólo conoce las interfases.
    • El módulo de nivel N funciona utilizando los servicios del nivel N – 1.
    • Esta estructura facilita la protección y el acceso.
    • Son S.O. de baja velocidad y de difícil definición de niveles.
    • Esta estructura puede representarse mediante anillos concéntricos (rings). Cada anillo tiene una apertura (trap) por donde accede a otras capas (niveles). Las capas internas son las de mayor privilegio.

    Estructura cliente-servidor

    • Se remueve la mayor parte del código del S.O., dejando un Kernel mínimo.
    • Las funciones del S.O. son implementadas como programas usuario.
    • Los servicios se efectúan mediante la técnica de message passing.
    • Sistemas altamente modulares. Los módulos del sistema no tienen acceso directo al HW.

    Procedimiento del Message passing (Paso de mensajes)

    1. El Proceso Cliente solicita al Kernel, mediante un mensaje, un servicio.
    2. El Kernel recibe el mensaje, toma las decisiones de planificación y envía el mensaje al Proceso Servidor.
    3. El Proceso Servidor ejecuta la función solicitada y devuelve al Kernel un mensaje con el resultado de la operación.
    4. El Kernel reenvía el mensaje al Proceso Cliente indicando que el servicio se ha cumplido.

    Máquinas virtuales

    • Posee una copia del HW base
    • Las características de la máquina virtual es igual a las de la real
    • Cada máquina virtual permite la ejecución de cualquier S.O.
    • Son de difícil implementación y de costosos recursos.

    2.9. SERVICIOS QUE BRINDA UN S.O.

    • Creación de programas: el S.O. ofrece una variedad de características y servicios, tales como los editores y los depuradores (debuggers), para ayudar al programador en la creación de programas.
    • Ejecución de programas: para ejecutar un programa se necesita un cierto número de tareas. El S.O. administra todas estas tareas para el usuario.
    • Acceso a los dispositivos de E/S: cada dispositivo de E/S requiere un conjunto propio y peculiar de instrucciones o de señales de control para su funcionamiento. El S.O. tiene en cuenta estos detalles.
    • Acceso controlado a los archivos: en el caso de archivos, el control debe incluir una comprensión, no sólo de la naturaleza del dispositivo de E/S sino del formato de los archivos y del medio de almacenamiento. Una vez más, es el S.O. el que se encarga de los detalles.
    • Acceso al sistema: en el caso de un sistema compartido o público, el S.O. controla el acceso al sistema como un todo y a los recursos específicos del sistema. Las funciones de acceso pueden brindar protección a los recursos y los datos, ante usuarios no autorizados y debe resolver los conflictos en la propiedad de los recursos.
    • Detección y respuesta a errores
    • Contabilidad: el S.O. debe recoger estadísticas de utilización de los diversos recursos y supervisar los parámetros de rendimiento tales como el tiempo de respuesta.

    2.10. PROGRAMAS RELACIONADOS CON EL SISTEMA OPERATIVO

    • Cargadores: SW que coloca las instrucciones del programa a ejecutar con sus datos en Memoria Principal.
    • Intérprete de mandatos o comandos: su función es obtener desde el teclado, el siguiente mandato especificado por el usuario y ejecutarlo. Hace de interfase usuario – sistema. Ej: Command.com en MS-DOS.
    • Compiladores: conjunto de programas que permiten la traducción de los lenguajes de alto nivel al lenguaje de máquina.
    • Intérpretes: traductores de instrucción de programa fuente a instrucción del lenguaje de máquina. No producen programas objetos.
    • Link-Editors: son los responsables de ubicar en el programa ejecutable las rutinas de bibliotecas (library).
    • Debuggers: son programas que permiten encontrar y depurar fácilmente errores en otros programas.

    2.11. JERARQUIA DE DISEÑO DE UN SISTEMA OPERATIVO

    Para ver la tabla seleccione la opción "Descargar" del menú superior

    2.12. SIMMETRIC MULTIPROCESSING (SMP)

    Últimamente, se han creado diseños (como por ejemplo el SMP) que posibilitan la ejecución en paralelo.

    Los procesadores en paralelo se dividen en SIMD (single instruction multiple data) y MIMD (multiple instruction multiple data). MIMD es un set de procesadores que simultáneamente ejecutan secuencias de instrucciones distintas en distintos sets de datos. Estos últimos pueden usar memoria compartida o memoria distribuida. Dentro del sistema de memoria compartida encontramos dos tipos de arquitecturas: master/slave (amo/esclavo) o SMP.

    La arquitectura master/slave corre el kernel en un procesador en particular, el master esta encargado de los procesos estimados y los hilos. La ventaja de esta arquitectura se da en que un proceso controla toda la memoria y los recursos de I/O. La desventaja se produce cuando una falla en el master produce una caída de todo el sistema. Además puede ocurrir un cuello de botella ya que el master se ocupa de todos los procesos estimados y la administración de los restantes.

    La arquitectura SMP corre su kernel en cualquier procesador. El kernel es construido como múltiples procesos o múltiples hilos. Esta arquitectura debe garantizar que dos procesadores no elijan el mismo proceso ya que ocurriría una falla. En SMP hay múltiples procesadores y cada uno de ellos tiene una unidad de control, unidad aritmetica-logica y registros propios. Cada procesador tiene acceso a memoria compartida y a dispositivos de I/O a través de un bus compartido. En maquinas modernas, el procesador tiene generalmente un nivel de memoria cache privada.

    2.13. MICROKERNELS

    La filosofía del microkernel es que solamente las funciones esenciales del sistema operativo deben estar en el kernel. Los componentes del sistema operativo externos al microkernel son implementados como procesos servidores; estos interactuan entre ellos sobre una misma base, mediante mensajes a través del microkernel. La función del microkernel con respecto al intercambio de mensajes, es la de validarlos, pasarlos entre componentes y conceder acceso al hardware. (El microkernel pasa a tener una arquitectura del tipo cliente/servidor).

    Los beneficios del microkernel son, entre otros, extensibilidad, portabilidad, flexibilidad y fiabilidad, siendo recomendado para sistemas operativos orientado a objetos. Una de las principales desventajas es la performance. Cuesta mucho el crear y enviar un mensaje, aceptar, decodificar y responder entre otras cosas.

    Administración de memoria primitiva

    El microkernel debe controlar el direccionamiento de memoria libre en el orden de hacer posible la implementacion de los niveles de protección. Es responsable del mapeo de cada pagina virtual a una pagina física. El volumen de administración de memoria, incluyendo la protección entre procesos, puede ser implementada fuera del kernel.

    I/O y administración de interrupciones

    La arquitectura del microkernel puede manejar las interrupciones del hardware mediante mensajes e incluir puertos I/O en espacios direccionables. El microkernel reconoce la interrupción pero no puede manejarla. Para esto genera un mensaje al proceso de nivel usuario que se encuentra asociado con las interrupciones. El transformar interrupciones en mensajes debe ser realizado por el microkernel.

    CAPITULO 3: PROCESOS.

    3.1. CONCEPTOS GENERALES SOBRE LOS PROCESOS

    Todos los sistemas operativos de multiprogramación están construidos en torno al concepto de proceso. Por lo tanto, los requisitos principales que deben satisfacer un S.O. están expresados haciendo referencia a procesos:

    • Debe intercalar la ejecución de un conjunto de procesos para maximizar la utilización del procesador ofreciendo a la vez un tiempo de respuesta razonable.
    • Debe asignar los recursos a los procesos en conformidad con un política específica
    • Podría tener que dar soporte a la comunicación entre procesos y la creación de procesos por parte del usuario

    El procesador ejecutará instrucciones de entre un repertorio en una secuencia dictada por los valores cambiantes del IP. A lo largo del tiempo, este contador puede apuntar a códigos de programas diferentes que son parte de diferentes aplicaciones. Desde el punto de vista de un programa individual, su ejecución involucra una secuencia de instrucciones del programa. La ejecución de un programa individual se conoce como proceso o tarea.

    El comportamiento de un proceso individual puede caracterizarse por la traza, que es un listado de la secuencia de instrucciones que se ejecutan para dicho proceso. El comportamiento del procesador puede caracterizarse mostrando la forma en que se intercalan las trazas de varios procesos. Todo sistema operativo permite a un proceso continuar su ejecución sólo por un cantidad máxima determinada de ciclos, después de los cuales es interrumpido (time-out); esto impide que un solo proceso monopolice el tiempo del procesador.

    3.2. MODELO DE PROCESOS CON DOS ESTADOS

    El modelo más sencillo que puede construirse tiene en cuenta que, en un momento dado, un proceso puede estar ejecutándose o no. Entonces, un proceso puede estar en uno de dos estados: Ejecución y No Ejecución. Cuando el sistema operativo crea un nuevo proceso, éste entra en el sistema en el estado de No Ejecución. De este modo, el proceso existe, es conocido por el sistema operativo y está esperando la oportunidad de ejecutarse. Aquellos procesos que no están ejecutándose tienen que guardarse en algún tipo de cola, para que esperen su turno de ejecución.

    Creación de procesos

    Cuando se añade un proceso a los que ya está administrando el sistema operativo, hay que construir las estructuras de datos que se utilizan para administrar el proceso y asignar el espacio de direcciones que va a utilizar el proceso.

    Cuatro sucesos comunes llevan a la creación de un proceso:

    • En un entorno de trabajo por lotes, un proceso se crea como respuesta a la remisión de un trabajo.
    • En un entorno interactivo, cuando un nuevo usuario intenta conectarse.
    • Por una aplicación. Por ejemplo, si un usuario solicita la impresión de un archivo, el S.O. creará un proceso que gestionará dicha impresión.
    • Por solicitud de otro proceso.

    Cuando un proceso es creado por el sistema operativo tras la solicitud explícita de otro proceso, la acción se conoce como generación de procesos (process spawning). Cuando un proceso genera otro, el proceso generador se conoce como proceso padre y el proceso generado es el proceso hijo.

    Existen dos tipos de creación:

    • Jerárquica: cada proceso que se crea es hijo del proceso creador y hereda el entorno de su ejecución de su padre. Un proceso durante su ejecución puede crear varios procesos hijos a través de llamadas al sistema para creación de procesos. Al restringirse un proceso hijo a un subconjunto de recursos del padre, se evita que éste sature al sistema creando demasiados procesos hijos. Al crear procesos hijos, el padre continúa ejecutando concurrentemente con sus hijos o espera a que todos sus hijos hayan terminado y luego continúa él.
    • No jerárquica: cada proceso creado se ejecuta en forma independiente de su creador en un entorno diferente.

    Terminación de procesos

    En cualquier sistema informático, debe haber alguna forma de que un proceso pueda indicar que ha terminado. Las formas existentes para terminar un proceso son:

    • En un entorno de trabajo por lotes, inclusión de una instrucción de detención (HALT). Esta instrucción generará una interrupción para avisar al S.O. que el proceso ha concluido.
    • En un entorno de trabajo por lotes, puede finalizarse por la llamada explícita a un servicio del S.O. para la terminación.
    • En una aplicación interactiva, es la acción del usuario la que indica terminación. Por ejemplo, en un sistema de tiempo compartido, el proceso de un usuario particular terminará cuando éste se desconecte del sistema o apague el terminal y en una PC o WorkStation cuando el usuario abandona una aplicación.
    • Cuando ocurren una serie de errores o condiciones de fallos
    • Un proceso puede ser eliminado por el proceso que lo creó o al terminar el proceso padre

    3.3. MODELO DE PROCESOS CON CINCO ESTADOS

    • Ejecución: si suponemos un computador con un único procesador, entonces sólo podrá haber un proceso en este estado.
    • Listo: proceso que está preparado para ejecutar, en cuanto se le dé la oportunidad
    • Bloqueados: proceso que no puede ejecutar hasta que se produzca cierto suceso, como la terminación de una operación de E/S.
    • Nuevo: proceso que se acaba de crear, pero que aún no ha sido admitido por el sistema operativo en el grupo de procesos ejecutables.
    • Terminado: un proceso que ha sido excluido del grupo de procesos ejecutables, porque se detuvo o porque fue abandonado por alguna razón.

    Si un nuevo usuario intenta conectarse a un sistema de tiempo compartido o si un nuevo trabajo por lotes es remitido para su ejecución. El sistema operativo puede definir un nuevo proceso en dos pasos. Primero, el S.O: lleva a acabo algunas tareas necesarias de gestión interna Se le asocia un identificador al proceso y se construyen y asignan algunas tablas necesarias para gestionar el proceso. En este punto, el proceso estará en el estado Nuevo. Esto significa que se han llevado a cabo las acciones necesarias para crear el proceso pero no se ha comprometido aún a su ejecución.

    Asimismo, un proceso sale de un sistema en dos pasos. Primero, el proceso termina cuando llega al punto normal de terminación, cuando se abandona debido a un error irrecuperable o cuando otro proceso con la debida autoridad hace que el proceso abandone. La terminación pasa el proceso al estado Terminado. En este punto, el proceso ya no se elige más para la ejecución. Sin embargo, las tablas y otra información asociada con el trabajo son conservadas temporalmente. Esto le da tiempo a otros programas auxiliares o de soporte para extraer la información necesaria.

    Cola de Listos y Bloqueados

    A medida que se admiten procesos en el sistema, se sitúan en la cola de Listo. Cuando llega el momento de que el S.O. escoja otro proceso para ejecutar, se selecciona uno de la cola de Listos. En ausencia de un esquema de prioridades, ésta puede ser una simple cola FIFO. Cuando un proceso que está ejecutándose es apartado de la ejecución, se lo da por terminado o se lo pone en la cola de Listos o Bloqueados, dependiendo de las circunstancias.

    Por último, cuando se produce un suceso, todos los procesos de la cola de Bloqueados que están esperando a dicho suceso se pasan a la cola de Listos. Esta última medida significa que, cuando se produce un suceso, el sistema operativo debe recorrer toda la cola de Bloqueados, buscando aquellos que esperaban al suceso. En un S.O. grande, puede haber demasiada cantidad de procesos en dichas cola y, por lo tanto, sería más eficiente tener una varias colas de Bloqueados, una por cada suceso.

    Procesos suspendidos

    Consideremos un sistema que no utiliza memoria virtual. Cada proceso que va a ejecutarse debe ser cargado por completo en la memoria principal. La memoria contiene varios procesos y el procesador puede dedicarse a otro proceso cuando uno esté esperando. Pero si el procesador es tan rápido en comparación con E/S, todos los procesos de memoria estarán esperando este recurso. Así pues, incluso con multiprogramación, el procesador podría estar desocupado la mayor parte del tiempo.

    Una solución es el intercambio, que significa mover una parte o todo el proceso de la memoria principal a disco. Cuando ninguno de los procesos en memoria está en estado Listo, el sistema operativo expulsa a disco a uno de los procesos que esté Bloqueado y lo pasa a una cola de Suspendidos. Al realizar la transferencia del proceso a disco, entonces el espacio que se libera de la memoria principal puede ser utilizado para traer otro proceso. En este modelo vemos que se ha agregado un estado Suspendido.

    Hemos visto dos conceptos independientes: si un proceso está esperando un suceso (bloqueado o no) y si un proceso ha sido expulsado de la memoria principal (suspendido o no). Para realizar las combinaciones de estos conceptos, hacen falta los cuatro estados siguientes:

    • Listo: el proceso está en memoria principal y listo para la ejecución.
    • Bloqueado: el proceso está en memoria principal esperando un suceso
    • Bloqueado y suspendido: el proceso está en memoria secundaria esperando un suceso.
    • Listo y suspendido: el proceso está en memoria secundaria pero está disponible para su ejecución tan pronto como se cargue en memoria principal.

    3.4. DESCRIPCION DE PROCESOS

    Estructuras de control del sistema operativo

    Si el sistema operativo va a administrar los procesos y los recursos, entonces tiene que disponer de información sobre el estado actual de cada proceso y de cada recurso. El S.O. construye y mantiene tablas de información sobre cada entidad que esté administrando. Hay cuatro tipo de tablas diferentes mantenidas por el sistema operativo: de memoria, de E/S, de archivos y de procesos.

    Las tablas de memoria deben incluir la siguiente información:

    • La asignación de memoria principal a los procesos
    • La asignación de memoria secundaria a los procesos
    • Atributos de protección de segmentos de memoria, tales como qué procesos pueden acceder a ciertas regiones compartidas de memoria
    • Cualquier información necesaria para gestionar la memoria virtual

    Las tablas de E/S son utilizadas por el sistema operativo para administrar los dispositivos y canales de E/S del sistema informático.

    Las tablas de archivos ofrecen información sobre la existencia de los archivos, su posición en la memoria secundaria, su estado actual y otros atributos. Gran parte de esta información (o toda) puede ser mantenida y utilizada por un sistema de gestión de archivos, en cuyo caso el sistema operativo tendrá poco o ningún conocimiento de los archivos.

    Finalmente, el sistema operativo debe mantener tablas de procesos para administrarlos.

    Todas estas tablas deben estar enlazadas o disponer de referencias cruzadas de alguna manera. La memoria, E/S y los archivos son administrados en nombre de los procesos, por lo que debe haber alguna referencia directa o indirecta a estos recursos en las tablas de procesos.

    Estructuras de control de procesos

    Los elementos típicos de una imagen de proceso son:

    • Espacio de direcciones privadas del usuario: incluye los datos del usuario (la parte modificable del espacio de usuario que puede guardar datos del programa, una zona para una pila del usuario y programas que pueden modificarse) y el programa del usuario (programa a ejecutar).
    • Pila del sistema: cada proceso tiene una o más pilas LIFO asociadas a él. Una pila se utiliza para almacenar los parámetros y las direcciones de retorno.
    • Bloque de control del proceso: información necesaria para que el sistema operativo controle al proceso.
    • Espacio de direcciones compartidas con otros procesos

    Para que el sistema operativo pueda administrar el proceso, al menos una pequeña parte de su imagen, que contiene la información a usar por el sistema operativo, debe mantenerse en memoria principal. Para ejecutar el proceso, la imagen completa debe cargarse en la memoria principal. Por tanto, el sistema operativo necesita conocer la ubicación de cada proceso en el disco y también la ubicación de los procesos que estén en memoria principal.

    Hay una tabla principal de procesos con una entrada para cada proceso. Cada entrada contiene, al menos, un puntero a la imagen de un proceso. Si la imagen del proceso contiene varios bloques, entonces esta información estará guardada directamente en la tabla principal o con referencias cruzadas a entradas de las tablas de memoria.

    Bloque de Control del Proceso

    En un sistema de multiprogramación sofisticado, se requiere una gran cantidad de información de cada proceso para su administración. Como ya se dijo, puede considerarse que esta información reside en un bloque de control del proceso (PCB), que será de utilidad para poder conmutar la CPU entre los distintos programas en ejecución. Los PCB son leídos y/o modificados por casi todos los módulos de un S.O., incluyendo aquellos que tienen que ver con la planificación, asignación de recursos, tratamiento de interrupciones y análisis y supervisión del rendimiento. Puede decirse que el conjunto de los PCB definen el estado del sistema operativo.

    Una serie de rutinas del S.O. intentarán acceder a la información de los PCB. La dificultad no está en el acceso, sino en la protección; existen dos problemas:

    • Un error en una sola rutina, como la de tratamiento de interrupciones, puede dañar los PCB, lo que destruiría la capacidad del sistema para administrar los procesos afectados.
    • Un cambio de diseño en la estructura o en la semántica del PCB podría afectar a varios módulos del S.O.

    Estos problemas planteados se pueden abordar exigiendo a todas las rutinas del S.O. que pasen a través de una rutina de manejo, cuya única tarea sería la de proteger los PCB y que se constituiría en el único árbitro para leer y escribir en estos bloques.

    La información del bloque de control del proceso puede agruparse en tres categorías generales:

    • Identificación del proceso: incluye el identificador de este proceso, el identificador del proceso que lo creó (proceso padre) y el identificador del usuario. A cada proceso se le asigna un identificador único, que puede ser tan simple como un índice en la tabla principal del proceso. Si no hay identificadores numéricos, entonces debe existir una correspondencia que permita al S.O. ubicar las tablas apropiadas a partir del identificador del proceso.
    • Información del estado del procesador: está formada por los registros del procesador, que son los Registros visibles al usuario (a los que puede hacerse referencia mediante el lenguaje de máquina), los Registros de Control y de Estado (IP – EFLAGS – Identificadores de habilitación/inhabilitación) y los Punteros de Pila (las pilas almacenan los parámetros y las direcciones de retorno de los procedimientos y de las llamadas al sistema; el puntero de pila apunta siempre a la cima de la pila). Por supuesto, mientras un proceso está ejecutándose, la información está en los registros. Cuando se interrumpe el proceso, toda la información de los registros debe salvarse de forma que pueda restaurarse cuando el proceso reanude su ejecución.
    • Información de control del proceso: es la información necesaria para que el S.O. controle y coordine los diferentes procesos activos. Incluye:

    . Información de Planificación y Control: estado del proceso, prioridad, información de planificación e identidad del suceso que el proceso está esperando antes de poder reanudarse

    . Estructuración de Datos: un proceso puede estar enlazada con otros procesos en una cola, anillos u otra estructura. El PCB puede contener punteros a otros procesos para dar soporte a estas estructuras.

    . Comunicación entre procesos: indicadores, señales y mensajes asociados con la comunicación entre dos procesos independientes.

    . Privilegios de los procesos

    . Gestión de Memoria

    . Propiedades y utilización de los recursos

    3.5. CONTROL DE PROCESOS

    Creación de procesos

    El procedimiento del sistema operativo para la creación de un nuevo proceso incluye los pasos siguientes:

    1. Asignar un único identificador al nuevo proceso. En ese momento se añade una nueva entrada a la tabla principal de procesos, que contiene una entrada por proceso.
    2. Asignar espacio para el proceso. Esto incluye todos los elementos de la imagen del proceso.
    3. Debe inicializarse el PCB. La parte de información del estado del procesador normalmente se inicializa con la mayor parte de las entradas a cero, excepto para el IP (que se prepara con el punto de entrada del programa) y los punteros a las pilas del sistema (que establecen los límites de la pila del proceso). La parte de información de control del procesador se inicializa a partir de los valores estándares por omisión y los atributos que se han solicitado para el proceso. La prioridad puede asignarse por omisión al valor más bajo, a menos que se haya hecho una solicitud explícita de un valor mayor.
    4. Se deben establecer los enlaces apropiados
    5. Puede haber otras estructuras de datos que crear o ampliar.

    Cambio de proceso

    A primera vista, la función de cambio de proceso parece sencilla. En cierto momento, un proceso que está ejecutándose se interrumpe, el sistema operativo pone a otro proceso en el estado de Ejecución y pasa el control a dicho proceso. Sin embargo, surgen algunas cuestiones. Una de esas cuestiones es cuándo cambiar de proceso.

    Existen tres mecanismos para realizar un cambio de proceso:

    • Interrupción: originada por algún suceso externo e independiente del proceso que está ejecutándose. El control se transfiere primero a un gestor de interrupciones, quien lleva a cabo algunas tareas básicas y luego se salta a una rutina del sistema operativo que se ocupa del tipo de interrupción que se produjo. Algunos ejemplos son:

    . Interrupción de reloj: el S.O. determina si el proceso que está ejecutándose ha estado ejecutándose durante un máximo de tiempo permitido. Si esto ocurre, el proceso pasa al estado Listo y se debe expedir otro proceso.

    . Interrupción de E/S: cuando el S.O. reconoce que se produjo una acción de E/S, y la acción constituye un suceso que están esperando uno o más procesos, entonces el S.O. traslada todos los procesos bloqueados al estado Listo y decide si reanuda la ejecución del proceso que está actualmente en estado de Ejecución o se expulsa a dicho proceso en favor de un proceso Listo de mayor prioridad.

    . Fallo de memoria: cuando el procesador encuentra una referencia a una dirección de memoria virtual de una palabra que no está en memoria principal, el S.O. debe traer a dicha memoria el bloque que contiene la referencia. Después de hacer la solicitud de E/S para traer el bloque de memoria, el S.O. puede llevar a cabo un cambio de contexto para reanudar la ejecución de otro proceso; el proceso que cometió el fallo de memoria se pasa a estado Bloqueado. Después de que el bloque en cuestión se carga en memoria, dicho proceso se pone en estado Listo.

    • Cepo: tiene que ver con una condición de error o de excepción generada dentro del proceso que está ejecutándose, como un intento ilegal de acceso a un archivo. El sistema operativo determina si el error ocurrido es fatal. Si lo es, el proceso que estaba ejecutándose pasa al estado de Terminado y se produce un cambio de proceso. Si no es fatal, se puede intentar algún procedimiento de recuperación o, simplemente, notificarlo al usuario. Se puede hacer un cambio de proceso o, simplemente, reanudar el mismo proceso que se estaba ejecutando.
    • Llamada del supervisor: se producen desde el programa que estaba ejecutándose. Por ejemplo, se está ejecutando un proceso de usuario y se llega a una instrucción que solicita una operación de E/S, tal como abrir un archivo. Esta llamada provoca la transferencia a una rutina que forma parte del código del sistema operativo. Por lo general, el uso de una llamada al sistema hace que el proceso de usuario pase al estado Bloqueado.

    Cambio de contexto

    Durante un ciclo de instrucción, el procesador comprueba si se ha producido alguna interrupción. Si no hay interrupción pendiente, continúa con el ciclo de lectura de la instrucción siguiente del programa en curso del proceso actual.

    Si hay alguna interrupción pendiente, el procesador salva el contexto del programa que está ejecutándose y asigna al IP el valor de la dirección de comienzo de un programa de tratamiento de la interrupción. El procesador continúa entonces con el ciclo de lectura de instrucción y trae la primera instrucción del programa de tratamiento de interrupciones, que atenderá a la interrupción. Al salvar el contexto, se debe incluir cualquier información que pueda alterarse por la ejecución de la rutina de tratamiento de la interrupción y que pueda ser necesaria para reanudar el programa que fue interrumpido. Así pues, deberá salvarse la parte de información de estado del procesador del PCB. El resto de la información del PCB depende de la influencia del tratamiento de la interrupción en el proceso.

    Cambio de estado de los procesos

    Está claro que el cambio de contexto es un concepto distinto del cambio de proceso. En los cambios de estado del proceso, por ejemplo, si el proceso que estaba ejecutándose pasa a otro estado (Listo, Bloqueado, etc) los pasos que se llevan a cabo son:

    1. Salvar el contexto del procesador
    2. Actualizar el PCB que estaba en estado de Ejecución. Esto implica cambiar el estado del proceso a alguno de los otros estados.
    3. Mover el PCB a la cola apropiada (Listos, Bloqueados, etc.)
    4. Seleccionar otro proceso para ejecución
    5. Actualizar el PCB del proceso seleccionado. Esto incluye cambiar el estado del proceso a Ejecución.
    6. Actualizar las estructuras de datos de gestión de memoria.
    7. Restaurar el contexto del proceso a aquél que existía en el momento en el que el proceso seleccionado dejó por última vez el estado de Ejecución.

    Ejecución del sistema operativo

    El S.O. es un conjunto de programas y es ejecutado por el procesador, entonces ¿es el sistema operativo un proceso?. Existen tres enfoques referidos a la ejecución de los S.O.:

    Núcleo fuera de todo proceso

    Un enfoque bastante tradicional y habitual en muchos de los sistemas operativos más antiguos es ejecutar el núcleo del sistema operativo fuera de cualquier proceso. Cuando el proceso en ejecución es interrumpido o hace una llamada de supervisor, se salva el contexto del procesador para este proceso y se pasa el control al núcleo. El S.O. tiene su propia región de memoria y su propia pila del sistema para controlar las llamadas y retornos de procedimientos. El S.O. puede llevar a cabo cualquier función deseada y luego restaurar el contexto del proceso interrumpido para reanudarlo.

    El punto clave es que se considera que el concepto de proceso se aplica sólo a los programas de usuario. El código del S.O. se ejecuta como una entidad separada que opera en modo privilegiado.

    Ejecución dentro de los procesos de usuario

    Ejecuta casi todo el software del sistema operativo en el contexto de un proceso de usuario. El enfoque es que el S.O. es principalmente una colección de rutinas que el usuario llama para llevar a cabo varias funciones y que son ejecutadas dentro del entorno del proceso de usuario. Una pila del núcleo separada se utiliza para gestionar las llamadas y los retornos mientras que el proceso esté en el modo del núcleo. El código y los datos del sistema operativo están en el espacio de direcciones compartidas y son compartidos por todos los procesos de usuario.

    Cuando se produce una interrupción, un cepo o una llamada del supervisor, el procesador se pone en modo del núcleo y el control pasa al S.O. Con tal fin, se salva el contexto del procesador y tiene lugar un cambio de contexto hacia una rutina del S.O. Sin embargo, la ejecución continúa dentro del proceso de usuario en curso.

    Si el sistema operativo, al completar su trabajo, determina que el proceso en curso debe continuar ejecutándose, entonces se lleva a cabo un cambio de contexto para reanudar el programa interrumpido del proceso en curso.

    Sistema operativo basado en procesos

    Consiste en implementar el sistema operativo como una colección de procesos del sistema. Al igual que en las otras opciones, el software que forma parte del núcleo ejecutará en modo núcleo. En este caso, sin embargo, las funciones más importantes del núcleo se organizan en procesos separados. Impone unas normas de diseño de programas que promueven el uso de un S.O. modular con interfases intermódulos mínimas y claras. Además, algunas funciones no críticas del S.O. se pueden implementar como procesos separados. Como un proceso, la función podrá ejecutar con un nivel de prioridad asignado y ser intercalada con otros procesos bajo el control del distribuidor. Por último, implementar el S.O. como un conjunto de procesos es útil en un entorno multiprocesador o multicomputador, en el cual algunos de los servicios del S.O. pueden enviarse a procesadores dedicados, mejorando así el rendimiento.

    3.6. THREADS, HILOS O PROCESOS LIVIANOS

    Se ha presentado el concepto de proceso incluyendo las dos características siguientes:

    • Unidad de propiedad de los recursos: a cada proceso se le asigna un espacio de direcciones virtuales para albergar a la imagen del proceso y, de cuando en cuando, al proceso se le puede asignar memoria virtual y otros recursos, tales como canales de E/S, dispositivos de E/S y archivos.
    • Unidad de expedición: un proceso es un camino de ejecución (traza) a través de uno o más programas. Esta ejecución puede ser intercalada con la de otros procesos. De este modo, un proceso tiene un estado (Ejecución, Listo, etc.) y una prioridad de expedición. La unidad planificada y expedida por el S.O. es el proceso.

    En la mayoría de los sistemas operativos, estas dos características son, de hecho, la esencia de un proceso. Para distinguir estas dos características, la unidad de expedición es llamada thread y la unidad de propiedad de los recursos, task. Un thread (también llamado hilo, hebra o proceso liviano) es, básicamente, la unidad de utilización de la CPU.

    Multi-threading

    Algunos sistemas operativos soportan múltiples hilos en la ejecución dentro de un proceso simple. Esto es conocido como multi-threading. Los procesos continúan teniendo un PCB y una cantidad de memoria para el usuario, pero cada hilo que pertenece a dicho proceso tiene un bloque de control de hilos, una pila de usuario y una pila de kernel propias.

    Implementación de los hilos

    Existen dos características generales en la implementación de los hilos:

    • Hilos de nivel usuario: en este nivel todo el trabajo de los hilos es realizado por la aplicación y el kernel no se percata de la existencia de dichos hilos. Una aplicación (que puede ser programada para ser multithread usando bibliotecas de hilos) comienza con un hilo simple. La aplicación y su hilo son localizados en un proceso simple administrado por el kernel. La generación de nuevos hilos es realizada invocando al utilitario que se encuentra en la biblioteca de hilos.
    • Hilos de nivel kernel: tiene la desventaja de que el cambio de hilos requiere siempre la intervención del kernel. No hay un código de administración de hilos en el área de la aplicación, sino simplemente una interface de una aplicación programada (API) para el kernel. El kernel mantiene la información del contexto del proceso entero y de cada uno de los procesos hilos que se encuentran dentro del mismo. La ventaja que presenta es que si uno de estos procesos hilos se encuentra en estado bloqueado, el kernel puede ejecutar otro proceso hilo del mismo padre.

    Algunas características de los threads

    Los threads poseen las siguientes características:

    • Tienen un pequeño estado no compartido
    • Un threads individual tiene su propio registro de estado y generalmente su propio Stack
    • Los hilos pueden estar en uno de los siguientes estados: listos, bloqueados, ejecutando o terminados. O sea, igual que un proceso tradicional. Los hilos comparten CPU, por lo que un solo hilo puede estar ejecutándose.
    • Un hilo dentro de un proceso se ejecuta secuencialmente.
    • Los hilos pueden crear hilos hijos.
    • Un hilo puede leer o escribir sobre cualquier otra pila de otro hilo. No se provee protección porque no es necesaria, ya que solo un usuario puede tener una tarea individual con múltiples hilos.
    • Una tarea no hace nada sin hilos y un hilo debe estar en una tarea
    • Un cambio de contexto en el hilo requiere un cambio en el juego de registros, pero el trabajo relacionado con manejo de memoria no es necesario hacerlo.
    • Un hilo único a nivel usuario ejecutando un System Call causará a la tarea entera esperar hasta que el System Call sea devuelto.

    CAPITULO 4. CONCURRENCIA: EXCLUSIÓN MUTUA Y SINCRONIZACIÓN. (*)

    4.1. CONCEPTOS GENERALES

    4.2. EXCLUSIÓN MUTUA: SOLUCIONES POR SOFTWARE.

    4.3. EXCLUSIÓN MUTUA: SOLUCIONES POR HARDWARE.

    4.4. SEMÁFOROS.

    4.5. MONITORES.

    4.6. PASO DE MENSAJES

    CAPITULO 5: CONCURRENCIA. INTERBLOQUEO (Deadlock) E INANICION (Starvation). (*)

    5.1. DEADLOCK

    5.2. CONDICIONES DE COFFMAN

    5.3. PREVENCIÓN DEL INTERBLOQUEO

    5.4. PREDICCION DEL INTERBLOQUEO (AVOIDANCE)

    5.5. DETECCIÓN DEL INTERBLOQUEO

    CAPITULO 6: GESTION DE MEMORIA. (*)

    6.1. GESTION DE MEMORIA

    6.2. OBJETIVOS DE LA ADMINISTRACIÓN DE MEMORIA

    6.3. CARGA DE PROGRAMAS EN MEMORIA

    CAPITULO 7: MEMORIA VIRTUAL. (*)

    7.1. CONCEPTOS SOBRE MEMORIA VIRTUAL

    7.2. PAGINACIÓN

    7.3. SEGMENTACIÓN

    7.4. SEGMENTOS PAGINADOS

    7.5. SOFTWARE DEL SISTEMA OPERATIVO

    7.6. TIEMPOS DE ACCESOS A MEMORIA

    CAPITULO 8: PLANIFICACIÓN DE MONOPROCESADORES (*)

    8.1. PLANIFICACIÓN A LARGO PLAZO

    8.2. PLANIFICACIÓN A MEDIO PLAZO

    8.3. PLANIFICACION A CORTO PLAZO

    8.4. CRITERIOS PARA LA PLANIFICACION A CORTO PLAZO

    8.5. ALGORITMOS PARA LA PLANIFICACION A CORTO PLAZO

    CAPITULO 9. PARTE I: PLANIFICACIÓN DE MULTIPROCESADORES (*)

    9.1.1. SISTEMAS MULTIPROCESADORES

    9.1.2. GRANULARIDAD

    9.1.3. PLANIFICACIÓN DE UN MULTIPROCESADOR

    9.1.4. PLANIFICACIÓN DE PROCESOS

    9.1.5. PLANIFICACION DE HILOS

    CAPITULO 9. PARTE II: PLANIFICACIÓN EN TIEMPO REAL (*)

    9.2.1. SISTEMAS DE TIEMPO REAL

    9.2.2. PLANIFICACIÓN EN TIEMPO REAL

    CAPITULO 10: GESTION DE E/S. PLANIFICACIÓN DE DISCOS. (*)

    10.1. DISPOSITIVOS DE E/S

    10.2. CONTROLADORES DE E/S

    10.3. OBJETIVOS EN EL DISEÑO DE E/S

    10.4. TÉCNICAS PARA LA ORGANIZACIÓN DE LA FUNCIÓN DE E/S

    10.5. CANALES DE E/S

    10.6. ESTRUCTURA LÓGICA DE LAS FUNCIONES DE E/S

    10.7. ALMACENAMIENTO INTERMEDIO DE E/S

    10.8. ENTRADA / SALIDA A DISCO

    10.9. TIPOS DE DISCOS

    CAPITULO 11. PARTE I: GESTION DE ARCHIVOS. (*)

    11.1.1. SISTEMAS DE GESTION DE ARCHIVOS

    11.1.2. FUNCIONES DEL FILE SYSTEM

    11.1.3. ARQUITECTURA DE UN FILE SYSTEM

    11.1.4. ORGANIZACIÓN Y ACCESO A ARCHIVOS

    11.1.5. OPERACIONES SOBRE UN ARCHIVO

    11.1.6. DIRECTORIOS DE ARCHIVOS

    11.1.7. COMPARTICIÓN DE ARCHIVOS

    11.1.8. AGRUPACIÓN DE REGISTROS

    11.1.9. CATALOGACION DE LOS ARCHIVOS EN EL SOPORTE

    11.1.10. GESTIÓN DEL ALMACENAMIENTO SECUNDARIO

    11.1.11. INTERCALADO DE DISCOS

    CAPITULO 11. PARTE II: FILE SYSTEM EN UNIX. I-NODOS. (*)

    11.2.1. SISTEMA DE ARCHIVOS EN LINUX

    11.2.2. TIPOS DE ARCHIVOS

    11.2.3. INODOS

    11.2.4. ASIGNACIÓN DE ARCHIVOS

    11.2.5. ESTRUCTURA FÍSICA DEL FILE SYSTEM

    11.2.6. RESIDENCIA DEL FILE SYSTEM

    11.2.7. MONTAJE DE UN FILE SYSTEM

    CAPITULO 12: REDES Y PROCESO DISTRIBUIDO. (*)

    12.1. REDES Y PROCESO DISTRIBUIDO

    12.2. ARQUITECTURA DE COMUNICACIONES

    12.3. PROCESO CLIENTE / SERVIDOR

    12.4. PROCESO DISTRIBUIDO MEDIANTE ENVIO DE MENSAJES

    12.5. PROCESO DISTRIBUIDO MEDIANTE LLAMADAS A PROCEDIMIENTOS REMOTOS

    APENDICE 1: JERARQUIAS DE MEMORIA (*)

    APENDICE 2: CONTROL DE PROCEDIMIENTOS (*)

    APENDICE 3: GESTION DE MEMORIA. CARGA Y MONTAJE. (*)

    APENDICE 4: COMPARACION DE FILE SYSTEMS EN DISTINTOS SISTEMAS OPERATIVOS (*)

    APENDICE 5: WINDOWS NT (*)

    APENDICE 6: UNIX (*)

    APENDICE 7: MVS (Multiple Virtual Storage) (*)

     (*)Para ver el texto completo seleccione la opción "Descargar" del menú superior

    Universidad Tecnológica Nacional

    Realizado entre marzo y mayo de 2005.

    Enviado por: