www

Unnamed repository; edit this file 'description' to name the repository.
Log | Files | Refs

multiboot.c (5915B)


      1 #include <module.h>
      2 #include <types.h>
      3 #include <string.h>
      4 
      5 #include <tri/tas/tas.h>
      6 #include <demarrage/multiboot/multiboot.h>
      7 #include <interfaceUtilisateur/console/console.h>
      8 #include <recherche/dichotomique/dichotomique.h>
      9 
     10 MODULE(Multiboot);
     11 
     12 DEPENDANCE_MODULE(Multiboot, Console);
     13 
     14 /* __listeModule et __finListeModules sont définis dans modules/creerImage.lds */
     15 
     16 extern InfoModule __listeModules;
     17 extern InfoModule __finListeModules;
     18 
     19 extern DependanceModule __listeDependancesModules;
     20 extern DependanceModule __finListeDependancesModules;
     21 
     22 
     23 void afficherNomModule(InfoModule* module) {
     24 	CouleurAvAr ancienneCouleur = consoleCouleur(0x00ff00ff, 0);
     25 	afficherChaineZ(module->nom);
     26 	afficherChaineZ("\n");
     27 	consoleCouleur(ancienneCouleur.av, ancienneCouleur.ar);
     28 }
     29 
     30 void afficherNomsModulesManques(InfoModule* listeModules) {
     31 	// effacerConsole(); /* Seulement en mode texte, en mode graphique, l'écran est déjà noir... */
     32 	InfoModule* module = listeModules;
     33 	
     34 	while (module != NULL) {
     35 		if (module->etapeChargementModule == ETAPE_MODULE_INITIALISE)
     36 			afficherNomModule(module);
     37 		module = module->suivant;
     38 	}
     39 }
     40 
     41 
     42 void* triDependancesGet(void* t, uint32 index) {
     43 	return ((DependanceModule*)t) + index;
     44 }
     45 
     46 void triDependancesEchange(void* t, uint32 a, uint32 b) {
     47 	DependanceModule* tt = t;
     48 	DependanceModule c;
     49 	
     50 	c = tt[a];
     51 	tt[a] = tt[b];
     52 	tt[b] = c;
     53 }
     54 
     55 int triDependancesCmp(void* a, void* b) {
     56 	void* aa = ((DependanceModule*)a)->module;
     57 	void* bb = ((DependanceModule*)b)->module;
     58 	
     59 	if (aa < bb)
     60 		return -1;
     61 	else if (aa == bb)
     62 		return 0;
     63 	else
     64 		return 1;
     65 }
     66 
     67 void pointEntreeNoyau(void* addrInfoMultiboot, uint32 magicMultiboot) {
     68 	asm volatile ("cli");
     69 	
     70 	int nbModules = 0;
     71 	InfoModule* module;
     72 	InfoModule* moduleTemp;
     73 	InfoModule* listeModules = &__listeModules;
     74 	InfoModule* finListeModules = &__finListeModules;
     75 	
     76 	int i;
     77 	int nbDependancesModules;
     78 	int premiereDependanceModule;
     79 	int derniereDependanceModule;
     80 	DependanceModule dependanceRecherchee;
     81 	DependanceModule* dependanceModule;
     82 	DependanceModule* listeDependancesModules = &__listeDependancesModules;
     83 	DependanceModule* finListeDependancesModules = &__finListeDependancesModules;
     84 	
     85 	/* Pré-initialisation de l'état du module multiboot */
     86 	etatMultiboot->InfoMultiboot = addrInfoMultiboot;
     87 	etatMultiboot->magicMultiboot = magicMultiboot;
     88 	
     89 	
     90 	/* Tri de la liste de dépendances */
     91 	nbDependancesModules = ((int)finListeDependancesModules - (int)listeDependancesModules) / sizeof(DependanceModule);
     92 	triParTas(
     93 		listeDependancesModules,
     94 		nbDependancesModules,
     95 		triDependancesGet,
     96 		triDependancesEchange,
     97 		triDependancesCmp
     98 	);
     99 	
    100 	/* Chaînage des modules */
    101 	nbModules = ((int)finListeModules - (int)listeModules) / sizeof(InfoModule);
    102 	module = listeModules;
    103 	while (module < finListeModules) {
    104 		module->suivant = module + 1;
    105 		
    106 		dependanceRecherchee = (DependanceModule){ module, NULL };
    107 		premiereDependanceModule = rechercheDichotomiquePremier(
    108 			&dependanceRecherchee,
    109 			listeDependancesModules,
    110 			nbDependancesModules,
    111 			triDependancesGet,
    112 			triDependancesCmp
    113 		);
    114 		
    115 		if (premiereDependanceModule < 0) {
    116 			module->dependances = NULL;
    117 			module->nbDependances = -1;
    118 		} else {
    119 			derniereDependanceModule = rechercheDichotomiqueDernier(
    120 				&dependanceRecherchee,
    121 				listeDependancesModules,
    122 				nbDependancesModules,
    123 				triDependancesGet,
    124 				triDependancesCmp
    125 			);
    126 			module->dependances = listeDependancesModules + premiereDependanceModule;
    127 			module->nbDependances = derniereDependanceModule - premiereDependanceModule + 1;
    128 		}
    129 		
    130 		module++;
    131 	}
    132 	if (nbModules != 0)
    133 		(module-1)->suivant = NULL;
    134 	
    135 	
    136 	/* Initialisation des modules */
    137 	module = (nbModules != 0) ? listeModules : NULL;
    138 	bool consoleDisponible = FALSE;
    139 	/* GCC BUG :
    140 	 * 
    141 	 *   while ((void*)module != (void*)NULL) {
    142 	 *       ...
    143 	 *   }
    144 	 * 
    145 	 * Lorsqu'on regarde la sortie assembleur de GCC, on voit qu'il teste
    146 	 * avant l'entrée dans la boucle s'il doit l'éviter, après quoi aucune
    147 	 * instruction ne permet d'en sortir. Ce qui explique le fonctionnement
    148 	 * incorrect du programme à l'exécution. De plus, on se rend compte
    149 	 * avec des comparaisons ( < , = , > ) qu'il semble considérer que
    150 	 * 1 < module < 2 (donc on a un pointeur flottant \o/ ). Vu qu'il y a
    151 	 * très peu de chances pour que l'info sur un module soit située à 1 (!),
    152 	 * on utilise ((void*)module > (void*)(1)) . */
    153 	
    154 	while ((void*)module > (void*)(1)) {
    155 		if (module->etapeChargementModule != ETAPE_MODULE_INITIALISE) {
    156 			dependanceModule = module->dependances;
    157 			
    158 			for (i = 0; i < module->nbDependances; i++) {
    159 				if (dependanceModule->dependance->etapeChargementModule != ETAPE_MODULE_INITIALISE) {
    160 					dependanceModule->dependance->suivantRecursionDependances = module;
    161 					module = dependanceModule->dependance;
    162 					goto finBoucleInitialisationModules;
    163 				}
    164 				dependanceModule++;
    165 			}
    166 			
    167 			
    168 			if (consoleDisponible)
    169 				afficherNomModule(module);
    170 			
    171 			
    172 			(*(module->init)) (module->etat);
    173 			module->etapeChargementModule = ETAPE_MODULE_INITIALISE;
    174 			
    175 			if (!consoleDisponible && consolePrete()) {
    176 				consoleDisponible = TRUE;
    177 				afficherNomsModulesManques(listeModules);
    178 			}
    179 		}
    180 		
    181 		
    182 		if (module->suivantRecursionDependances != NULL) {
    183 			moduleTemp = module->suivantRecursionDependances;
    184 			module->suivantRecursionDependances = NULL;
    185 			module = moduleTemp;
    186 		} else {
    187 			module = module->suivant;
    188 		}
    189 		
    190 		finBoucleInitialisationModules:
    191 		{} /* Fausse instruction pour éviter un "error: label at end of compound statement" */
    192 	}
    193 	
    194 	
    195 	/* Fin */
    196 	afficherChaineZ("\n\n");
    197 	
    198 	for (;;) asm volatile ("hlt;");
    199 }
    200 
    201 
    202 void initMultiboot(void** etat) {
    203 	*etat = etatMultiboot;
    204 	
    205 	/* if (etatMultiboot->InfoMultiboot->flags.bootLoaderName) {
    206 		afficherChaineZ("Charg" STR_eacute " par ");
    207 		afficherChaineZ(etatMultiboot->InfoMultiboot->bootLoaderName);
    208 		afficherChaineZ(".\n");
    209 	} */
    210 }
    211 
    212 void deinitMultiboot(void** etat) {
    213 	*etat = NULL;
    214 }