Segmentación y ejemplos de utilización

De Departamento de Informatica
Saltar a: navegación, buscar

Contenido

Segmentación

Es un esquema de manejo de memoria mediante el cual la estructura del programa refleja su división lógica, llevándose a cabo una agrupación lógica de la información en bloques de tamaño variable denominados segmentos. Cada uno de ellos tienen información lógica del programa. Luego cada espacio de direcciones de programa consiste de una colección de segmentos, que generalmente reflejan la división lógica del programa.

Conceptualizacion de un programa en bloques, o conjuntos


Dicho lo anterior, pensemos en cuando programamos. Por lo general vemos a los elementos de nuestro programa conceptualmente, es decir nos preocupamos de la función, de la estructura de datos, programa principal, variables globales, etc. Poco nos importa su código binario, o como estos se almacenan en memoria principal. Cada uno de estos elementos o segmentos de código posee una longitud, que varia en cada uno y cada elemento dentro de un segmento se identifica por la posición respecto del inicio, de este (por ejemplo al referirnos a un valor guardado en un arreglo decimos Array[8], osea el elemento almacenado nueve posiciones respecto de la inicial).Ver figura a la izquierda.


La segmentación es un esquema que es mas compatible con esta visión de la memoria que poseen los programadores y usuarios en general (visión de conjuntos, mas que elementos linealmente ordenados). Nos referimos entonces a un espacio lógico de direcciones lógicas como una colección de segmentos, cada uno con nombre y longitud. Las direcciones especifican el nombre del segmento y el desplazamiento respecto del inicio de este. Esto le permite al usuario especificar nombre de segmento y desplazamiento, es decir esta a la vista del programador. El nombre es un numero y entonces para referirnos a un segmento utilizamos una 2-tupla:


(Selector , Desplazamiento)


Siendo el selector el identificador y el desplazamiento la brecha respecto del inicio de este. Para almacenar los diferentes elementos asignados en segmentos debemos transformar esta tupla en la dirección de byte apropiada. Esto se hace mediante una tabla de segmentos que tiene almacenada una dirección base y un limite para cada segmento, la cual usa como indice el numero de segmento que mencionamos anterioremente o el selector. Esto se hace mediante hardware siguiendo el siguiente esquema:

Organizacion del Hardware para segmentación

Tengamos presente, a modo de ejemplo explicativo, la estructura lógica un programa cualquiera que posee una subroutina, pila, programa principal, una función sqrt, y una tabla de símbolos, cada uno de estos con un segmento asociado en la tabla de segmentación, la cual hace direccionamiento a la memoria física. Como se aprecia en la siguiente figura:

Ejemplo de Segmentación, representación en la tabla de segmentos, y en la memoria física - Imagen del libro "Fundamentos de sistemas operativos"


Objetivos de la segmentación

La segmentación permite alcanzar los siguientes objetivos:

Modularidad de programas: Cada rutina del programa puede ser un bloque sujeto a cambios y recopilaciones, sin afectar al resto del programa.

Estructura de datos de largo variable: Donde cada estructura tiene su propio tamaño y este puede variar. Ej: Stack.

Protección: Se pueden proteger los módulos del segmento contra accesos no autorizados.

Compartición: Dos o más procesos pueden ser un mismo segmento, bajo reglas de protección; aunque no sean propietarios de los mismos.

Enlace dinámico entre segmentos: Puede evitarse realizar todo el proceso de enlace antes de comenzar a ejecutar un programa. Los enlaces se establecerán solo cuando sea necesario.



Ventajas de la segmentación

El esquema de segmentación ofrece las siguientes ventajas:

  • El programador puede conocer las unidades lógicas de su programa, dándoles un tratamiento particular.
  • Es posible compilar módulos separados como segmentos el enlace entre los segmentos puede suponer hasta tanto se haga una referencia entre segmentos.
  • Debido a que es posible separar los módulos, se hace más fácil la modificación de los mismos. Cambios dentro de un modulo no afecta al resto de los módulos.
  • Es fácil el compartir segmentos.
  • Es posible que los segmentos crezcan dinámicamente según las necesidades del programa en ejecución.
  • Existe la posibilidad de definir segmentos que aun no existan. Así, no se asignará memoria, sino a partir del momento que sea necesario hacer usos del segmento. Un ejemplo de esto, serían los arreglos cuya dimensión no se conoce hasta tanto no se comienza a ejecutar el programa. En algunos casos, incluso podría retardar la asignación de memoria hasta el momento en el cuál se referencia el arreglo u otra estructura de datos por primera vez.



Desventaja de la segmentación

  • Hay un incremento en los costos de hardware y de software para llevar a cabo la implantación, así como un mayor consumo de recursos: memoria, tiempo de CPU, etc.
  • Debido a que los segmentos tienen un tamaño variable se pueden presentar problemas de fragmentación externas, lo que puede ameritar un plan de reubicación de segmentos en memoria principal.
  • Se complica el manejo de memoria virtual, ya que los discos almacenan la información en bloques de tamaños fijos, mientras los segmentos son de tamaño variable. Esto hace necesaria la existencia de mecanismos más costosos que los existentes para paginación.
  • Al permitir que los segmentos varíen de tamaño, pueden ser necesarios planes de reubicación a nivel de los discos, si los segmentos son devueltos a dicho dispositivo, lo que conlleva a nuevos costos.
  • No se puede garantizar que al salir un segmento de la memoria, este pueda ser traído fácilmente de nuevo, ya que será necesario encontrar nuevamente un área de memoria libre ajustada a su tamaño.
  • La compartición de segmentos permite ahorrar memoria, pero requiere de mecanismos adicionales da hardware y software.

Estas desventajas tratan de ser minimizadas, bajo la técnica conocida como Segmentación paginada.


.

Segmentación paginada

Paginación y segmentación son técnicas diferentes, cada una de las cuales busca brindar las ventajas enunciadas anteriormente. Para la segmentación se necesita que estén cargadas en memoria áreas de tamaños variables. Si se requiere cargar un segmento en memoria que antes estuvo en ella y fue removido a memoria secundaria, se necesita encontrar una región de la memoria lo suficientemente grande para contenerlo, lo cual no es siempre factible. En cambio recargar una página implica sólo encontrar un marco de página disponible.

A nivel de paginación, si quiere referenciar en forma cíclica n paginas, estas deberán ser cargadas una a una, generándose varias interrupciones por fallas de páginas. Bajo segmentación, esta página podría conformar un sólo segmento, ocurriendo una sola interrupción por falla de segmento. No obstante, si bajo segmentación se desea acceder un área muy pequeña dentro de un segmento muy grande, este deberá cargarse completamente en memoria, desperdiciándose memoria. Bajo paginación sólo se cargará la página que contiene los ítems referenciados.

Puede hacerse una combinación de segmentación y paginación para obtener las ventajas de ambas. En lugar de tratar un segmento como una unidad contigua, éste puede dividirse en páginas. Cada segmento puede ser descrito por su propia tabla de páginas.

Los segmentos son usualmente múltiplos de páginas en tamaño, y no es necesario que todas las páginas se encuentren en memoria principal a la vez. Además, las páginas de un mismo segmento, aunque se encuentren contiguas en memoria virtual, no necesitan estarlo en memoria real. Las direcciones tienen tres componentes: (s, p, d), donde la primera indica el número del segmento, la segunda el número de la página dentro del segmento y la tercera el desplazamiento dentro de la página.


Tablas de segmentación paginada

Se deberán usar varias tablas:

  • Tabla de mapas de segmentos (SMT): Una para cada proceso. En cada entrada de la SMT se almacena la información descrita bajo segmentación pura, pero en el campo de dirección se indicara la dirección de la PMT (tabla de mapas de páginas) que describe a las diferentes páginas de cada segmento.
  • Tabla de mapas de páginas (PMT): Una por segmento; cada entrada de la PMT describe una página de un segmento, en la forma que se presentó la pagina pura.
  • Tabla de bloques de memoria (TBM): Para controlar asignación de páginas por parte del sistema operativo.
  • Tabla de Jobs (JT): Que contiene las direcciones de comienzo de cada una de las SMT de los procesos que se ejecutan en memoria.

En el caso de que un segmento sea de tamaño inferior o igual al de una página, no se necesita tener la correspondiente PMT, actuándose en igual forma que bajo segmentación pura. Puede arreglarse un bit adicional (S) a cada entrada de la SMT, que indicará si el segmento está paginado o no.


Ventajas de la segmentación paginada

El esquema de segmentación paginada tiene todas las ventajas de la segmentación y la paginación:

  • Debido a que los espacios de memorias son segmentados, se garantiza la facilidad de implantar la compartición y enlace.
  • Como los espacios de memoria son paginados, se simplifican las estrategias de almacenamiento.
  • Se elimina el problema de la fragmentación externa y la necesidad de compactación.


Desventajas de la segmentación paginada

  • Los tres componentes de la dirección y el proceso de formación de direcciones hace que se incremente el costo de su implantación. El costo es mayor que en el caso de de segmentación pura o paginación pura.
  • Se hace necesario mantener un número mayor de tablas en memoria, lo que implica un mayor costo de almacenamiento.
  • Sigue existiendo el problema de fragmentación interna de todas -o casi todas- las páginas finales de cada uno de los segmentos. Bajo paginación pura se desperdicia sólo la última página asignada, mientras que bajo segmentación paginada el desperdicio puede ocurrir en todos los segmentos asignados.


.

Consideraciones Respecto de la Gestion de Memoria

Para terminar el tema paginación y segmentación es útil saber ciertos datos.Si bien los diversos métodos de Gestión de memoria poseen cada uno ventajas y desventajas propias, al diseñar un sistema complejo debemos tener en primera consideración el Hardware hacia el cual esta orientado. Debemos recordar que el hardware se encarga de manera eficiente de tareas como la verificación de legalidad de una dirección, y el mapeo sobre la memoria física.

Es por eso que al optar por un algoritmo de gestion de memoria u otro, debemos considerar diversos aspectos, no solo su ventajas, desventajas y eficiencia propios a cada uno. Debemos tener en cuenta:

  • Soporte de Hardware: Si bien un esquema de partición simple tiene suficiente con la existencia de un registro base, esquemas mas complejos como segmentación o paginación en niveles, necesitan de tablas de mapeo para direccionar.
  • Rendimiento: Con el aumento de la complejidad del algoritmo de gestión de memoria, el rendimiento disminuye, es decir, cada vez se tarda mas en mapear una dirección lógica en una dirección física.
  • Fragmentación: los sistemas multiprogramados logran una mayor eficiencia si poseen un alto grado de multiprogramación, sin embargo para aprovechar al máximo las capacidades de un sistema multiprogramado debemos lograr que quepan mas procesos de memoria, para lo que es necesario reducir la memoria desperdiciado por fragmentación. Sistemas con unidades de asignación de tamaño fijo tiene el problema de fragmentación interna y los de unidades de asignación de tamaño variable presenta el problema de la fragmentación externa.
  • Reubicación: para apalear el problema de fragmentación externa es la compactación e implica mover un programa en memoria de modo que este no se de cuenta. este proceso necesita que las direcciones lógicas se reubiquen dinámicamente en tiempo de ejecución, de otra forma no es posible la compactación.
  • Intercambio: Se refiere a volcar procesos de memoria principal a almacenamiento secundario o dispositivos de respaldo, y viceversa. De esta forma se logra tener mas programas en memoria de los que normalmente cabrían.
  • Compartición: Es otro metodo para incrementar el nivel de multiprogramacion, que consiste en compartir el codigo y datos de un proceso entre distintos usuarios. Es un metodo de ejecutar multiples procesos en una cantidad limitada de memoria.
  • Protección: Al implementar algun mecanismo de segmentacion o paginacion es necesario diferenciar las partes de un programa en lectura, escritura, lectura-escritura, etc. Es necesaria, por ejemplo, para segmentos compartidos con el fin de evitar errores.


.

Ejemplos de Segmentación

Como vimos anteriormente la segmentación, como la mayoría de los sistemas, presenta tanto ventajas como desventajas, al igual que la paginación. Es por lo anterior que algunos arquitecturas soportan ambas, así como algunos sistemas operativos harán mayor uso de uno que de otro. Sin embargo la segmentación se encuentra principalmente en sistemas antiguos, y ha sido desplazada por técnicas de paginacion. El primer computador en implementar segmentación fue el Burroughs Corporation B5000. A continuación analizaremos el mecanismo de segmentación del Procesador Pentium para luego revisar la utilización (de la segmentación) por parte de un sistema Linux.



El caso Pentium

En una arquitectura Pentium, la CPU entrega las direcciones lógicas generadas a la unidad de segmentación, la cual produce una dirección lineal. Esta dirección lineal es luego enviada a la unidad de paginación, generando finalmente la dirección física, del tipo 0X0F8C9DAB, por ejemplo.


Encerrado en el cuadrado rojo es el Unidad de Administración de Memoria (MMU por sus siglas en inglés).


  • Un segmento puede tener un máximo de 4 GB
  • Para cada proceso el número máximo de segmentos es de 16KB
  • El espacio lógico de un proceso se divide en 2:
  1. primera partición de hasta 8 KB segmentos privados al proceso. La información de ella se almacena en la tabla local de descriptores (LDT por sus siglas en inglés)
  2. Segunda partición de hasta 8 KB, segmentos compartidos entre todos los procesos. La información de ella se almacena en la tabla global de descriptores (GDT por sus siglas en inglés)

Las entradas tanto de la LDT como de la GDT están descritas por un descriptor de segmentos de 8 bytes, que da información como posición base y limite de segmento. Es una 2-tupla de la forma (selector, desplazamiento):

  • El selector es un numero de 16 bits con sus trece primeros bits designado el numero de segmento, 1 bit indicando si esta en GDT o LDT y los 2 bits restantes de protección.
  • El desplazamiento especifica la ubicación de la palabra dentro del segmento, es un numero de 32 bits que guarda la ubicación del byte.

La siguiente figura ilustra la estructura de de una dirección lógica (2-tupla), con su selector y su desplazamiento (a menudo referido como offset):


Forma de dirección lógica (dirección, desplazamiento) en procesadores Pentium.


Ademas la arquitectura Pentium posee 6 registros de segmento, permitiendo al procesador direccionar hasta 6 segmentos distintos, en cualquier momento. Ademas 6 registros de 8 bytes, para guardar los descriptores LDT o GDT, según corresponda.

Esquema de Segmentación en Intel Pentium, transformación de dirección lógica a Lineal


A partir de la dirección lógica, cuya estructura describimos anteriormente, debemos generar nuestro dirección lineal, interpretable por la unidad de paginación. El proceso para generar la dirección lineal es el siguiente:

  • Debemos considerar que el registro de segmento respectivo apunta a entrada de LDT o GDT, ya que la información de base y limite del segmento se usa para generar la dirección lineal.
  • Verifica el limite para revisar la validez de la dirección. Dando dos alternativas:

- Si no es valido, se genera un fallo de memoria, y la consiguiente interrupción al sistema operativo.

- Si es valido, entonces se suma el valor del desplazamiento al valor de la base, dando como resultado una dirección de 32 bits.

El proceso se muestra en la figura a la izquierda. Luego el trabajo de convertir las direcciones lineales a direcciones físicas es trabajo de la unidad de paginación.


Segmentación en sistemas Linux

Segmentos en un sistemas Linux, no necesariamente en ese orden


Anteriormente vimos como manejaba la segmentación el procesador Intel Pentium. Ahora veremos como un sistema operativo, en este caso Linux, maneja segmentación con un procesador Pentium.


Dado que Linux es un sistema operativo para ejecutarse en procesadores muy variados, utiliza de forma mínima la segmentación (debe considerar aquellos procesadores con un pobre soporte para segmentación). En el procesador Pentium, Linux utiliza 6 segmentos:


  • 1 segmento para código del kernel y 1 segmento para los datos del kernel: Como su nombre lo indica están reservados para su uso por parte del kernel.
  • 1 segmento para el código de usuario, y 1 segmento para los datos de usuario: todos los proceso que se ejecutan en modo usuario comparten estos segmentos, lo cual se hace posible debido a que usan el mismo espacio lógico de direcciones y la GDT(a modo de recordatorio: global descriptor table -> tabla Global de descriptores) almacena todos los descriptores de segmentos relacionados.
  • 1 segmento de estado de tareas (TSS por sus siglas en inglés): Aquí se almacena el contexto de hardware de cada proceso,para cada vez que se realiza un Cambio de Contexto (Context Switch). Cada proceso tiene su TSS y el descriptor de este segmento se almacena en la GDT.
  • 1 segmento LDT predeterminado: Es compartido por todos los procesos y no se utiliza frecuentemente. Su uso es para el caso especifico que un proceso requiera su LDT, para lo cual puede reservar un lugar de esta LDT predeterminada.


Como vimos anteriormente, Pentium designa dos bits de protección a cada selector de segmento, por lo cual permite 4 niveles de proteccion (22). Sin embargo Linux solo reconoce modo usuario y modo kernel, es decir solo utiliza 2 niveles.



Arquitectura x86_64

la arquitectura de 64 bits de AMD, no soporta segmentacion. Por lo tanto, no tienen las latencias asociadas con almacenar y recuperar la información de segmentación ni tienen que realizar las comprobaciones necesarias de protección a nivel de segmentación. Lo cual se traduce en llamadas al sistema mas rápidas.

Un ejercicio ejemplificador

1.- considere una direccion logica de n+m, siendo n el selector y m el desplazamiento. Si n = 4 y m = 12, entonces:

  • ¿Cual es el tamaño de segmento máximo de segmento?

Resp: es el maximo numero posible obtenido con la cantidad de bits del desplazamiento de la direccion lógica, o sea 212.

  • En la tabla abajo señalada. ¿Cual es el segmento en el que se encuentra una direccion logica con selector = 2?

Resp:

  • ¿Cuales son los pasos para la traducción de direcciones?

Resp:

- Extraer el numero de segmento como los n bits de la izquierda de la dirección lógica.

- Utilizar el numero de segmento como un índice a la tabla de segmentos del proceso para encontrar la dirección física inicial del segmento.

- Comparar el desplazamiento, expresado como los m bits de la derecha, y la longitud del segmento. Si el desplazamiento es mayor o igual que la longitud, la dirección no es valida.

- La dirección física deseada es la suma de la dirección física inicial y el desplazamiento.


2.- Considerando una direccion logica de tamaño n+m bits, con n = 4 y m = 12. Si se obtiene la direccion logica 0001001011110000, y la direccion fisica de inicio del segmento es 0010000000100000, responda:

  • ¿En que segmento se ubica esta direccion?

Resp: Consideremos los primeros 4 bits de la direccion logica, es 00012 o 110, por lo que se encuentra en el segmento numero 1.

  • ¿Cual es la tupla correspondiente a esta direccion logica?

Resp: (1, 752).

  • ¿Determina la dirección de física de la dirección lógica dada?

Resp: Para la dirección física debemos considerar el desplazamiento de la dirección lógica de y la dirección física de inicio del segmento. Dado que el desplazamiento obedece a los 12 últimos bits, obtenemos:

direccionFisica = direccionInicioSegmento + desplazamiento.

X = 0010000000100000 + 001011110000

Herramientas personales
Espacios de nombres
Variantes
Acciones
Navegación
Herramientas