mm.c

Go to the documentation of this file.
00001 
00007 #include "routix/system.h"
00008 #include "routix/paging.h"
00009 #include "routix/segm.h"
00010 #include "routix/kalloc.h"
00011 #include "routix/task.h"
00012 #include "routix/debug.h"
00013 
00014 addr_t KERNEL_PDT = POSICION_DIR_PAGINAS;
00015 addr_t USER_PDT;
00016 
00017 void init_MM_base(void);
00018 dword contar_memoria (void);
00019 dword memoria;
00020 
00021 
00027 void init_MM_base()
00028 {
00029         page_index_t indice;
00030         pd_t *dir;
00031         pt_t *tabla;
00032         word i;
00033         gdtr_t *gdtr;
00034         descriptor_t *gdt;
00035 
00036         dir= (pd_t *) POSICION_DIR_PAGINAS;
00037 
00038         /* Mapear linealmente en Tabla 1 de 0-4MB (posicion fisica del kernel */
00039         indice=get_page_index( 0 );
00040         dir->entry[ indice.dir_index ]=make_pde (POSICION_TABLA_1, PAGE_PRES | PAGE_SUPER | PAGE_RW);
00041         tabla = (pt_t *) (dir->entry[ indice.dir_index ] & 0xfffff000);
00042         for(i=0 ; i < PAGINAS_POR_TABLA ; i++)
00043                 tabla->entry[i]= make_pte( i * PAGINA_SIZE, PAGE_PRES | PAGE_SUPER | PAGE_RW ) ;
00044 
00045 
00046         /* Mapear El codigo de kernel en 3GB (0xC0000000) */
00047         indice=get_page_index(KERNEL_CODE);
00048         dir->entry[ indice.dir_index ]=make_pde (POSICION_TABLA_KCODE, PAGE_PRES | PAGE_SUPER | PAGE_RW);
00049         tabla = (pt_t *) (dir->entry[ indice.dir_index ] & 0xfffff000);
00050         for(i=0 ; i < PAGINAS_POR_TABLA ; i++)
00051                 tabla->entry[i]= make_pte( KERNEL_FCODE + (i * PAGINA_SIZE), PAGE_PRES | PAGE_SUPER | PAGE_RW ) ;
00052 
00053         
00054         /* Mapear Los datos de kernel en 3GB + 128MB (0xC8000000) */
00055         indice=get_page_index(KERNEL_DATA);
00056         dir->entry[ indice.dir_index ]=make_pde (POSICION_TABLA_KDATA, PAGE_PRES | PAGE_SUPER | PAGE_RW);
00057         tabla = (pt_t *) (dir->entry[ indice.dir_index ] & 0xfffff000);
00058         for(i=0 ; i < PAGINAS_POR_TABLA ; i++)
00059                 tabla->entry[i]= make_pte( KERNEL_FDATA + (i * PAGINA_SIZE), PAGE_PRES | PAGE_SUPER | PAGE_RW ) ;
00060 
00061         /* Mapear el stack de kernel en 3GB + 128MB + 128Mb + 128MB - 128Kb
00062          * mapeamos desde el TOP 128Kb hacia arriba (32 páginas) */
00063 
00064         
00065         indice=get_page_index(KERNEL_STACK_TOP - KERNEL_STACK_SIZE);
00066         dir->entry[ indice.dir_index ]=make_pde (POSICION_TABLA_KSTACK, PAGE_PRES | PAGE_SUPER | PAGE_RW);
00067         tabla = (pt_t *) (dir->entry[ indice.dir_index ] & 0xfffff000);
00068         for(i=0 ; i < KERNEL_STACK_SIZE / PAGINA_SIZE; i++)
00069          tabla->entry[i+indice.tabla_index]= make_pte( KERNEL_FSTACK + (i * PAGINA_SIZE), PAGE_PRES | PAGE_SUPER | PAGE_RW );
00070 
00071 
00072         /* Cargamos ahora la gdt */
00073         gdtr = (gdtr_t *) POSICION_TABLA_GDT;
00074         gdt  = (descriptor_t *) POSICION_TABLA_GDT;
00075 
00076         *gdt++ = make_descriptor( 0, 0, 0, 0);
00077         *gdt++ = make_descriptor( 0, 0xfffff, PRESENTE | DPL_0 | GENERAL | CODIGO, GRANULARIDAD | DB);
00078         *gdt++ = make_descriptor( 0, 0xfffff, PRESENTE | DPL_0 | GENERAL | DATA | WRITE, GRANULARIDAD | DB);
00079         *gdt++ = make_descriptor( 0, 0xfffff, PRESENTE | DPL_3 | GENERAL | CODIGO, GRANULARIDAD | DB);
00080         *gdt++ = make_descriptor( 0, 0xfffff, PRESENTE | DPL_3 | GENERAL | DATA | WRITE, GRANULARIDAD | DB);
00081         *gdt++ = make_descriptor( (dword) &tss, sizeof(tss_t), PRESENTE | DPL_0 | SISTEMA | TSS_AVAILABLE, DB);
00082 
00083         gdtr->limite =(dword) gdt - (dword) POSICION_TABLA_GDT - 1;
00084         gdtr->base   =(dword) POSICION_TABLA_GDT;
00085 
00086         lgdt( gdtr );
00087 
00088         _set_ds(DESC_DATA);
00089         _set_es(DESC_DATA);
00090         _set_fs(DESC_DATA);
00091         _set_gs(DESC_DATA);
00092 
00093         ltr(DESC_TSS0);
00094 }       
00095 
00096 
00097 void init_MM (void)
00098 {
00099         dword memoria_total=0;
00100 
00101         page_off();     /* Deshabililitar paginacion */
00102 
00103         memoria_total=contar_memoria(); /* Contar memoria total del sistema */
00104 
00105         /* Habilitar 1 Tabla de 0-4MB, otra con Kernel Code (0xC0000000) y otra con Kernel Data (0xC8000000) */
00106         init_MM_base();
00107 
00108         load_cr3( POSICION_DIR_PAGINAS );
00109         page_on();
00110 
00111         memoria = memoria_total;
00112 }
00113 
00114 
00115 #define STEP    0x10000
00116 
00117 dword contar_memoria (void)
00118 {       
00119  dword *dir = (dword *) 0x200000;
00120  dword data = 0x12345678;
00121  dword prev;
00122 
00123  prev = *dir;
00124  *dir = data;
00125 
00126  while ( *dir == data) {
00127   *dir = prev;
00128   dir += STEP;
00129   prev = *dir;
00130   *dir = data;
00131  }
00132                  
00133  return ( (dword) dir / 0x100000 );
00134 }
00135  
00136 
00138 void init_all_memory( dword memoria ) {
00139 
00140         int i,j;
00141         page_index_t indice;
00142         pt_t *pt;
00143 
00144         pd_t *dir= (pd_t *) POSICION_DIR_PAGINAS;
00145         
00146         /* Mapear linealmente en el resto de la memoria
00147          * desde los 4Mb en adelante */
00148         for ( i=1; i < memoria/4 ; i++) {
00149 
00150 #if __VMDEBUG
00151                 kprintf("PDE Numero %d (0x%x)\n",i,i*PAGINA_SIZE*1024);
00152 #endif
00153                 indice = get_page_index(i*PAGINA_SIZE*1024);
00154                 pt = (pt_t *) kmalloc_page();
00155 
00156                 dir->entry[ indice.dir_index ] = make_pde((addr_t)pt, PAGE_PRES | PAGE_SUPER | PAGE_RW);
00157 
00158                 for ( j=0; j < PAGINAS_POR_TABLA; j++) {
00159                         pt->entry[j] = make_pte( i*PAGINA_SIZE*1024 + j*PAGINA_SIZE, PAGE_PRES | PAGE_SUPER | PAGE_RW);
00160                 }
00161 
00162         }
00163 
00164 }
00165 

Generated on Sun May 30 18:38:35 2004 for Routix OS by doxygen 1.3.6