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
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