My Project
Chargement...
Recherche...
Aucune correspondance
memoire.c
Aller à la documentation de ce fichier.
1
10#include <manux/config.h>
11#include <manux/types.h> /* TacheID */
12#include <manux/debug.h> /* assert */
13#include <manux/memoire.h>
14#include <manux/atomique.h>
15#include <manux/pagination.h> /* ajouterPage() */
16#include <manux/console.h>
17#include <manux/i386.h> // ADDR_VERS_PAGE
18
31
36
37/*
38 * Début de la zone mémoire dans laquelle on mémorise l'occupation
39 * des pages
40 */
41#ifndef MANUX_AFFECTATION_PAGES
42# define MANUX_AFFECTATION_PAGES 0x1000
43#endif
44
45/*
46 * Nombre de pages communes à toutes les tâches.
47 */
49
50/*
51 * Le propriétaire de chaque page mémoire est identifié dans le
52 * tableau suivant (0 <=> page libre). WARNING, pour le moment,
53 * c'est 1 ou 0 (utilisé ou libre).
54 */
55//TacheID * proprietairePage = (TacheID *)MANUX_AFFECTATION_PAGES ;
57
58/*
59 * Le nombre global de pages dans le système
60 */
61static uint32_t nombrePages = 0;
62static uint32_t nombreDePagesAllouees = 0;
63
64/*
65 * Marquer une page comme réservée. WARNING : il faut se protéger par un mutex
66 */
67inline
68static
69void reserverPage(uint32_t i)
70{
71 if (proprietairePage[i] != (TacheID)0) {
72 paniqueNoyau("Page 0x%x (%d) deja prise\n", i, i);
73 }
74 nombreDePagesAllouees++;
75 proprietairePage[i] = (TacheID)1; // WARNING
76}
77
81void libererPage(void * pageLiberee)
82{
83 int i = ((uint32_t) pageLiberee) / MANUX_TAILLE_PAGE;
84
85 if (proprietairePage[i] == (TacheID)0) {
86 paniqueNoyau("Liberation de la page %d non allouee !\n", i);
87 }
88 nombreDePagesAllouees--;
90
91}
92
93/*
94 * Marquer une page comme libre (WARNING trouve un plus joli nom)
95 */
96static
97inline
98void demarquerPage(uint32_t i)
99{
101}
102
103void initialiserMemoire(uint32_t tailleMemoireDeBase,
104 uint32_t tailleMemoireEtendue)
105{
106 uint32_t i; // Pour compter les pages initialisées
107 uint32_t tailleProprietaire; // Taille nécessaire pour les gérer
108 uint32_t nbrePagesManuX, nbrePagesPile;
109
110 // On met l'allocation des pages après la pile
112
113 // On affiche un petit récapitulatif
114 printk_debug(DBG_KERNEL_MEMOIRE, "base = %d, et = %d\n",
115 tailleMemoireDeBase, tailleMemoireEtendue);
116 printk_debug(DBG_KERNEL_MEMOIRE, "noyau d = 0x%x , f = 0x%x\n", adresseDebutManuX, adresseFinManuX);
119
120 // Les tailles sont données en Ko
121 nombrePages = (tailleMemoireDeBase + tailleMemoireEtendue) / 4;
122
123 printk_debug(DBG_KERNEL_MEMOIRE, "%d pages de %d octets\n",
124 nombrePages, MANUX_TAILLE_PAGE);
125
126 /* De combien de pages a-t-on besoin pour les gérer ? */
127 /* Pour le moment, la gestion d'une page demande 4 octets (bientôt 1 bit !) */
128 tailleProprietaire = 4 * nombrePages / MANUX_TAILLE_PAGE;
129 printk_debug(DBG_KERNEL_MEMOIRE, "taille proprietaire %d\n", tailleProprietaire);
130
131 // Le tableau d'allocation des pages ne doit pas télescoper le BIOS !
132 assert((void*)(proprietairePage + tailleProprietaire*MANUX_TAILLE_PAGE)
133 < (void *)MANUX_ADRESSE_BIOS);
134
135 // Par défaut tout est libre
136 for (i = 0; i < nombrePages; i++) {
137 demarquerPage(i);
138 }
139
140 // Les handlers : WARNING est-ce utile ?
141 reserverPage(0);
142 printk_debug(DBG_KERNEL_MEMOIRE, "%3d pg 0x00 a 0x00 pour les handlers\n", 1);
143
144 // La IDT
145 for (i=0 ; i < MANUX_IDT_NB_PAGES; i++) {
146 reserverPage(ADDR_VERS_PAGE(MANUX_ADRESSE_IDT)+i);
147 }
148 printk_debug(DBG_KERNEL_MEMOIRE, "%3d pg 0x0%x a 0x0%x pour la IDT\n",
152
153 // La GDT
154 for (i=0 ; i < MANUX_GDT_NB_PAGES; i++) {
155 reserverPage(ADDR_VERS_PAGE(MANUX_ADRESSE_GDT)+i);
156 }
157 printk_debug(DBG_KERNEL_MEMOIRE, "%3d pg 0x0%x a 0x0%x pour la GDT\n",
161
162 // Le noyau
165 for (i=0 ; i < nbrePagesManuX; i++) {
166 reserverPage(ADDR_VERS_PAGE(adresseDebutManuX)+i);
167 }
168 printk_debug(DBG_KERNEL_MEMOIRE, "%3d pg 0x%2x a 0x%2x pour le noyau\n",
169 nbrePagesManuX,
171 ADDR_VERS_PAGE(adresseDebutManuX)+nbrePagesManuX-1);
172
173 // La pipile
176 for (i=0 ; i < nbrePagesPile; i++) {
177 reserverPage(ADDR_VERS_PAGE(adressePileManuX)+i);
178 }
179 printk_debug(DBG_KERNEL_MEMOIRE, "%3d pg 0x%2x a 0x%2x pour la pile\n",
180 nbrePagesPile,
183 // ADDR_VERS_PAGE()+nbrePagesPile-1);
184
185 // La table d'allocation de la mémoire
186 for (i=0 ; i < tailleProprietaire; i++){
187 reserverPage(ADDR_VERS_PAGE(((uint32_t)proprietairePage))+i);
188 }
189 printk_debug(DBG_KERNEL_MEMOIRE, "%3d pg 0x%2x a 0x%2x pour gestion memoire\n",
190 tailleProprietaire,
192 ADDR_VERS_PAGE(((uint32_t)proprietairePage)) + tailleProprietaire-1);
193
194 // Le BIOS (indéboulonable !)
195 for (i=0 ; i < MANUX_BIOS_NB_PAGES; i++) {
196 reserverPage(ADDR_VERS_PAGE(MANUX_ADRESSE_BIOS)+i);
197 }
198 printk_debug(DBG_KERNEL_MEMOIRE, "%3d pg 0x%2x a 0x%2x pour le BIOS\n",
202
203}
204
205/*
206void * reserverPageSysteme()
207{
208 void * pageAllouee = NULL;
209 int numeroPage;
210
211 while (pageAllouee == NULL) {
212 numeroPage = MANUX_DEBUT_MEMOIRE_ETENDUE/MANUX_TAILLE_PAGE;
213 while ( (numeroPage < nombrePagesSysteme)
214 &&(proprietairePage[numeroPage] != (TacheID) 0)) {
215 numeroPage++;
216 }
217 // Si on trouve une page dispo
218 if (numeroPage < nombrePages) {
219 // On essaie de la réserver
220 if (atomiqueTestInit((Atomique *)&(proprietairePage[numeroPage]),
221 1, 0)) {
222 pageAllouee = (void *) (numeroPage * MANUX_TAILLE_PAGE);
223 }
224 // Sinon inutile de continuer
225 } else {
226 return NULL;
227 }
228 }
229 //printk("return 0x%x\n", pageAllouee);
230 return pageAllouee;
231}
232*/
233
234void * allouerPage(void)
235{
236 void * pageAllouee = NULL;
237 uint32_t numeroPage = 0;
238
239 // On cherche la première page libre
240 while ( (numeroPage < nombrePages)
241 &&(proprietairePage[numeroPage] != (TacheID) 0)) {
242 numeroPage++;
243 }
244
245 /* Si on trouve une page dispo */
246 if (numeroPage < nombrePages) {
247 reserverPage(numeroPage);
248 pageAllouee = (void *) (numeroPage * MANUX_TAILLE_PAGE);
249 }
250 /*
251 printk_debug(DBG_KERNEL_MEMOIRE, "Page 0x%x allouee\n",
252 numeroPage);
253 */
254 return pageAllouee;
255}
256
258{
259 return nombreDePagesAllouees;
260}
261
263{
264 return nombrePages;
265}
266
270static
271uint32_t nombrePagesLibres(uint32_t numeroPage)
272{
273 int result = 0;
274
275 while ((proprietairePage[numeroPage+result] == (TacheID) 0)
276 && (numeroPage + ++result < nombrePages)) {
277 }
278 return result;
279}
280
284void * allouerPages(uint32_t nombre)
285{
286 void * result = NULL;
287 uint32_t numeroPage = 0;
288
289 // On cherche la première page libre
290 while ( (numeroPage < nombrePages - nombre)
291 && (nombrePagesLibres(numeroPage) < nombre)) {
292 // Inutile d'aller voir les suivantes, qui sont trop peu
293 // nombreuses, ni celle d'après, qui est allouée.
294 numeroPage += nombrePagesLibres(numeroPage) + 1;
295 }
296
297 /* Si on trouve une page dispo */
298 if ((numeroPage < nombrePages) && (nombrePagesLibres(numeroPage) >= nombre)){
299 for (uint32_t i = numeroPage; i < numeroPage+nombre; i++) {
300 reserverPage(i);
301 }
302 result = (void *) (numeroPage * MANUX_TAILLE_PAGE);
303 }
304
305 return result;
306}
307
308#if defined(MANUX_APPELS_SYSTEME) && defined(MANUX_PAGINATION)
309/*
310 * WARNING : pas encore utilisé ?!
311 */
312[[maybe_unused]]
313static
314int AS_obtenirPages(ParametreAS p, int nbPages)
315{
316 Page unePage;
317 Tache * tache = tacheEnCours;
318
319 (void) p;
320
321 /* Pour le moment, on ne sait faire qu'une à la fois */
322 if (nbPages != 1) {
323 return 0;
324 }
325
326 /* Obtention de la page */
327 unePage = allouerPage();
328
329 /* Ajout à la fin de la mémoire virtuelle de la tâche */
330 ajouterPage((PageDirectory *)&tache->tss.CR3,
331 unePage,
332 tache->tailleMemoire);
333
334 /* On note qu'on a davantage de mémoire */
336
337 return 1;
338}
339#endif
Définition des opérations de synchronisation de ManuX.
#define MANUX_NOMBRE_PAGES_SYSTEME
#define MANUX_TAILLE_PAGE
Définition des fonctions de base d'accés à la console.
#define ADDR_VERS_PAGE(a)
Definition i386.h:42
typedef void(Handler(void))
#define NULL
Definition stddef.h:10
unsigned long uint32_t
Definition types.h:20
void * Page
Definition types.h:66
uint16_t TacheID
Definition types.h:61
#define assert(cond)
Definition debug.h:126
#define DBG_KERNEL_MEMOIRE
Definition debug.h:27
#define paniqueNoyau(fmt, args...)
Definition debug.h:107
#define printk_debug(lvl, fmt, args...)
Definition debug.h:86
void * allouerPages(uint32_t nombre)
Definition memoire.c:284
int nombrePagesSysteme
Definition memoire.c:48
uint32_t _adresseDebutManuX[]
Implantation des sous-programme de manipulation de la mémoire sous ManuX. On fait pour le moment un tru...
uint32_t _adresseLimitePileManuX[]
Definition memoire.c:30
int nombrePagesAllouees(void)
Definition memoire.c:257
uint32_t adresseLimitePileManuX
Definition memoire.c:35
void initialiserMemoire(uint32_t tailleMemoireDeBase, uint32_t tailleMemoireEtendue)
Initialisation de la mémoire au niveau pages.
Definition memoire.c:103
int nombrePagesTotal(void)
Definition memoire.c:262
uint32_t adresseFinManuX
Definition memoire.c:33
uint32_t _adressePileManuX[]
Definition memoire.c:29
uint32_t adresseDebutManuX
Definition memoire.c:32
uint32_t _adresseFinManuX[]
Definition memoire.c:28
void * allouerPage(void)
Definition memoire.c:234
TacheID * proprietairePage
Definition memoire.c:56
uint32_t adressePileManuX
Definition memoire.c:34
void libererPage(void *pageLiberee)
Definition memoire.c:81
int ajouterPage(PageDirectory *repertoirePagination, Page adressePhysique, void *adresseVirtuelle)
Definition pagination.c:133
PDE * PageDirectory
Definition pagination.h:28
#define MANUX_BIOS_NB_PAGES
#define MANUX_ADRESSE_BIOS
#define MANUX_ADRESSE_IDT
#define MANUX_GDT_NB_PAGES
#define MANUX_ADRESSE_GDT
Tache * tacheEnCours
: L'identification de la tâche en cours
Definition scheduler.c:91
uint32_t CR3
Definition tache.h:56
: Définition du type décrivant une tache.
Definition tache.h:83
void * tailleMemoire
Definition tache.h:90
IntelTSS tss
Definition tache.h:84
#define MANUX_IDT_NB_PAGES
Definition config.h:29