Comment quitter correctement QEMU après avoir exécuté un programme en métal nu sans intervention de l'utilisateur?

j'assemble une unité de compilation croisée pour tester un système de bras et j'exécute les essais sur une machine hôte avec qemu-system-arm . Plus précisément, j'utilise qemu pour émuler la carte eval Stellaris LM3S6965 car elle contient un processeur Cortex M3 comme mon environnement cible. L'exécution binaire dans qemu est construite avec les outils GNU pour ARM.

il n'y a pas D'OS impliqué. La suite de tests est exécutée comme une application en métal nu avec qemu en mode -nographic . La chaîne d'outils et le banc d'essai lui-même fonctionnent très bien. Et les tests fonctionnent avec succès jusqu'à l'achèvement et produire des résultats de test dans qemu tout aussi bien.

le problème est d'emballer qemu dans un outil de compilation automatisé (râteau dans ce cas). En dehors des commandes de clavier, je n'ai pas encore trouvé de bonne façon de faire sortir qemu après que la suite de test s'exécute et crache ses résultats. Cela provoque l'accumulation de l'environnement pour accrocher / compter sur l'intervention de l'utilisateur.

j'ai regardé haut et faible et n'ont trouvé aucune bonne source sur la façon d'accomplir une sortie simple après la fin du programme. J'ai trouvé quelques suggestions d'exécuter qemu avec l'option -no-reboot et de déclencher une réinitialisation du système à partir du programme en cours d'exécution dans l'émulateur. J'ai essayé cette. Il fonctionne... un peu. J'écris les valeurs appropriées au vecteur de réinitialisation du processeur émulé après l'exécution de main() , ce qui déclenche une réinitialisation. Après avoir lancé la suite de tests, qemu déclare avoir détecté une réinitialisation du système. Cependant, il déclare ceci comme une erreur matérielle, vide le contenu du Registre, puis sort en colère (message d'erreur ci-dessous). Alors que cela permet d'effectuer la sortie après l'exécution de la suite de test, cela casse alors le script de construction automatisé en raison de qemu sortie avec une condition d'erreur.

qemu: hardware error: System reset

j'aimerais éviter de hacker l'insertion de commandes clavier dans le build pour simuler l'intervention de l'utilisateur. J'aimerais aussi éviter de compter sur qemu sortie dans un état d'erreur.

il semble que je sois près d'une sortie propre mais pas tout à fait là. La recherche du message d'erreur qemu (ci-dessus) n'a produit aucune documentation pertinente autre que des rapports de bogue tangentiellement liés.

y a-t-il un mécanisme pour faire sortir qemu après que main() retourne dans un programme de métal nu que je manque? Cette stratégie -no-reboot + de réinitialisation du système fonctionnera-t-elle? Si oui, que faut-il d'autre pour permettre à qemu de sortir proprement?

4
demandé sur Michael Karlesky 2015-08-13 17:04:50

5 réponses

je recommande D'utiliser Angel interface pour ARM processores. Il est très utile pour le débogage. Vous pouvez lire quelque chose à ce sujet sur ARM Info Center . Regardez en particulier l'opération angel_SWIreason_ReportException (0x18) et le paramètre ADP_Stopped_ApplicationExit à laquelle QEMU comprendra que votre application est terminée.

N'oubliez pas de lancer l'argument QEMU avec-semihosting, comme ceci:

qemu-system-arm -nographic -semihosting -kernel your_binary

voici le code pour dire à QEMU d'arrêter (vous devez utiliser un assembleur):

register int reg0 asm("r0");
register int reg1 asm("r1");

reg0 = 0x18;    // angel_SWIreason_ReportException
reg1 = 0x20026; // ADP_Stopped_ApplicationExit

asm("svc 0x00123456");  // make semihosting call

vous pouvez également regarder mon projet à github où je l'ai utilisé.

4
répondu J. Havran 2016-12-04 11:05:22

généralement, vous devez faire tout ce qui sur le matériel pourrait causer un arrêt du système (power off); QEMU fera qui font un 'exit QEMU'. Malheureusement, tout le matériel que nous émulons n'est pas doté d'un mécanisme de mise hors tension (et parfois il n'est pas câblé dans le modèle QEMU, bien que ce soit généralement un bug facile à corriger).

1
répondu Peter Maydell 2015-08-13 14:37:49

l'option la plus propre pour moi était de saisir la source pour une version stable de Qemu proche de celle que nous utilisions déjà. Ce qui suit se réfère à la version 1.1.2 de la source Qemu.

j'ai modifié l'émulation de la manipulation du vecteur reset pour le tableau eval Cortex M3 + Stellaris LM3S6965 dans armv7m_nvic.c . J'ai remplacé l'appel hw_error() par un appel qemu_system_reset_request() . Cet appel système interne va réinitialiser une machine virtuelle mais répond aussi au -no-reboot option de ligne de commande pour un arrêt propre comme discuté dans ma question originale.

Ces instructions a fonctionné pour moi après avoir retenu un portrait de Qemu 1.1.2 . J'ai rencontré plusieurs erreurs de compilation, mais les recherches sur le web ont rapidement résolu chaque problème.

1
répondu Michael Karlesky 2015-08-18 03:56:17

L'ARMv7M qemu actuel (basé sur le microcontrôleur TI Stellaris LM3S6965) prend en charge la réinitialisation à partir du registre AICRCR ( application interrompre and Reset Control Register ). L'écriture au bit SYSRESETREQ de ce registre assigne un signal au système extérieur qui demande une réinitialisation.

Écrit AICRCR nécessite d'écrire 0x5FA à la VECTKEY sur le terrain, sinon le processeur ignore l'écriture.

This la ligne permet de réinitialiser ARMv7M qEmu.

SCB->AIRCR = (0x5FA << SCB_AIRCR_VECTKEY_Pos) | SCB_AIRCR_SYSRESETREQ_Msk;

pour empêcher qEmu de redémarrer indéfiniment, vous pouvez ajouter l'argument qEmu -no-reboot .

0
répondu OlivierM 2018-06-25 19:12:25

aarch64 semihosting exit

https://stackoverflow.com/a/40957928/895245 a donné A32, voici A64:

.global main
main:
    /* 0x20026 == ADP_Stopped_ApplicationExit */
    mov x1, #0x26
    movk x1, #2, lsl #16
    str x1, [sp,#0]

    /* Exit status code. Host QEMU process exits with that status. */
    mov x0, #0
    str x0, [sp,#8]

    /* x1 contains the address of parameter block.
     * Any memory address could be used. */
    mov x1, sp

    /* SYS_EXIT */
    mov w0, #0x18

    /* Do the semihosting call on A64. */
    hlt 0xf000

voici un exemple sur GitHub:

la Documentation est déplacée à: https://developer.arm.com/docs/100863/latest

0