12.10.2014 Views

TEMA 3. GESTIÓN DE MEMORIA - Universidad de Almería

TEMA 3. GESTIÓN DE MEMORIA - Universidad de Almería

TEMA 3. GESTIÓN DE MEMORIA - Universidad de Almería

SHOW MORE
SHOW LESS

You also want an ePaper? Increase the reach of your titles

YUMPU automatically turns print PDFs into web optimized ePapers that Google loves.

Diseño <strong>de</strong> Sistemas Operativos<br />

Tema <strong>3.</strong> Gestión <strong>de</strong> Memoria<br />

Un pregunta que en este momento pue<strong>de</strong> hacerse es la siguiente: ¿cuál es el rango <strong>de</strong> direcciones lineales<br />

para asignar en calidad <strong>de</strong> áreas <strong>de</strong> memoria no contigua?. Des<strong>de</strong> 0 a PAGE_OFFSET – 1 está reservado<br />

para procesos. Recor<strong>de</strong>mos que el kernel inicialmente mapea la memoria física existente a partir <strong>de</strong><br />

PAGE_OFFSET (comienzo <strong>de</strong>l cuarto GigaByte). El final <strong>de</strong> la memoria física está en la variable<br />

high_memory. Des<strong>de</strong> high_memory hasta el final, está disponible. Se <strong>de</strong>jan 8 MBytes <strong>de</strong> margen a partir <strong>de</strong><br />

high_memory, VMALLOC_START, y 4 KBytes entre áreas no contiguas asignadas. VMALLOC_END<br />

<strong>de</strong>fine la dirección final <strong>de</strong>l espacio lineal reservado para áreas <strong>de</strong> memoria no contiguas.<br />

Figura <strong>3.</strong>15. El intervalo <strong>de</strong> dirección lineal empezando <strong>de</strong>s<strong>de</strong> PAGE_OFFSET<br />

Descriptores <strong>de</strong> áreas <strong>de</strong> memoria no contiguas ⇒ cada área <strong>de</strong> memoria no contigua va asociada a un<br />

<strong>de</strong>scriptor <strong>de</strong> tipo struct vm_struct que tiene la siguiente estructura (flags, dirección <strong>de</strong> comienzo, tamaño,<br />

puntero al siguiente <strong>de</strong>scriptor):<br />

struct vm_struct {<br />

unsigned long flags;<br />

void *addr;<br />

unsigned long size;<br />

struct vm_struct *next;<br />

};<br />

Se mantienen los <strong>de</strong>scriptores <strong>de</strong> áreas <strong>de</strong> memoria no contiguas en una lista enlazada con direcciones en<br />

or<strong>de</strong>n creciente para facilitar la s búsquedas, y la búsqueda <strong>de</strong> regiones libres <strong>de</strong> memoria lineal. La función<br />

get_vm_area() crea nuevos <strong>de</strong>scriptores <strong>de</strong>l tipo vm_struct, llamando en su interior a la función kmalloc.<br />

Asignación y liberación ⇒ una vez se obtiene el rango <strong>de</strong> direcciones lineal, se asignan las páginas, y para<br />

cada una <strong>de</strong> ellas: (1) se han <strong>de</strong> modificar las tablas <strong>de</strong> páginas (incluidos PMD y PGD); (2) se pi<strong>de</strong>n las<br />

páginas al Buddy system con __get_free_paqe().<br />

Para asignar área <strong>de</strong> memoria no contigua el kernel utiliza la función vmalloc que se encuentra <strong>de</strong>clarada en<br />

el archivo cabecera . Esta función llama a get_vm_area() para crear un nuevo<br />

<strong>de</strong>scriptor y <strong>de</strong>volver la dirección lineal asignada al área <strong>de</strong> memoria. También llama a vmalloc_area_pages()<br />

marcos <strong>de</strong> página no contiguos. Y termina <strong>de</strong>volviendo la dirección lineal inicial <strong>de</strong>l área <strong>de</strong> memoria no<br />

contigua. Para liberar área <strong>de</strong> memoria no contigua el kernel utiliza la función vfree(). En primer lugar se<br />

llama a vmlist() para encontrar la dirección lineal <strong>de</strong>l <strong>de</strong>scriptor <strong>de</strong>l área asociada al área a liberar. El área en<br />

sí es liberada llamando a vmfree_area_pages(), mientras que el <strong>de</strong>scriptor es liberado llamando a kfree().<br />

<strong>3.</strong>4.<strong>3.</strong>7. Memoria para Procesos<br />

Como acabamos <strong>de</strong> ver, una <strong>de</strong> las funciones <strong>de</strong>l kernel es obtener memoria dinámica <strong>de</strong> forma sencilla<br />

llamando a una variedad <strong>de</strong> funciones: __get_free_pages() o pages_alloc() para obtener páginas <strong>de</strong>l<br />

algoritmo <strong>de</strong>l Buddy system; kmem_cache_alloc() o kmalloc() para utilizar el Slab allocator para objetos <strong>de</strong><br />

propósito general o específico, y vmalloc() para obtener un área <strong>de</strong> memoria no contigua. En estos casos, si la<br />

petición pue<strong>de</strong> realizarse satisfactoriamente, cada una <strong>de</strong> estas funciones <strong>de</strong>vuelve una dirección <strong>de</strong>l<br />

<strong>de</strong>scriptor <strong>de</strong> página o una dirección lineal i<strong>de</strong>ntificando el principio <strong>de</strong>l área <strong>de</strong> memoria dinámica asignada.<br />

Cuando se asigna memoria a procesos en modo usuario, la situación es diferente: (1) Los procesos que<br />

<strong>de</strong>mandan memoria dinámica se consi<strong>de</strong>ran no urgentes. Cuando se carga el archivo ejecutable <strong>de</strong> un<br />

proceso, es poco probable que el proceso direccionará todas las páginas <strong>de</strong> código en un futuro próximo.<br />

Equivalentemente, cuando un proceso llama a la función malloc() para obtener memoria dinámica adicional,<br />

esto no quiere <strong>de</strong>cir que el proceso acce<strong>de</strong>rá pronto a toda la memoria adicional obtenida. Por tanto, como<br />

Departamento <strong>de</strong> Lenguajes y Computación. <strong>Universidad</strong> <strong>de</strong> Almería Página <strong>3.</strong>36

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!