1 /*! \addtogroup MemoryManager
3 Administra la memoria del kernel.
8 #include "routix/system.h"
10 #include <routix/kstdio.h>
11 #include <routix/kalloc.h>
12 #include "routix/task.h"
14 #include "routix/debug.h"
15 #include "routix/paging.h"
17 #include "routix/misc.h"
20 addr_t
*_inicio
,*_fin
,*_sp
;
26 * _inicio -> |---------------|
30 * _sp -> |xxxxxxxxxxxxxxx|
33 * _fin -> |---------------|
38 //! \brief Inicializa el stack que almacena las páginas libres
39 int kmalloc_page_start (addr_t
*inicio
, addr_t
*fin
)
47 //! \brief Retorna al stack una página que el kernel no utiliza
48 int kfree_page(addr_t direccion
)
50 if ( _sp
< _inicio
) { return NULL
; }
51 if (getvar("mmdebug")==1)
52 kprintf("KFREE: 0x%x\n", direccion
);
61 return get_free_page();
64 /*! \brief Entrega una página de memoria
65 * \return addr_t dirección de la página
67 addr_t
get_free_page()
72 // if ((_fin - _sp) < 20)
75 kpanic("No hay mas memoria disponible\n");
82 if (getvar("mmdebug")==1)
83 kprintf("KMALLOC: _inicio=0x%x _fin=0x%x _sp=0x%x - valor: %x\n",_inicio
,_fin
,_sp
,direccion
);
89 /*! \brief Imprime la ubicación de páginas libres
90 * \param Cantidad de páginas de las cuales se desea conocer su dirección
91 * \note Utilizada para propósitos de debug
93 void print_free_pages(word cant
)
96 for(i
=0 ; i
<cant
; i
++)
97 kprintf("Direccion: %x\n", *(_sp
+i
));
102 /*! Bien, supongamos ahora que determinamos la cantidad de memoria del sistema
103 * en función de esa cantidad armamos el área de stack necesaria para pushear
104 * bloques de 4Kb (memoria física libre)
106 void inicializacion_kmalloc(int memoria_fisica
, int memoria_kernel
)
110 int mm_stack_size
,paginas
;
113 memoria_libre
= memoria_fisica
- memoria_kernel
/ 0x100000;
115 kprintf("Memoria: \tInstalada %d Mb\tKernel %d Mb\tLibre %d Mb\n",memoria_fisica
, memoria_kernel
/0x100000,memoria_libre
);
117 paginas
= 1024*1024*memoria_libre
/ 4096;
118 mm_stack_size
= 4 * paginas
;
120 kprintf("El tamanio del stack de kmalloc_page para %d paginas es %d bytes - ",paginas
,mm_stack_size
);
121 kprintf("Inicio: 0x%x - Fin: 0x%x\n",memoria_kernel
, memoria_kernel
+ mm_stack_size
);
124 kmalloc_page_start( (dword
*) memoria_kernel
, (dword
*) ( memoria_kernel
+ mm_stack_size
) );
126 /* Determinamos la primer pagina de memoria libre */
127 pagina
= memoria_kernel
+ mm_stack_size
;
129 if ( pagina
& 0xfff ) {
130 pagina
+= 0x1000 - ( pagina
& 0xfff );
133 pagina
= 0x1000 + pagina
;
137 for( pag
=((memoria_fisica
*1024*1024)&0xfffff000)-4096 ; pag
>= pagina
; pag
-= 0x1000 ) {
138 if ( kfree_page( (dword
) pag
) == NULL
) { puts("error\n"); }
144 //! Retorna la cantidad de poáginas disponibles
145 inline dword
kmem_free (void)
153 /*! \brief Pide una pagina, completa la estructura user_page, y la mapea en la dirección lógica
154 * \param flags: tipo de pagina
155 * \param vdir: dirección lógica donde se ubicará la página
156 * \param cr3: dirección del directorio de páginas
159 struct user_page
* umalloc_page ( word flags
, addr_t vdir
, addr_t cr3
)
161 addr_t aux
= get_free_page();
163 kprintf("umalloc_page(): error 1: No free memory\n");
164 actual
->err_no
= ENOMEM
;
167 // Deberia mapear segun los flags que recibo
168 if (kmapmem( aux
, vdir
, cr3
, PAGE_PRES
|PAGE_USER
|PAGE_RW
) !=OK
) {
169 kprintf("umalloc_page: error kmapmem\n");
173 //struct user_page *mem = (struct user_page *) malloc (sizeof(struct user_page));
174 struct user_page
*mem
= (struct user_page
*) MALLOC(MM_WRAPPER_USERPAGE
,sizeof(struct user_page
));
179 kprintf("umalloc_page(): error 2: No free memory\n");
181 actual
->err_no
= ENOMEM
;
192 /*! Libera una estructura descriptora de pagina de tarea (solo si no esta siendo utilizada por otro proceso)
193 * incluyendo al nodo que contiene su direccion
195 struct user_page
* ufree_page (struct user_page
*aux
)
197 aux
->count
--; // Un proceso menos que refiere a esta pagina
198 if (aux
->count
> 0) // Si alguien sigue utilizandola, me voy
201 if (aux
->dir
) // Si no, la libero
202 kfree_page(aux
->dir
);
207 //free(aux); // Libero el nodo
208 FREE(MM_WRAPPER_USERPAGE
,aux
); // Libero el nodo