initial commit
[pfinal.git] / Routix / src / mm / kalloc.c
blobb0a43a88c9952cbd68357e9c1be54ba96f1c5566
1 /*! \addtogroup MemoryManager
2 \page kalloc.c
3 Administra la memoria del kernel.
4 */
7 #ifndef __SYSTEM
8 #include "routix/system.h"
9 #endif
10 #include <routix/kstdio.h>
11 #include <routix/kalloc.h>
12 #include "routix/task.h"
13 #include "error.h"
14 #include "routix/debug.h"
15 #include "routix/paging.h"
17 #include "routix/misc.h"
20 addr_t *_inicio,*_fin,*_sp;
26 * _inicio -> |---------------|
27 * | |
28 * | |
29 * | |
30 * _sp -> |xxxxxxxxxxxxxxx|
31 * | |
32 * | |
33 * _fin -> |---------------|
35 * */
38 //! \brief Inicializa el stack que almacena las páginas libres
39 int kmalloc_page_start (addr_t *inicio, addr_t *fin)
41 _inicio = inicio;
42 _fin = fin;
43 _sp = fin;
44 return OK;
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);
53 *_sp-- = direccion;
55 return 1;
59 addr_t kmalloc_page()
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()
70 addr_t direccion;
72 // if ((_fin - _sp) < 20)
74 if ( _sp > _fin ) {
75 kpanic("No hay mas memoria disponible\n");
76 return NULL;
79 _sp++;
80 direccion = *_sp;
82 if (getvar("mmdebug")==1)
83 kprintf("KMALLOC: _inicio=0x%x _fin=0x%x _sp=0x%x - valor: %x\n",_inicio,_fin,_sp,direccion);
85 return 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)
95 word i;
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)
109 int memoria_libre;
110 int mm_stack_size,paginas;
111 int pagina,pag;
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 );
132 else {
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)
147 return (_fin - _sp);
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();
162 if (!aux) {
163 kprintf("umalloc_page(): error 1: No free memory\n");
164 actual->err_no = ENOMEM;
165 return NULL;
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");
170 return NULL;
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));
175 // DEBUG
176 umalloc_alloc++;
178 if (!mem) {
179 kprintf("umalloc_page(): error 2: No free memory\n");
180 kfree_page (aux);
181 actual->err_no = ENOMEM;
182 return NULL;
184 mem->dir = aux;
185 mem->vdir = vdir;
186 mem->flags = flags;
187 mem->count = 1;
188 mem->next = NULL;
189 return mem;
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
199 return aux;
201 if (aux->dir) // Si no, la libero
202 kfree_page(aux->dir);
204 // DEBUG
205 umalloc_free++;
207 //free(aux); // Libero el nodo
208 FREE(MM_WRAPPER_USERPAGE,aux); // Libero el nodo
209 return NULL;