2017-02-02 2 views
0

Est-il possible de créer un programme de démarrage/démarrage d'assemblage bare metal avec des options de ligne de commande GNU LD uniquement? lieu d'un script -T habituel pour une cible Cortex-M4?Est-il possible de créer un programme de démarrage/démarrage d'assemblage bare metal simple en utilisant uniquement les options de ligne de commande GNU LD

J'ai passé en revue la documentation de GNU LD et ai recherché divers emplacements comprenant ce site; Cependant, je n'ai trouvé aucune information suggérant que l'utilisation exclusive d'options de ligne de commande pour l'éditeur de liens GNU est possible ou impossible.

Ma tentative de gestion de la disposition du fichier objet sans un fichier script * .ld fourni par le fournisseur est purement académique. Ce n'est pas un devoir. Je ne demande pas d'aide pour écrire le code d'assemblage de démarrage. Je cherche simplement une réponse définitive ou une autre direction des ressources.

$ arm-none-eabi-ld bootup.o -o bootup @bootup.ld.cli.file 

contenu Sample bootup.ld.cli.file

--entry 0x0 
--Ttext=0x0 
--section-start .isr_vector=0x0 
--section-start _start=0x4 
--section-start .MyCode=0x8c 
--Tdata=0x20000000 
--Tbss=0x20000000 
-M=bootup.map 
--print-gc-sections 
+0

Vous pouvez le faire avec un fichier de liaison (définissez les données de section en utilisant [output section data] (https://sourceware.org/binutils/ docs/ld/Output-Section-Data.html) avec 'BYTE',' SHORT', 'LONG' et' QUAD' Vous pouvez aussi faire lire votre fichier depuis stdin pour pouvoir utiliser 'echo' ou d'autres méthodes Ces instructions ('BYTE, SHORT, LONG, QUAD') sont principalement utiles pour fournir des informations d'en-tête pour un autre chargeur de système (peut-être du code SOC ROM) .C'est donc ** possible **, c'est –

+0

@artlessnoise - Oui, merci, mais dans le cas présent, j'essaie d'éviter le fichier linker, du moins directement. – InfinitelyManic

+0

Je vois, votre 'bootup.ld.cli' ressemble beaucoup à un lien fichier er, mais ce n'est pas techniquement. Je pensais que vous ne vouliez pas compiler/assembler du code pour créer un fichier bootable/exécutable. Votre titre me trompe. –

Répondre

2

vous avez votre réponse là le -Ttext = nombre -Tdata = nombre et ainsi de suite sont pas des éléments de script éditeur de liens gnu ils sont gnu éléments de ligne de commande. notez le signe at sur votre ligne de commande. Un script de gnu linker ressemble plus à ceci (bien que la plupart soient significativement plus compliqués même s'ils n'ont pas besoin d'être).

MEMORY 
{ 
    rom : ORIGIN = 0x08000000, LENGTH = 0x1000 
    ram : ORIGIN = 0x20000000, LENGTH = 0x1000 
} 

SECTIONS 
{ 
    .text : { *(.text*) } > rom 
    .rodata : { *(.rodata*) } > rom 
    .bss : { *(.bss*) } > ram 
} 

Notez que l'éditeur de liens gnu est un peu drôle quand vous utilisez l'approche -Ttext = adresse, parfois, il insérera les lacunes que vous pourriez avoir quelques kilo-octets de programme et au lieu de le plaçant juste de façon linéaire à l'adresse comme il devrait en mettre, puis tamponner un peu d'espace mort, puis en mettre plus, sans jamais comprendre pourquoi mais pour des cibles extrêmement limitées le script linker (vs ligne de commande) tous les autres facteurs maintenus constants, ne met pas l'écart dans la sortie.

EDIT:

so.s

.cpu cortex-m0 
.thumb 

.thumb_func 
.global _start 
_start: 
stacktop: .word 0x20001000 
.word reset 
.word hang 
.word hang 
.word hang 
.word hang 

.thumb_func 
reset: 
    b hang 
.thumb_func 
hang: b . 

flash.s

.cpu cortex-m0 
.thumb 

.thumb_func 
.global _start 
_start: 
stacktop: .word 0x20001000 
.word reset 
.word hang 
.word hang 
.word hang 
.word hang 
.word hang 

.thumb_func 
reset: 
    bl notmain 
    b hang 

.thumb_func 
hang: b . 

.thumb_func 
.globl dummy 
dummy: 
    bx lr 

flash.ld

MEMORY 
{ 
    rom : ORIGIN = 0x08000000, LENGTH = 0x1000 
    ram : ORIGIN = 0x20000000, LENGTH = 0x1000 
} 

SECTIONS 
{ 
    .text : { *(.text*) } > rom 
    .rodata : { *(.rodata*) } > rom 
    .bss : { *(.bss*) } > ram 
} 

blinker02.c

void dummy (unsigned int); 

int notmain (void) 
{ 
    unsigned int ra; 
    for(ra=0;ra<100;ra++) dummy(ra); 
    return(0); 
} 

Makefile

ARMGNU = arm-none-eabi 

AOPS = --warn -mcpu=cortex-m0 
COPS = -Wall -O2 -nostdlib -nostartfiles -ffreestanding -mcpu=cortex-m0 

all : blinker02.bin sols.bin socl.bin 

clean: 
    rm -f *.bin 
    rm -f *.o 
    rm -f *.elf 
    rm -f *.list 

so.o : so.s 
    $(ARMGNU)-as $(AOPS) so.s -o so.o 

flash.o : flash.s 
    $(ARMGNU)-as $(AOPS) flash.s -o flash.o 

blinker02.o : blinker02.c 
    $(ARMGNU)-gcc $(COPS) -mthumb -c blinker02.c -o blinker02.o 

blinker02.bin : flash.ld flash.o blinker02.o 
    $(ARMGNU)-ld -o blinker02.elf -T flash.ld flash.o blinker02.o 
    $(ARMGNU)-objdump -D blinker02.elf > blinker02.list 
    $(ARMGNU)-objcopy blinker02.elf blinker02.bin -O binary 

sols.bin : so.o 
    $(ARMGNU)-ld -o sols.elf -T flash.ld so.o 
    $(ARMGNU)-objdump -D sols.elf > sols.list 
    $(ARMGNU)-objcopy sols.elf sols.bin -O binary 

socl.bin : so.o 
    $(ARMGNU)-ld -o socl.elf -Ttext=0x08000000 -Tbss=0x20000000 so.o 
    $(ARMGNU)-objdump -D socl.elf > socl.list 
    $(ARMGNU)-objcopy socl.elf socl.bin -O binary 

La différence entre la ligne de commande et la liste des fichiers de script éditeur de liens SOCI et sols sont les noms

diff sols.list socl.list 
2c2 
< sols.elf:  file format elf32-littlearm 
--- 
> socl.elf:  file format elf32-littlearm 

ne va pas à se soucier de démontrer la différence que vous pouvez voir en bas la route.

Pour l'assemblage uniquement, vous n'avez pas à vous soucier des fichiers no start et des autres options de ligne de commande (sur gcc). Avec des objets C, vous faites. en ne permettant pas au linker d'utiliser le code bootstrap tel que construit ou configuré (ou laisse dire C library), vous devez en fournir un, si vous ne compliquez pas le script linker au point que des fichiers objets spécifiques sont appelés, puis le ordering des objets sur la ligne de commande, si vous échangez flash.o et blinker02.o sur la ligne de commande ld dans le makefile, le binaire ne fonctionnera pas. vous pouvez définir des points d'entrée tout ce que vous voulez mais ceux-ci sont strictement pour le chargeur, si c'est du métal nu qu'il semble être alors le point d'entrée est inutile, le matériel démarre comment il démarre, dans ce cas avec une adresse cortex-m est la valeur à charger dans le pointeur de la pile, l'adresse quatre est l'adresse du vecteur de réinitialisation (avec l'ensemble de lsbits puisqu'il s'agit d'une machine uniquement au pouce, laissez les outils faire cela pour vous en utilisant le marqueur thumb_func est une adresse de destination de branche). J'ai saupoudré cortex-m0 environ un parce que c'est ce que j'ai pris ce code et deux armv4t original et armv5t ou comme appelé dans le nouveau bras docs "toutes les variantes du pouce", est l'instruction d'armement le plus portable mis à travers les cœurs de bras. avec votre cortex-m4 vous pouvez vous en débarrasser ou peut-être en faire un -m3 ou -m4 pour insérer les extensions arm2-m thumb2.

donc la réponse courte est

arm-none-eabi-ld -o so.elf -Ttext=0x08000000 -Tbss=0x20000000 so.o 

est plus que suffisant pour faire des binaires de travail suppose vous ne besoin d'un .data. .data nécessite beaucoup plus de choses, script d'éditeur de liens, un bootstrap plus compliqué, etc. Que ou vous faites une chose de copie-saut, compilez le programme REAL à exécuter en sram seulement (point d'entrée différent de style de bras complet mais à l'adresse de base de RAM), puis écrire un outil adhoc pour prendre ce binaire et le transformer en dire .word 0xabcdef entrées dans un programme qui copie de flash pour ramer tout le programme REAL puis branche, que le programme de copie et de saut est maintenant flash seulement sans .data ni .bss vraiment nécessaire et peut utiliser la ligne de commande, de même que le programme RAM réel seulement. Et je t'ai probablement déjà perdu sur celui-là. De même, en utilisant la ligne de commande, vous ne pouvez ou ne devez pas supposer que .bss est mis à zéro, votre bootstrap doit le faire aussi. Maintenant, si vous avez .bss et pas de .data, alors vous pouvez mettre à zéro tout le ram au démarrage avant de vous connecter au point d'entrée de vos programmes C (j'utilise notmain() car au moins un ancien compilateur ajoute des ordures inutiles au binary s'il voyait une fonction main() et pour souligner le fait que normalement il n'y a rien de magique dans la fonction nommée main().). Les scripts de Linker sont spécifiques à la chaîne d'outils, donc aucune raison de s'attendre à ce que les scripts de gnu linker soient portés vers Kiel pour être portés vers ARM (oui, je sais qu'Arm possède Kiel maintenant faisait référence à RVCT ou autre), etc. le premier problème .data/.bss. Idéalement, vous voulez que vos outils fassent le travail, alors ils savent comment bit .data et .bss sont si juste qu'ils vous disent, comment vous leur laissez dire que vous créez le script du linker correctement (au moins avec ld) et c'est difficile , mais il crée des variables si vous voulez qui peut définir des choses comme l'adresse de début .bss, l'adresse de fin pour .bss peut-être même quelques maths pour les soustraire et obtenir longueur, de même pour .data, alors dans le bootstrap la mémoire .bss utilisant l'adresse de début et la longueur, et/ou l'adresse de début et l'adresse de fin. Pour .data vous avez besoin de deux adresses, où vous le mettez en flash (plus de script de foo foo) et où il veut aller en RAM, et la longueur puis les copies de bootstrap.

donc en gros si vous écrivez ce code

unsigned int x=5; 
unsigned int y; 

et que vous utilisez un script de ligne de commande de liaison, il n'y a aucune raison que ce soit à attendre que x soit 5 ou y être 0 lorsque la première fonction C est activé qui utilise ces variables. Si vous supposez que x sera un 5 alors votre programme échouera.

si vous faites cela au lieu

unsigned int x; 
unsigned int y; 
void myfun (void) 
{ 
    x=5; 
    y=0; 
} 

maintenant ces missions sont des instructions dans .text et non valeurs.données de sorte qu'il fonctionnera toujours en ligne de commande ou pas simple script de liaison ou compliqué, etc

+0

La présentation semble correcte lors de la visualisation via le fichier map, objdump et readelf; Cependant, je ne suis pas en mesure de franchir le ResetHandler. Le PC n'avance pas; C'est pourquoi je demande si une approche par ligne de commande est suffisante pour une mise en page complète et correcte. Je vais marquer votre réponse en conséquence, car je pense que cela devrait fonctionner. – InfinitelyManic

+1

oui absolument construit avec et sans scripts éditeur de liens pendant des années, la principale différence est ce bizarre ld gnu ... –

+0

vous avez un objet est ce langage d'assemblage ou essayez-vous de faire confiance à la chaîne d'outils bootstrap? (qui ne fonctionnera pas sans le script d'éditeur de liens correspondant qui va avec). –