Forum: Compiler & IDEs ld: Sections eines Objects innerhalb einer library an bestimmte Adresse linken


von TuNichtGut (Gast)


Lesenswert?

Hallo,
ich baue in einem Projekt eine CMSIS Library.
Jetzt habe ich unterschiedlich schnelle Speicherbereiche.

Startup -> soll in den langsamen Teil
Alles andere -> passt dann gerade noch so in den schnellen Teil:
1
SECTIONS
2
{
3
  .text_DDR_startup : /*ONLY_IF_RO /* see initial ATTENTION! */
4
  {
5
    KEEP(*(.vectors))
6
    *libCMSIS.a:*startup_ARM_CM3.S.obj(.text)
7
    /**libCMSIS.a:(.text)*/
8
  } > SLOW_MEM
9
10
...
11
}
Das wäre jetzt das korrekte Handling nach meinem Verständnis gewesen.
Er zieht aber nicht die Section raus.

Mit auskommentieren vom *libCMSIS.a:(.text*) funktioniert es, aber dann 
liegt mehr in dem langsamen Bereich als soll.
Wer kann mich schnell bezüglich meines Syntax Fehlers/Verständins 
Problems aufklären?

Wenn ich mir das *.a File genauer mit objdump und readelf anschaue, 
scheint eine Zuteilung aufgrund des ürspringlichen *.obj-Files ja noch 
möglich zu sein!?

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Vermutlich hast du irgendwo ein *(.text) für den schnellen Speicher? 
Dies hat dann wahrscheinlich Priorität. Verschiebe die Section für den 
schnellen Speicher mal hinter den für den langsamen...

von TuNichtGut (Gast)


Lesenswert?

Alles davor im Script:
[avrasm]
MEMORY
{
  SLOW_MEM (rx)  :  ORIGIN = 0x00000000, LENGTH = 2048M
  FAST_MEM (rx)  :  ORIGIN = 0x10000000, LENGTH = 64K
  RAM (rw)       :  ORIGIN = 0x20000000, LENGTH = 128K
}


/* Linker script to place sections and symbol values.
 * It references following symbols, which must be defined in code:
 *   Reset_Handler : Entry of reset handler
 *
 * It defines following symbols, which code can use without definition:
 *   __exidx_start
 *   __exidx_end
 *   _copy_table_start_
 *   _copy_table_end_
 *   _zero_table_start_
 *   _zero_table_end_
 *   __etext
 *   _data_start_
 *   __preinit_array_start
 *   __preinit_array_end
 *   __init_array_start
 *   __init_array_end
 *   __fini_array_start
 *   __fini_array_end
 *   _data_end_
 *   _bss_start_
 *   _bss_end_
 *   _end_
 *   end
 *   __HeapLimit
 *   __StackLimit
 *   __StackTop
 *   __stack
 */

ENTRY(Reset_Handler)

von TuNichtGut (Gast)


Lesenswert?

Vielleicht noch aus dem readelf output:
1
File: ./libCMSIS.a(startup_ARMCM3.S.obj)
2
There are 24 section headers, starting at offset 0x1ddc:
3
  [Nr] Name
4
       Type            Addr     Off    Size   ES   Lk Inf Al
5
       Flags
6
  [ 0] 
7
       NULL            00000000 000000 000000 00   0   0  0
8
       [00000000]: 
9
  [ 1] .text
10
...

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Versuch mal "libCMSIS.a(.text)" und "libCMSIS.a(.text*)", ohne führendes 
Sternchen.

von TuNichtGut (Gast)


Lesenswert?

Niklas G. schrieb:
> Versuch mal "libCMSIS.a(.text)" und "libCMSIS.a(.text*)", ohne führendes
> Sternchen.

?
"*libCMSIS.a:(.text)" funktioniert ja für die ganze Lib.
Nur da sind halt auch Sachen drin, die zur Laufzeit in relevantem Maße 
aufgerufen werden und dann auch im langsamen Speicher liegen.
...
Ich kann natürlich umbauen, dass keine Lib gebaut wird. Aber eigentlich 
sollte das hier doch ganz einfach funktionieren. Kann doch nicht sein 
grr.

Aber schon mal danke fürs draufschauen!

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

TuNichtGut schrieb:
> "*libCMSIS.a:(.text)" funktioniert ja für die ganze Lib.
> Nur da sind halt auch Sachen drin, die zur Laufzeit in relevantem Maße
> aufgerufen werden und dann auch im langsamen Speicher liegen.

Und wo/wie wählst du die kritischen Sachen aus, die im schnellen 
Speicher landen sollen? Das müsste dann vor diesem "Catch-All" stehen. 
Oder willst du die gesamte CMSIS im schnellen Speicher haben?

: Bearbeitet durch User
von TuNichtGut (Gast)


Lesenswert?

... ist ja eigentlich egal ob ich mir zuerst den kleinen langsamen Teil 
rauspicke, oder den schnellen Teil. Solange ich zu doof für die 
scheinbar richtige Syntax bin :(.

Aktuell passt alles gerade so rein, wenn ich nur die paar Bytes Startup 
rausschmeiße ;).

Alles danach funktioniert Problemlos, da ich dann für .text nur noch ein
1
.text :
2
  {
3
    __data2_start__ = .;
4
    *(.text*)
5
     *(.rodata*)
6
7
    KEEP(*(.eh_frame*))
8
    __data2_end__ = .;
9
  } > FAST_MEM AT SLOW_MEM
mache. Davor ist noch der ganze C++ kram mit den Konstruktor/Destruktor, 
Stackunwinding und so Kram der nicht verwendet wird. Basiert auf einem 
ARM Beispiel, hier wird nur C verwendet.

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

TuNichtGut schrieb:
> ... ist ja eigentlich egal ob ich mir zuerst den kleinen langsamen Teil
> rauspicke, oder den schnellen Teil

Ja, aber mit "libCMSIS.a:(.text)" pickst du nicht den langsamen Teil 
raus, sondern nimmst alles in den langsamen Speicher. Wenn du danach 
versuchst etwas schnelles heraus zu picken, klappt das nicht (wird 
ignoriert).


TuNichtGut schrieb:
> Solange ich zu doof für die
> scheinbar richtige Syntax bin :(.

Ich glaube nicht dass die Syntax der Fehler ist. Die Anweisungen müssen 
in der richtigen Reihenfolge kommen.

TuNichtGut schrieb:
> Ich kann natürlich umbauen, dass keine Lib gebaut wird.

Das ändert auch nichts. Auch hier ist die Reihenfolge wichtig.

Woher soll der Linker wissen was schnell ist und in den schnellen 
Speicher soll?

: Bearbeitet durch User
von TuNichtGut (Gast)


Lesenswert?

Niklas G. schrieb:
> TuNichtGut schrieb:
>> ... ist ja eigentlich egal ob ich mir zuerst den kleinen langsamen Teil
>> rauspicke, oder den schnellen Teil
>
> Ja, aber mit "libCMSIS.a:(.text)" pickst du nicht den langsamen Teil
> raus, sondern nimmst alles in den langsamen Speicher. Wenn du danach
> versuchst etwas schnelles heraus zu picken, klappt das nicht (wird
> ignoriert).
>
> Woher soll der Linker wissen was schnell ist und in den schnellen
> Speicher soll?

Aber ja "nur" von der gebauten CMSIS Lib.
War auch nur der Test, ob ich da was komplett verkehrt mache.
Deswegen will ich ja eigentlich über den spezifischeren Pfad:
1
"./libCMSIS.a:startup_ARM_CM3.S.obj"(.text)
gehen.
Allerdings klappt das ja nicht. Dabei verstehe ich die Doku so, ...
och miste!
1
ld Doku: "For instance, you cannot extract a from an archive by using "archive:file" in an INPUT command."
 :(

von Niklas G. (erlkoenig) Benutzerseite


Lesenswert?

Ach, jetzt verstehe ich es erst. Nur "startup_ARM_CM3.S.obj" aus der 
CMSIS soll in den langsamen, der ganze Rest in den schnellen Speicher?

TuNichtGut schrieb:
> ld Doku: "For instance, you cannot extract a from an archive by using
> "archive:file" in an INPUT command."

Das ist dann doof. Du kannst mit ".section" den Startup-Code in eine 
spezielle Section packen, und die dann mit *(.StartupCode) o.ä. in den 
langsamen Speicher übernehmen.

von TuNichtGut (Gast)


Lesenswert?

Niklas G. schrieb:
> Ach, jetzt verstehe ich es erst. Nur "startup_ARM_CM3.S.obj" aus
> der
> CMSIS soll in den langsamen, der ganze Rest in den schnellen Speicher?
>
> TuNichtGut schrieb:
>> ld Doku: "For instance, you cannot extract a from an archive by using
>> "archive:file" in an INPUT command."
>
> Das ist dann doof. Du kannst mit ".section" den Startup-Code in eine
> spezielle Section packen, und die dann mit *(.StartupCode) o.ä. in den
> langsamen Speicher übernehmen.

Genau!

So werd ich es wohl machen (müssen). Oder halt das ganze vorab nicht 
zusammenpacken. Aber das ist nicht mein Bereich ;), da mische ich mich 
jetzt nicht mehr ein.

Aber noch Danke!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.