2017-06-19 2 views
6

J'ai une application qui fonctionne sur cible en métal nu et a la structure suivanteDynamiquement code charge cible embarquée

  • main.c
  • service.c/.h

Il est compilé à l'exécutable ELF (system.elf) en utilisant la séquence standard gcc -c, ld. J'utilise linker pour générer un fichier de carte montrant les adresses de tous les symboles.

Maintenant, sans re-clignoter mon système, j'ai besoin d'ajouter une fonctionnalité supplémentaire avec un chargeur d'exécution personnalisé. Rappelez-vous, c'est un bare-metal sans OS.

Je voudrais

  • compilation qui utilise extra.c API définies dans service.h (et lien en quelque sorte contre service.o existant/system.elf)
  • copier l'exécutable résultant à mon SDRAM lors de l'exécution et sauter pour qu'il
  • code chargé doit être en mesure d'exécuter et les accès les symboles exportés de service.c comme prévu

I THO ught je serais en mesure de réutiliser fichier carte pour lier le extra.o contre system.elf mais cela ne fonctionne pas:

ld -o extraExe extra.o system.map 

Est-ce que gcc ou ld ont un certain mode pour rendre cette procédure tardive de liaison? Si non, comment puis-je obtenir le chargement de code dynamique que j'ai décrit ci-dessus?

+1

gcc n'est pas alinker. – Olaf

+0

fixé le titre, pls supprimer -1, ou simplement donner une réponse productive :) –

+1

Encore c'est un frontend à un éditeur de liens, de sorte que vous pouvez lier en utilisant gcc ... –

Répondre

4

Vous pouvez utiliser le 'R nom de fichier' ou '--just-symboles = nom de fichier' options de commande dans ld. Il lit les noms de symboles et leurs adresses à partir du nom de fichier, mais ne le déplace pas ou ne l'inclut pas dans la sortie. Cela permet à votre fichier de sortie de se référer symboliquement aux emplacements absolus de la mémoire définis dans votre programme system.elf. (se référer à ftp://ftp.gnu.org/old-gnu/Manuals/ld-2.9.1/html_node/ld_3.html).

Donc ici le nom de fichier sera 'system.elf'. Vous pouvez compiler extra.c avec GCC normalement, y compris services.h mais sans liaison et générer « extra.o » puis appelez ld comme ci-dessous:

ld -R"system.elf" -o"extra.out" extra.o 

Le « extra.out » ont vos symboles liés. Vous pouvez utiliser objdump pour comparer le contenu de 'extra.out' et de 'extra.o'. Notez que vous pouvez toujours passer l'adresse de début de votre programme à ld (par exemple -defsym _TEXT_START_ADDR = 0xAAAA0123) ainsi que l'adresse de début d'autres sections de mémoire comme bss, data. (par exemple -Tbss, -Tdata)
Faites attention à pour utiliser une adresse valide qui ne soit pas en conflit avec votre 'system.elf' car ld ne générera pas d'erreur pour cela. Vous pouvez définir de nouvelles zones pour le code chargé + data + bss dans votre script d'éditeur d'origine et recompiler le système. Ensuite, pointez les adresses de début vers vos zones définies en liant 'extra.o'.