00001
00007 #ifndef __SYSTEM
00008 #include "routix/system.h"
00009 #endif
00010 #include <routix/kstdio.h>
00011 #include "routix/kalloc.h"
00012 #include "routix/task.h"
00013 #include "error.h"
00014 #include "routix/debug.h"
00015 #include "routix/paging.h"
00016
00017 #include "routix/misc.h"
00018
00019 addr_t *_inicio,*_fin,*_sp;
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035
00036
00038 int kmalloc_page_start (addr_t *inicio, addr_t *fin)
00039 {
00040 _inicio = inicio;
00041 _fin = fin;
00042 _sp = fin;
00043 return OK;
00044 }
00045
00047 int kfree_page(addr_t direccion)
00048 {
00049 if ( _sp < _inicio ) { return NULL; }
00050 if (getvar("mmdebug")==1)
00051 kprintf("KFREE: 0x%x\n", direccion);
00052 *_sp-- = direccion;
00053
00054 return 1;
00055 }
00056
00057
00058 addr_t kmalloc_page()
00059 {
00060 return get_free_page();
00061 }
00062
00066 addr_t get_free_page()
00067 {
00068
00069 addr_t direccion;
00070
00071 if ( _sp > _fin ) { return NULL; }
00072
00073 _sp++;
00074 direccion = *_sp;
00075
00076 if (getvar("mmdebug")==1)
00077 kprintf("KMALLOC: _inicio=0x%x _fin=0x%x _sp=0x%x - valor: %x\n",_inicio,_fin,_sp,direccion);
00078
00079 return direccion;
00080 }
00081
00082
00087 void print_free_pages(word cant)
00088 {
00089 word i;
00090 for(i=0 ; i<cant ; i++)
00091 kprintf("Direccion: %x\n", *(_sp+i));
00092 }
00093
00094
00095
00100 void inicializacion_kmalloc(int memoria_fisica, int memoria_kernel)
00101 {
00102
00103 int memoria_libre;
00104 int mm_stack_size,paginas;
00105 int pagina,pag;
00106
00107 memoria_libre = memoria_fisica - memoria_kernel / 0x100000;
00108
00109 kprintf("Memoria: \tInstalada %d Mb\tKernel %d Mb\tLibre %d Mb\n",memoria_fisica, memoria_kernel/0x100000,memoria_libre);
00110
00111 paginas = 1024*1024*memoria_libre / 4096;
00112 mm_stack_size = 4 * paginas;
00113
00114 kprintf("El tamanio del stack de kmalloc_page para %d paginas es %d bytes - ",paginas,mm_stack_size);
00115 kprintf("Inicio: 0x%x - Fin: 0x%x\n",memoria_kernel, memoria_kernel + mm_stack_size);
00116
00117
00118 kmalloc_page_start( (dword *) memoria_kernel, (dword *) ( memoria_kernel + mm_stack_size ) );
00119
00120
00121 pagina = memoria_kernel + mm_stack_size;
00122
00123 if ( pagina & 0xfff ) {
00124 pagina += 0x1000 - ( pagina & 0xfff );
00125 }
00126 else {
00127 pagina = 0x1000 + pagina;
00128 }
00129
00130
00131 for( pag=((memoria_fisica*1024*1024)&0xfffff000)-4096 ; pag >= pagina ; pag -= 0x1000 ) {
00132 if ( kfree_page( (dword) pag ) == NULL ) { puts("error\n"); }
00133 }
00134
00135
00136 }
00137
00139 inline dword kmem_free (void)
00140 {
00141 return (_fin - _sp);
00142 }
00143
00144
00145
00146
00153 struct user_page *umalloc_page ( word flags, addr_t vdir, addr_t cr3)
00154 {
00155 addr_t aux = get_free_page();
00156 if (!aux) {
00157 actual->err_no = ENOMEM;
00158 return NULL;
00159 }
00160
00161 if (kmapmem( aux , vdir , cr3 , PAGE_PRES|PAGE_USER|PAGE_RW) !=OK) {
00162 kprintf("umalloc_page: KMAPMEM error...\n");
00163 return NULL;
00164 }
00165
00166 struct user_page *mem = (struct user_page *) malloc (sizeof(struct user_page));
00167
00168 umalloc_alloc++;
00169
00170 if (!mem) {
00171 kfree_page (aux);
00172 actual->err_no = ENOMEM;
00173 return NULL;
00174 }
00175 mem->dir = aux;
00176 mem->vdir = vdir;
00177 mem->flags = flags;
00178 mem->count = 1;
00179 mem->next = NULL;
00180 return mem;
00181 }
00182
00186 struct user_page *ufree_page (struct user_page *aux)
00187 {
00188 aux->count--;
00189 if (aux->count > 0)
00190 return aux;
00191
00192 if (aux->dir)
00193 kfree_page(aux->dir);
00194
00195
00196 umalloc_free++;
00197
00198 free(aux);
00199 return NULL;
00200 }
00201