2010-04-21 5 views
7

Ich schreibe ein Boot-Skript für ein ARM-Cortex M3-basiertes Gerät. Wenn ich das Assembler-Boot-Skript und den C-Anwendungscode kompiliere und dann die Objektdateien kombiniere und sie auf mein Gerät übertrage, funktioniert alles.GNU ld entfernt Abschnitt

Wenn ich jedoch ar verwende ein Archiv (libboot.a) und kombiniert dieses Archiv mit der C-Anwendung zu erstellen gibt es ein Problem:

ich den Boot-Code in einem Abschnitt gesetzt habe:

.section .boot, "ax" 
    .global  _start 

_start: 
    .word  0x10000800 /* Initial stack pointer (FIXME!) */ 
    .word  start 
    .word  nmi_handler 
    .word  hard_fault_handler 
    ... etc ... 

Ich habe festgestellt, dass ld dies aus der endgültigen Binärdatei streift (der Abschnitt "boot" ist nicht verfügbar). Dies ist ganz natürlich, da es keine Abhängigkeit gibt, die ld kennt, aber es verursacht, dass das Gerät nicht ordnungsgemäß gestartet wird.

Meine Frage ist also: Was ist der beste Weg, um diesen Code zu erzwingen?

Antwort

10

Versuche Zugabe so etwas wie:

KEEP(*(.boot)) 

im ld Linker-Skript des Linker zu sagen, den .boot Abschnitt zu halten.

Aber ich ist nicht sicher, ob dies genug ist ld verursachen in beliebigen Objekten aus dem Archiv zu ziehen, die in dem .boot Abschnitt sind - es ist nicht ein Objekt überhaupt, es sei denn einige Symbole in diesem Objekt betrachten könnte es verursacht Wenn dies ein Problem ist, kann die Lösung die _start als Einstiegspunkt (mit -e _start in der LD-Befehlszeile oder ENTRY(_start) im Linker-Skript) angeben.

3

Ich denke, Sie möchten die --no-gc-Abschnitte Option an den Linker übergeben. Von der GNU ld documentation:

--gc-sections 
--no-gc-sections 

Enable garbage collection of unused input sections. 

`--gc-sections' decides which input sections are used 
by examining symbols and relocations. The section 
containing the entry symbol and all sections containing symbols 
undefined on the command-line will be kept, as will sections 
containing symbols referenced by dynamic objects. 
Note that when building shared libraries, the linker must 
assume that any visible symbol is referenced. Once this initial 
set of sections has been determined, the linker recursively marks 
as used any section referenced by their relocations. 
See `--entry' and `--undefined'. 
2

Der Linker wird nur aus einem Archiv benötigt diese Objekte extrahieren explizit verwiesen Symbole zu lösen. Ihr Start-Code wird nicht explizit referenziert, da er über den Reset-Vektor aufgerufen wird.

Wenn Ihr Boot-Code mehrere Module umfasst, sollten Sie eine teilweise verknüpft Objektdatei mit ld und die -r/--relocatable Option erstellen, wird dies die Objekte zu einem einzigen Objekt, ohne die Notwendigkeit zu vereinen alle Symbole (wie Haupt zu lösen() beispielsweise). Dies kann dann in einer vollständigen Verknüpfung mit Ihrem Anwendungscode verwendet werden. Wenn es sich nur um eine einzelne Objektdatei handelt, hat das Erstellen eines Archivs in keinem Fall einen wirklichen Vorteil (und wie Sie herausgefunden haben, wird es nicht funktionieren).

Beachten Sie, dass GNU C Runtime-Start-up traditionell in einer Datei namens crt0.o (kein Archiv) vermutlich aus dem gleichen Grund zur Verfügung gestellt wird.

1

Sie können die Option ld --whole-archive verwenden, um nicht referenzierte Symbole einzufügen. Diese ld options page hat dies für die Ganz Archiv --whole-Archiv

Für jedes Archiv auf die Befehlszeile erwähnt nach dem --whole-Archiv Option, umfasst das Archiv in der Verbindung jeder Objektdatei in , statt Durchsuchen des Archivs nach den erforderlichen Objektdateien. Dies wird normalerweise verwendet, um eine Archivdatei in eine freigegebene -Bibliothek zu verwandeln, wodurch jedes Objekt gezwungen wird, in der resultierenden gemeinsamen -Bibliothek enthalten zu sein. Diese Option kann mehr als einmal verwendet werden .
Zwei Hinweise, wenn diese Option von gcc verwendet wird: Erstens, gcc weiß nicht über diese Option, so müssen Sie -Wl, -whole-Archiv verwenden. Zweitens, vergessen Sie nicht, -WL, -no-whole-Archiv nach Ihrer Liste der Archive, weil gcc wird eine eigene Liste von Archiven zu Ihrem Link hinzufügen, und Sie können nicht wollen, dass diese Flagge diese als beeinflussen Gut.

Siehe auch diese Frage auf Stack-Überlauf, uses of whole-archive option

2

Sie können --whole-archive verwenden, wenn Sie verknüpfen, aber es ist eine große Elefantenpistole. Die Manpage Ansprüche:

Für jedes Archiv in der Befehlszeile nach der --whole-archive Option erwähnt, umfassen jede Objektdatei im Archiv in der Verbindung, anstatt die Suche im Archiv für die erforderlichen Objektdateien.

Verwandte Themen