initial commit
[pfinal.git] / Routix / src / mm / mm.c
blob33a5b6bdb97f8b89711459bd453d6168ca99d5d2
1 /*! \addtogroup MemoryManager
2 \page mm.c
3 Core de la administración de memoria. Inicializa la memoria y al mismo Memory Manager.
4 No es utilizado una vez que el sistema ha sido inicializado.
5 */
7 #include "routix/system.h"
8 #include "routix/paging.h"
9 #include "routix/segm.h"
10 #include <routix/kalloc.h>
11 #include "routix/task.h"
12 #include "routix/debug.h"
14 addr_t KERNEL_PDT = POSICION_DIR_PAGINAS;
15 addr_t USER_PDT;
17 void init_MM_base(void);
18 dword contar_memoria (void);
19 dword memoria;
22 /*! Esta funcion inicializa 3 Tablas de paginas:
23 * 1. Apunta de 0-4MB fisicos (donde se haya el kernel y los datos)
24 * 2. Apuntan a los 3GB (direccion virtual del kernel)
25 * 3. Apunta a 3GB + 128MB (direccion virtual de kernel data)
27 void init_MM_base()
29 page_index_t indice;
30 pd_t *dir;
31 pt_t *tabla;
32 word i;
33 gdtr_t *gdtr;
34 descriptor_t *gdt;
36 dir= (pd_t *) POSICION_DIR_PAGINAS;
38 /* Mapear linealmente en Tabla 1 de 0-4MB (posicion fisica del kernel */
39 indice=get_page_index( 0 );
40 dir->entry[ indice.dir_index ]=make_pde (POSICION_TABLA_1, PAGE_PRES | PAGE_SUPER | PAGE_RW);
41 tabla = (pt_t *) (dir->entry[ indice.dir_index ] & 0xfffff000);
42 for(i=0 ; i < PAGINAS_POR_TABLA ; i++)
43 tabla->entry[i]= make_pte( i * PAGINA_SIZE, PAGE_PRES | PAGE_SUPER | PAGE_RW ) ;
46 /* Mapear El codigo de kernel en 3GB (0xC0000000) */
47 indice=get_page_index(KERNEL_CODE);
48 dir->entry[ indice.dir_index ]=make_pde (POSICION_TABLA_KCODE, PAGE_PRES | PAGE_SUPER | PAGE_RW);
49 tabla = (pt_t *) (dir->entry[ indice.dir_index ] & 0xfffff000);
50 for(i=0 ; i < PAGINAS_POR_TABLA ; i++)
51 tabla->entry[i]= make_pte( KERNEL_FCODE + (i * PAGINA_SIZE), PAGE_PRES | PAGE_SUPER | PAGE_RW ) ;
54 /* Mapear Los datos de kernel en 3GB + 128MB (0xC8000000) */
55 indice=get_page_index(KERNEL_DATA);
56 dir->entry[ indice.dir_index ]=make_pde (POSICION_TABLA_KDATA, PAGE_PRES | PAGE_SUPER | PAGE_RW);
57 tabla = (pt_t *) (dir->entry[ indice.dir_index ] & 0xfffff000);
58 for(i=0 ; i < PAGINAS_POR_TABLA ; i++)
59 tabla->entry[i]= make_pte( KERNEL_FDATA + (i * PAGINA_SIZE), PAGE_PRES | PAGE_SUPER | PAGE_RW ) ;
61 /* Mapear el stack de kernel en 3GB + 128MB + 128Mb + 128MB - 128Kb
62 * mapeamos desde el TOP 128Kb hacia arriba (32 páginas) */
65 indice=get_page_index(KERNEL_STACK_TOP - KERNEL_STACK_SIZE);
66 dir->entry[ indice.dir_index ]=make_pde (POSICION_TABLA_KSTACK, PAGE_PRES | PAGE_SUPER | PAGE_RW);
67 tabla = (pt_t *) (dir->entry[ indice.dir_index ] & 0xfffff000);
68 for(i=0 ; i < KERNEL_STACK_SIZE / PAGINA_SIZE; i++)
69 tabla->entry[i+indice.tabla_index]= make_pte( KERNEL_FSTACK + (i * PAGINA_SIZE), PAGE_PRES | PAGE_SUPER | PAGE_RW );
72 /* Cargamos ahora la gdt */
73 gdtr = (gdtr_t *) POSICION_TABLA_GDT;
74 gdt = (descriptor_t *) POSICION_TABLA_GDT;
76 *gdt++ = make_descriptor( 0, 0, 0, 0);
77 *gdt++ = make_descriptor( 0, 0xfffff, PRESENTE | DPL_0 | GENERAL | CODIGO, GRANULARIDAD | DB);
78 *gdt++ = make_descriptor( 0, 0xfffff, PRESENTE | DPL_0 | GENERAL | DATA | WRITE, GRANULARIDAD | DB);
79 *gdt++ = make_descriptor( 0, 0xfffff, PRESENTE | DPL_3 | GENERAL | CODIGO, GRANULARIDAD | DB);
80 *gdt++ = make_descriptor( 0, 0xfffff, PRESENTE | DPL_3 | GENERAL | DATA | WRITE, GRANULARIDAD | DB);
81 *gdt++ = make_descriptor( (dword) &tss, sizeof(tss_t), PRESENTE | DPL_0 | SISTEMA | TSS_AVAILABLE, DB);
83 gdtr->limite =(dword) gdt - (dword) POSICION_TABLA_GDT - 1;
84 gdtr->base =(dword) POSICION_TABLA_GDT;
86 lgdt( gdtr );
88 _set_ds(DESC_DATA);
89 _set_es(DESC_DATA);
90 _set_fs(DESC_DATA);
91 _set_gs(DESC_DATA);
93 ltr(DESC_TSS0);
97 void init_MM (void)
99 dword memoria_total=0;
101 page_off(); /* Deshabililitar paginacion */
103 memoria_total=contar_memoria(); /* Contar memoria total del sistema */
105 /* Habilitar 1 Tabla de 0-4MB, otra con Kernel Code (0xC0000000) y otra con Kernel Data (0xC8000000) */
106 init_MM_base();
108 load_cr3( POSICION_DIR_PAGINAS );
109 page_on();
111 memoria = memoria_total;
115 #define STEP 0x10000
116 //! \brief Cuenta la cantidad de memoria física del sistema
117 dword contar_memoria (void)
119 dword *dir = (dword *) 0x200000;
120 dword data = 0x12345678;
121 dword prev;
123 prev = *dir;
124 *dir = data;
126 while ( *dir == data) {
127 *dir = prev;
128 dir += STEP;
129 prev = *dir;
130 *dir = data;
133 return ( (dword) dir / 0x100000 );
137 //! Mapea toda la memoria disponible para que el kernel la vea en la misma dirección lógica que física
138 void init_all_memory( dword memoria ) {
140 int i,j;
141 page_index_t indice;
142 pt_t *pt;
144 pd_t *dir= (pd_t *) POSICION_DIR_PAGINAS;
146 /* Mapear linealmente en el resto de la memoria
147 * desde los 4Mb en adelante */
148 for ( i=1; i < memoria/4 ; i++) {
150 #if __VMDEBUG
151 kprintf("PDE Numero %d (0x%x)\n",i,i*PAGINA_SIZE*1024);
152 #endif
153 indice = get_page_index(i*PAGINA_SIZE*1024);
154 pt = (pt_t *) kmalloc_page();
156 dir->entry[ indice.dir_index ] = make_pde((addr_t)pt, PAGE_PRES | PAGE_SUPER | PAGE_RW);
158 for ( j=0; j < PAGINAS_POR_TABLA; j++) {
159 pt->entry[j] = make_pte( i*PAGINA_SIZE*1024 + j*PAGINA_SIZE, PAGE_PRES | PAGE_SUPER | PAGE_RW);