web-dev-qa-db-fra.com

Quel est le processus de démarrage pour ARM?

Comme nous le savons, pour l'architecture X86: après avoir appuyé sur le bouton d'alimentation, la machine commence à exécuter le code à 0xFFFFFFF0, puis elle commence à exécuter le code dans le BIOS afin de faire l'initialisation matérielle. Après l'exécution du BIOS, il utilise le chargeur de démarrage pour charger l'image du système d'exploitation dans la mémoire. À la fin, le code du système d'exploitation commence à s'exécuter. Pour l'architecture ARM, quel est le processus de démarrage après utilisation, appuyez sur le bouton d'alimentation? Merci!

51
Fengwei Zhang

Actuellement, il existe deux modèles d'exception dans l'architecture ARM (la réinitialisation est considérée comme une sorte d'exception):

Le modèle classique, utilisé dans les puces pré-Cortex et les puces Cortex-A/R actuelles. Dans ce document, la mémoire à 0 contient plusieurs gestionnaires d'exceptions:

 Offset  Handler
 ===============
 00      Reset 
 04      Undefined Instruction
 08      Supervisor Call (SVC)
 0C      Prefetch Abort
 10      Data Abort
 14      (Reserved)
 18      Interrupt (IRQ)
 1C      Fast Interrupt (FIQ)

Lorsque l'exception se produit, le processeur commence simplement l'exécution à partir d'un décalage spécifique, donc généralement cette table contient des branches à instruction unique vers les gestionnaires complets plus loin dans le code. Une table vectorielle classique typique ressemble à ceci:

00000000   LDR   PC, =Reset
00000004   LDR   PC, =Undef
00000008   LDR   PC, =SVC
0000000C   LDR   PC, =PrefAbort
00000010   LDR   PC, =DataAbort
00000014   NOP
00000018   LDR   PC, =IRQ
0000001C   LDR   PC, =FIQ

Au moment de l'exécution, la table vectorielle peut être déplacée vers 0xFFFF0000, qui est souvent implémentée en tant que plage de mémoire étroitement couplée pour la gestion des exceptions la plus rapide. Cependant, la réinitialisation à la mise sous tension commence généralement à 0x00000000 (mais dans certaines puces, elle peut être définie sur 0xFFFF0000 par une broche de processeur).

Le nouveau modèle de microcontrôleur est utilisé dans la gamme de puces Cortex-M. Là, la table vectorielle à 0 est en fait une table de vecteurs (pointeurs), pas d'instructions. La première entrée contient la valeur de démarrage du registre SP, la seconde est le vecteur de réinitialisation. Cela permet d'écrire le gestionnaire de réinitialisation directement en C, puisque le processeur configure la pile. Encore une fois, la table peut être déplacée au moment de l'exécution. La table vectorielle typique pour Cortex-M commence comme suit:

__Vectors       DCD     __initial_sp              ; Top of Stack
                DCD     Reset_Handler             ; Reset Handler
                DCD     NMI_Handler               ; NMI Handler
                DCD     HardFault_Handler         ; Hard Fault Handler
                DCD     MemManage_Handler         ; MPU Fault Handler
                DCD     BusFault_Handler          ; Bus Fault Handler
                DCD     UsageFault_Handler        ; Usage Fault Handler
                [...more vectors...]

Notez que dans les puces complexes modernes telles que OMAP3 ou A4 d'Apple, le premier morceau de code qui est exécuté n'est généralement pas du code utilisateur mais la ROM de démarrage sur puce. Il peut vérifier diverses conditions pour déterminer d'où charger le code utilisateur et s'il doit le charger (par exemple, il peut nécessiter une signature numérique valide). Dans de tels cas, le code utilisateur peut devoir se conformer à différentes conventions de démarrage.

61
Igor Skochinsky

... À la fin, le code du système d'exploitation commence à s'exécuter. Pour l'architecture ARM, quel est le processus de démarrage après utilisation, appuyez sur le bouton d'alimentation?

Cette réponse se situe principalement dans le contexte des processeurs Cortex-A modernes; il existe une grande variété de plates-formes ARM. Cependant, pour un ARM qui ressemble à un PC (tablette, téléphone portable, etc.) ...

Le ARM CPU récupérera une instruction de 0x0 ou 0xffff0000 (pour un Cortex-M, ce sont des données par opposition à une instruction). Typique ARM SOC avoir une ROM de démarrage qui utilise ce mécanisme. Pour un utilisateur final, vous devez consulter un manuel pour déterminer comment exécuter votre code. C'est-à-dire qu'il existe un [~ # ~] bios [~ # ~] intégré à de nombreux ARM SOC qui utilisent le vecteur, mais vous devez utiliser quelque chose de différent pour exécuter votre code.

En général, le SOC ARM prend en charge plusieurs périphériques de démarrage. Le périphérique est déterminé par un fusible (défini par un outil de fabrication) ou par des broches d'échantillonnage. Les broches seront des sorties CPU dans un système en cours d'exécution, mais ont été tirés vers le haut/bas pour configurer un périphérique de démarrage. Chaque périphérique de démarrage aura des détails particuliers; ROM est simple, mais flash NAND, SPI flash, MMC , etc. ont besoin de certains détails de configuration. Ils sont également souvent fournis par un fusible sur la puce et/ou des broches d'échantillonnage. Une petite partie de l'appareil peut être lue pour configurer davantage l'appareil.

Pour une puce ARM profondément intégrée, elle ne peut démarrer qu'à partir du flash intégré et ce processus est beaucoup plus simple; mais je crois que dans le contexte de la question à laquelle vous faites référence, plus avancée ARM CPU. Plus avancés ARM ont un chargeur de démarrage. Cela est dû au fait que la quantité de code a ROM que le chargeur chargera est souvent La configuration de la SDRAM est également souvent complexe et le chargeur de démarrage peut être structuré pour fonctionner à partir de la RAM statique interne, ce qui configure la SDRAM.

Voir: Pourquoi nous avons besoin d'un chargeur de démarrage

L'exécution du système d'exploitation a ses propres problèmes particuliers. Pour ARM Linux, c'était ATAGS et est maintenant devicetree. Les gens peuvent coder leur propre chargeur de démarrage ou utiliser l'un des nombreux projets open source avec u-boot étant le plus courant. U-boots prend en charge vxWorks, Linux, NetBSD, Plan9, OSE, QNX, Integrity et OpenRTOS ainsi que des images binaires.

De nombreux périphériques Linux ARM Linux pris en charge un démarrage direct de Linux sans chargeur de démarrage. Cependant, Linux ne prend pas en charge cette dans la ligne principale, à l'exception de quelques très anciens ARM SOC/cores.

3
artless noise

Après la mise sous tension Le processeur commencera à exécuter le mode d'exception Le premier est réinitialisé, car la réinitialisation doit s'exécuter en mode superviseur car le processeur ne connaît pas l'état du registre à ce moment de l'exécution, il ne peut pas passer en mode superviseur. un petit code doit être écrit (voir à la fin). après cela, d'autres exceptions peuvent être gérées en chargeant l'adresse dans le PC.

.globl _start
 _start: b       reset
    ldr     pc, _undefined_instruction
    ldr     pc, _software_interrupt
    ldr     pc, _prefetch_abort
    ldr     pc, _data_abort
    ldr     pc, _not_used
    ldr     pc, _irq
    ldr     pc, _fiq

reset:
    mrs     r0,cpsr                 /* set the cpu to SVC32 mode        */
    bic     r0,r0,#0x1f             /* (superviser mode, M=10011)       */
    orr     r0,r0,#0x13
    msr     cpsr,r0
3
user1813332