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 }