Dans le contexte de Linux, le chargeur de démarrage est responsable de certaines tâches prédéfinies. Comme cette question est étiquetée arm, je pense que le démarrage ARM pourrait être une ressource utile. Plus précisément, le chargeur de démarrage était/est responsable de la configuration d'un ATAG
list qui décrit la quantité de RAM, une ligne de commande du noyau et d'autres paramètres. L'un des paramètres les plus importants est le type de machine . Avec arborescences d'appareils , une description complète de la carte est transmise. Cela rend un ARM Linux d'origine impossible à démarrer sans un peu de code pour configurer les paramètres comme décrit.
Les paramètres permettent un générique Linux pour prendre en charge plusieurs appareils. Par exemple, un noyau ARM Debian peut prendre en charge des centaines de types de cartes différents. Uboot ou un autre chargeur de démarrage peut déterminer dynamiquement ces informations ou elles peuvent être codées en dur pour la carte.
Vous pouvez également consulter la page d'informations sur le chargeur de démarrage ici sur le débordement de la pile.
Un système de base pourrait être en mesure de configurer ATAGS
et copiez le flash NOR dans la SRAM. Cependant, c'est généralement un peu plus complexe que cela. Linux nécessite une configuration RAM, vous devrez donc peut-être initialiser un contrôleur SDRAM. Si vous utilisez le flash NAND, vous devez gérer les mauvais blocs et la copie peut être un peu plus complexe que memcpy()
.
Linux a souvent des bogues de pilote latents où un pilote supposera qu'une horloge est initialisée. Par exemple, si Uboot initialise toujours une horloge Ethernet pour une machine particulière, le pilote Ethernet Linux peut avoir négligé de configurer cette horloge. Cela peut être particulièrement vrai avec les arbres d'horloge.
Certains systèmes nécessitent des formats d'image de démarrage qui ne sont pas pris en charge par Linux; par exemple un en-tête spécial qui peut initialiser le matériel immédiatement ; comme configurer le devices
pour lire le code initial à partir de. De plus, il y a souvent du matériel qui doit être configuré immédiatement; un chargeur de démarrage peut le faire rapidement alors que la structure normale de Linux peut retarder cela de manière significative, entraînant des conflits d'E/S, etc.
D'un point de vue pragmatique, il est plus simple d'utiliser un chargeur de démarrage. Cependant, rien ne vous empêche de modifier le source de Linux pour démarrer directement à partir de celui-ci; bien que cela puisse ressembler à coller le chargeur de démarrage code directement au démarrage de Linux.
Voir aussi :Coreboot, Uboot et la comparaison de Wikipédia. Barebox est un chargeur de démarrage moins connu, mais bien structuré et moderne pour l'ARM. RedBoot est également utilisé dans certains systèmes ARM; Les partitions RedBoot sont prises en charge dans l'arborescence du noyau.
Un chargeur de démarrage est un programme informatique qui charge le système d'exploitation principal ou l'environnement d'exécution de l'ordinateur une fois les autotests terminés.
^ Extrait de l'article de Wikipédia
Donc, fondamentalement, le chargeur de démarrage fait exactement ce que vous vouliez - copier les données de la mémoire flash dans la mémoire d'exploitation. C'est vraiment aussi simple.
Si vous voulez en savoir plus sur le boostrapping du système d'exploitation, je vous recommande fortement de lire l'article lié. La phase de démarrage consiste, outre les tests, également à vérifier les périphériques et quelques autres choses. Les ignorer n'a de sens que sur des appareils embarqués très simples, et c'est pourquoi leurs chargeurs de démarrage sont encore plus simples :
Certains systèmes embarqués ne nécessitent pas de séquence de démarrage notable pour commencer à fonctionner et, lorsqu'ils sont allumés, ils peuvent simplement exécuter des programmes opérationnels stockés dans la ROM.
La même source
Pourquoi ne pouvons-nous pas charger directement le noyau dans la RAM à partir de la mémoire flash sans chargeur de démarrage ? Si nous le chargeons, que se passera-t-il ? En fait, le processeur ne le supportera pas, mais pourquoi suivons-nous la procédure ?
Bartek, Artless et Felipe donnent tous des parties de l'image.
Chaque type de processeur embarqué (par exemple 386EX, Coretex-A53, EM5200) fera quelque chose automatiquement lorsqu'il est réinitialisé ou allumé. Parfois, ce quelque chose est différent selon que l'alimentation est rallumée ou que l'appareil est réinitialisé. Certains processeurs intégrés vous permettent de changer ce quelque chose basé sur les tensions appliquées aux différentes broches lorsque l'appareil est alimenté ou réinitialisé.
Quoi qu'il en soit, il y a une quantité limitée de quelque chose ce qu'un processeur peut faire, en raison de l'espace physique sur le processeur requis pour définir ce quelque chose , qu'il s'agisse d'un FLASH sur puce, d'un micro-code d'instruction ou d'un autre mécanisme.
Cette limite signifie que quelque chose est
- objectif fixe, fait une chose le plus rapidement possible.
- portée et capacité limitées, chargeant généralement un petit bloc de code (souvent quelques kilo-octets ou moins) dans un emplacement de mémoire fixe et s'exécutant depuis le début du code chargé.
- non modifiable.
Ainsi, ce qu'un processeur fait en réponse à une réinitialisation ou à un cycle d'alimentation ne peut pas être modifié et ne peut pas faire grand-chose, et nous ne voulons pas qu'il copie automatiquement des centaines de mégaoctets ou de gigaoctets dans une mémoire qui peut ne pas exister ou ne pas être initialisée, et qui pourrait prendre looooongtemps.
Alors....
Nous avons mis en place un petit programme qui est plus petit que la plus petite taille autorisée sur tous les appareils que nous allons utiliser. Ce programme est stocké partout où quelque chose en a besoin.
Parfois, le petit programme est U-Boot. Parfois, même U-Boot est trop volumineux pour le chargement initial, de sorte que le petit programme charge à son tour U-Boot.
Le fait est que tout ce qui est chargé par le quelque chose , est modifiable selon les besoins d'un système particulier. Si c'est U-Boot, super, sinon, il sait où charger le système d'exploitation principal ou où charger U-Boot (ou un autre chargeur de démarrage).
U-Boot (parlant des chargeurs de démarrage en général) configure ensuite un ensemble minimal de périphériques, de mémoire, de paramètres de puce, etc., pour permettre au système d'exploitation principal d'être chargé et démarré. L'initialisation principale du système d'exploitation prend en charge toute configuration ou initialisation supplémentaire.
Donc la séquence est :
- Allumage ou réinitialisation du processeur
- Quelque chose charge le code de démarrage initial (ou le chargeur de démarrage intégré de style U-Boot)
- Code de démarrage initial (peut ne pas être nécessaire)
- U-Boot (ou autre chargeur de démarrage général intégré)
- Init Linux
Le chargeur de démarrage principal est généralement intégré au silicium et effectue le chargement du premier code USER qui sera exécuté dans le système.
Le chargeur de démarrage existe car il n'existe pas de protocole standardisé pour charger le premier code, car il dépend de la puce. Parfois, le code peut être chargé via un port série, une mémoire flash ou même un disque dur. C'est la fonction bootloader pour le localiser.
Une fois le code utilisateur chargé et en cours d'exécution, le chargeur de démarrage n'est plus utilisé et l'exactitude de l'exécution du système relève de la responsabilité de l'utilisateur.
Dans la chaîne Linux intégrée, le chargeur de démarrage principal configurera et exécutera Uboot. Ensuite, Uboot trouvera le noyau Linux et le chargera.