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
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
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
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
00062
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
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();
00102
00103 memoria_total=contar_memoria();
00104
00105
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
00147
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