Forum: Compiler & IDEs Woher kommen die Segmentnamen ".text", ".bss" und ".data" ?


von Ralf (Gast)


Lesenswert?

Hi,

ich such mir in der GCC Doku grad n Wolf, ich versuche herauszufinden, 
woher die Segmentnamen ".text", ".bss" und ".data" eigentlich kommen?
Sind das fest eingebaute Namen und der Linker weist Funktion ohne 
'attribute' automatisch .text zu (und analog dazu Variablen .data bzw. 
.bss), oder ist das einfach eine Konvention, die einfach in allen 
Linker-Scripts Einzug gehalten hat?

Ralf

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ralf schrieb:

> ich such mir in der GCC Doku grad n Wolf, ich versuche herauszufinden,
> woher die Segmentnamen ".text", ".bss" und ".data" eigentlich kommen?

UNIX-Historie.  "bss" steht der Überlieferung nach für "block
starting symbol", was wiederum auf irgendeiner alten Maschine die
Mnemonik eines entsprechenden Befehls war.

> Sind das fest eingebaute Namen und der Linker weist Funktion ohne
> 'attribute' automatisch .text zu (und analog dazu Variablen .data bzw.
> .bss), oder ist das einfach eine Konvention, die einfach in allen
> Linker-Scripts Einzug gehalten hat?

Sowohl als auch.  Es dürfte der Assembler sein, der Default-Sections
einträgt, für ausführbaren Code eben .text, für Datenreservierungen
.data.  .bss bzw. COMMON muss explizit belegt werden.

von Ralf (Gast)


Lesenswert?

@Jörg Wunsch:
> UNIX-Historie.  "bss" steht der Überlieferung nach für "block
> starting symbol", was wiederum auf irgendeiner alten Maschine die
> Mnemonik eines entsprechenden Befehls war.
Ah, okay. Also "so ist's halt gewesen, so ist's auch geblieben". :)

> Sowohl als auch.  Es dürfte der Assembler sein, der Default-Sections
> einträgt, für ausführbaren Code eben .text, für Datenreservierungen
> .data.  .bss bzw. COMMON muss explizit belegt werden.
Hmmmm... Okay, ich wollt es mir so einrichten, dass .text mit "Code" 
angegeben wird. Aber wenn der Assembler das defaultmäßig vergibt, dann 
lass ich's so.

Wenn ich das richtig verstanden habe, dann ist .text + .data die Größe, 
die ein Firmware-Image belegt, ist das korrekt? .text ist reiner Code, 
.data sind die initialisierten Variablen. .bss ist informell wieviel 
nicht initialisierter RAM verbraucht wurde oder der komplette RAM?

Ralf

von Manfred F. (manfred_f)


Lesenswert?

Jörg Wunsch schrieb:
> UNIX-Historie.  "bss" steht der Überlieferung nach für "block
> starting symbol", was wiederum auf irgendeiner alten Maschine die
> Mnemonik eines entsprechenden Befehls war.

Interessant. Ich hab damals noch gelernt, es hieße "Block Storage 
Segment":
http://www.wachtler.de/ck/9_Speichermodell_Prozesses.html

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ralf schrieb:

> Wenn ich das richtig verstanden habe, dann ist .text + .data die Größe,
> die ein Firmware-Image belegt, ist das korrekt?

Ja, bzw. der ladbare Teil einer ELF-Datei, wenn man sie direkt
lädt (bspw. in einem unixartigen System).

> .text ist reiner Code,
> .data sind die initialisierten Variablen.

Yep.

> .bss ist informell wieviel
> nicht initialisierter RAM verbraucht wurde oder der komplette RAM?

.bss sind die nicht initialisierten Daten, die durch den Startup-Code
ausgenullt werden.  .bss + .data ist der gesamte statische RAM-
Verbrauch.  Zur Laufzeit kommen dann noch Stack und ggf. Heap hinzu.

Manfred Freise schrieb:
> Interessant. Ich hab damals noch gelernt, es hieße "Block Storage
> Segment":

Scheint ein gängiger Irrtum zu sein.

Meine Erinnerung war auch nicht völlig korrekt: "block started by
symbol", siehe Wikipedia:

http://en.wikipedia.org/wiki/.bss

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Um die Verwirrung noch zu vergrößern, unterscheider der Linker zwischen 
Input- und Output-Sections.

Zu .text gehört daher auch .progmem.data, in die zB Lookup-Tabellen per 
progmem gelegt werden.  Und Sprungtabellen aus switch/case werdenn auch 
dort abgelegt.

Weiers gehören zur text-Sections: .vectors, .lowtext, .jumptables, 
.trampolines, .ctors, .dtors, ...

Zu .bss wiederum gehört auch .noinit, das vom Startupcode nicht 
gelöscht wird.

von Ralf (Gast)


Lesenswert?

@Jörg Wunsch:
>> Wenn ich das richtig verstanden habe, dann ist .text + .data die Größe,
>> die ein Firmware-Image belegt, ist das korrekt?
> Ja, bzw. der ladbare Teil einer ELF-Datei, wenn man sie direkt
> lädt (bspw. in einem unixartigen System).
Okay... Verwirrung :)
Was heisst in dem Zusammenhang "ladbarer Teil"? Das ist doch das gesamte 
Programm, oder? Die .bss entsteht zur Laufzeit, ohne Stack oder 
nicht-statische lokale Variablen, dachte ich.

> Zur Laufzeit kommen dann noch Stack und ggf. Heap hinzu.
Heap ist soweit ich das verstanden habe (siehe auch oben) der freie 
RAM-Bereich, in dem lokale Variablen erzeugt werden, korrekt?

@Johann L.:
> Um die Verwirrung noch zu vergrößern, unterscheider der Linker zwischen
> Input- und Output-Sections.
> ...
Ja, das hatte ich in der GCC Doku schon gelesen (aber noch nicht ganz 
verinnerlicht, ich arbeite dran grins ).
Ist für einen Newbie etwas viel. Hab bisher nur C & ASM für 8051er 
programmiert, da ist das ein klitze bitze einfacher ;)

Gibt's eigentlich schon von jemandem, der da richtig tief drin steckt 
einen Artikel dazu? ;)
Wie lernt man das denn alles? Immer dann wenn man's braucht, oder wie? 
Ich find die Doku in der Hinsicht nicht geeignet.

Ralf

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ralf schrieb:

> Was heisst in dem Zusammenhang "ladbarer Teil"?

Alles das, was in der ELF-Datei das Flag PT_LOAD gesetzt hat. ;-)

> Die .bss entsteht zur Laufzeit, ohne Stack oder
> nicht-statische lokale Variablen, dachte ich.

bss ist statisch bereits vorbelegt, während der Initialisierung
wird lediglich das Ausnullen vorgenommen.  Im Prinzip könnte man
bss auch wie data behandeln, dann müsste man allerdings die Nullen
mit in der Datei (bzw. dann im Flash) speichern.  Früher (vor
Version 4.x) hat GCC auch zwischen diesen beiden Varianten
unterschieden (auf global scope natürlich bezogen):
1
int foo;  /* .bss, wird implizit mit 0 initialisiert */
2
int foo = 0; /* .data, 0 wurde explizit als Initialwert gespeichert */

Aktuell optimiert er das zweite jedoch auch als bss.

>> Zur Laufzeit kommen dann noch Stack und ggf. Heap hinzu.

> Heap ist soweit ich das verstanden habe (siehe auch oben) der freie
> RAM-Bereich, in dem lokale Variablen erzeugt werden, korrekt?

Nein, lokale Variablen werden auf dem Stack angelegt.  Der Heap ist
für die dynamische Speicherverwaltung da (malloc() bei C, new bei
C++).

> Wie lernt man das denn alles?

Du lernst es doch gerade. :-)

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Jörg Wunsch schrieb:

> Früher (vor Version 4.x) hat GCC auch zwischen diesen beiden
> Varianten unterschieden (auf global scope natürlich bezogen):
>
> int foo;  /* .bss, wird implizit mit 0 initialisiert */
> int foo = 0; /* .data, 0 wurde explizit als Initialwert gespeichert */

Macht das einen Unterschied? Dafür ist doch 
-f[no-]zero-initilized-in-bss (ab 3.3.1).

von Ralf (Gast)


Lesenswert?

@Jörg Wunsch:
>> Was heisst in dem Zusammenhang "ladbarer Teil"?
> Alles das, was in der ELF-Datei das Flag PT_LOAD gesetzt hat. ;-)
grins Okay :)

> bss ist statisch bereits vorbelegt, während der Initialisierung
> wird lediglich das Ausnullen vorgenommen.
Damit die nicht initialisierten Daten C-konform den Wert 0 haben.

> Im Prinzip könnte man bss auch wie data behandeln, dann müsste man
> allerdings die Nullen mit in der Datei (bzw. dann im Flash) speichern.
Klar, eine Schleife, die den kompletten RAM erstmal mit Null füllt ist 
kürzer ;)

> Nein, lokale Variablen werden auf dem Stack angelegt.  Der Heap ist
> für die dynamische Speicherverwaltung da (malloc() bei C, new bei
> C++).
Dann ist das eine der Denkfallen, in die ich getappt bin. Beim 8051 ist 
der Stack für Rücksprungadressen und Sicherung von Registern während 
Funktionsaufrufen bzw. Interrupt-Service-Funktionen.
Die Bezeichnung Stack hat hier wohl eine ganz andere Bedeutung. Dann 
muss ich mir das nämlich auch noch genauer angucken, denn ich versteh 
gerade nicht, wo denn dann die Rücksprungadressen etc. landen und wie 
dann Parameter gehandhabt werden, die nicht in die Register R0-R12 
passen. Zu dem Kapitel muss ich dann nämlich auch noch schauen, wie 
lokale Variablen gehandhabt werden verglichen mit globalen etc.

>> Wie lernt man das denn alles?
> Du lernst es doch gerade. :-)
Ja, das stimmt, aber a) kann ich dich ja nicht die ganze Zeit alles 
fragen, was ich grad wissen will, damit ich ne gescheite Basis hab, und 
b) wohnst du wahrscheinlich nicht um die Ecke, so dass ich dir 
wenigstens n Bier ausgeben könnte ;)
Mir bleibt momentan einzig mich zwischendurch mal zu bedanken -> Danke!

Ralf

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Johann L. schrieb:

>> int foo;  /* .bss, wird implizit mit 0 initialisiert */
>> int foo = 0; /* .data, 0 wurde explizit als Initialwert gespeichert */
>
> Macht das einen Unterschied?

Ja, im Flash-Verbrauch bzw. der Größe der ELF-Datei schon.

> Dafür ist doch
> -f[no-]zero-initilized-in-bss (ab 3.3.1).

OK, dann ist es schon ab GCC 3.3.1 so, dass er explizit mit 0
initialisierte Variablen freiwillig in den BSS legt.

Davor (bzw. mit -fno-zero-initialized-in-bss) ist es einfach eine
Pessimierung, wenn ein Programmierer denkt, er müsste dem C-Standard
nicht übern Weg trauen, und globale oder statische Variablen
explizit mit 0 initialisieren, "für den Fall der Fälle".

Ralf schrieb:
>> bss ist statisch bereits vorbelegt, während der Initialisierung
>> wird lediglich das Ausnullen vorgenommen.
> Damit die nicht initialisierten Daten C-konform den Wert 0 haben.

Es gibt noch weitere Gründe, warum man diese Bereiche ausnullt:
Sicherheit beispielsweise.  Es sollte ja nicht so sein, dass du die
Passwörter eines anderen Nutzers plötzlich in deinem nicht initiali-
sierten Speicher vorfindest … insofern muss BSS bei aktuellen
Betriebssystemen dann gar nicht unbedingt explizit genullt werden,
wenn man sich drauf verlassen kann, dass das OS es sowieso macht.

> Beim 8051 ist
> der Stack für Rücksprungadressen und Sicherung von Registern während
> Funktionsaufrufen bzw. Interrupt-Service-Funktionen.

Stichwort Parameter- und Returnstack.  IAR zum Beispiel trennt auch
beide.  Vorteil: man kann die Returnadressen besser nachvollziehen.
Nachteil: man kann nicht beide Stacks "automatisch" so anlegen, dass
sie stets nur so viel verbrauchen, wie tatsächlich nötig ist.  Einer
von beiden muss statisch vorgegeben werden (typisch der Returnstack),
und wehe, seine Tiefe wird zur Laufzeit überschritten.

Unix-Systeme haben daher typisch beide in einen vereinigt.  Das macht
das Modell etwas komplizierter, aber dafür wird nur so viel Platz
benötigt, wie tatsächlich erforderlich ist.  Je nach Architektur
gibt es einen sogenannten frame pointer, über den man die Aufruf-
hierarchie dann verfolgen kann.

von Le X. (lex_91)


Lesenswert?

Hallo,
sehr interessant das Thema hier :-)

Deswegen reicht es wahrscheinlich auch, wenn nur die Sektionen .data und 
.text ins Hex-File übernommen werden, richtig?
(Bei objcopy)

von Ralf (Gast)


Lesenswert?

Guten Morgen zusammen,

wie ist das dann eigentlich, wenn ich nun beispielsweise einen 
RAM-Bereich mit einem anderen Namen anlege, sagen wir mal einfach .RAM2. 
RAM2 liegt innerhalb vom normalen RAM, also .data. ist RAM2 dann 
automatisch auch .data?

Ralf

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Das hängt davon am ob .RAM2 eine Input-Section ist oder eine 
Output-Section, der ein eigener Spreicherbereich und Input-Sections 
zugeordnet werden per Linker-Script.

Wird die Input-Section nicht im Linker-Script behandelt, dann handelt es 
sich um eine Orphan-Section, die der Linker anhand ihrer Flags zuordnet 
bzw. zuzuordnen versucht.

Legt man Daten ich eine nicht-Standard Input-Section, so werden diese 
u.U. nicht initialisier vom Startup-Code, denn avr-gcc berücksichtigt 
aus Effizienzgründen lediglich .bss* und .data*, siehe PR18145.

von Masl (Gast)


Lesenswert?

Wie würde ich denn nun eine eigene Section anlegen und Compiler 
mitteilen, er solle mir genau da mein Zeugs reinlegen?
Sagen wir, ich würde gerne 3 8-Bit Werte an immer der-selben Adresse 
liegen haben? Geht das?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

le x. schrieb:
> Deswegen reicht es wahrscheinlich auch, wenn nur die Sektionen .data und
> .text ins Hex-File übernommen werden, richtig?
> (Bei objcopy)

ojbcopy übernimmt ohnehin nur Sektionen mit Inhalt.  Hat man
allerdings auch Sektionen für EEPROM und/oder Fuses, dann würden
diese (mit ihren fiktiven Adressen) auch mit kopiert.  Daher kann
man das auch entsprechend einschränken.  Hat man Sektionen mit
Nicht-Standard-Namen, muss man diese natürlich ggf. ebenfalls mit
kopieren lassen.

Masl schrieb:
> Wie würde ich denn nun eine eigene Section anlegen und Compiler
> mitteilen, er solle mir genau da mein Zeugs reinlegen?
> Sagen wir, ich würde gerne 3 8-Bit Werte an immer der-selben Adresse
> liegen haben? Geht das?

Zum Beispiel (Offsets beziehen sich jetzt auf AVR, geht aber im
Prinzip mit jeder Architektur ungefähr so):
1
$ cat test.c
2
#include <stdint.h>
3
4
#define ALTSECTION __attribute__((section(".alt")))
5
6
volatile uint8_t var1 ALTSECTION;
7
volatile uint8_t var2;
8
9
int
10
main(void)
11
{
12
        return var1 + var2;
13
}
1
$ avr-gcc -Os -mmcu=atmega1281 -o test.elf test.c -Wl,--section-start=.alt=0x805000
2
$ avr-objdump -dh test.elf
3
4
test.elf:     file format elf32-avr
5
6
Sections:
7
Idx Name          Size      VMA       LMA       File off  Algn
8
  0 .text         0000010a  00000000  00000000  00000094  2**1
9
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
10
  1 .alt          00000001  00805000  00805000  0000019e  2**0
11
                  CONTENTS, ALLOC, LOAD, DATA
12
  2 .bss          00000001  00800200  00800200  0000019e  2**0
13
                  ALLOC
14
  3 .stab         000006cc  00000000  00000000  000001a0  2**2
15
                  CONTENTS, READONLY, DEBUGGING
16
  4 .stabstr      00000054  00000000  00000000  0000086c  2**0
17
                  CONTENTS, READONLY, DEBUGGING
18
19
Disassembly of section .text:
20
21
00000000 <__vectors>:
22
   0:   0c 94 66 00     jmp     0xcc    ; 0xcc <__ctors_end>
23
   4:   0c 94 78 00     jmp     0xf0    ; 0xf0 <__bad_interrupt>
24
[...]
25
26
000000f4 <main>:
27
  f4:   20 91 00 50     lds     r18, 0x5000
28
  f8:   80 91 00 02     lds     r24, 0x0200
29
  fc:   30 e0           ldi     r19, 0x00       ; 0
30
  fe:   28 0f           add     r18, r24
31
 100:   31 1d           adc     r19, r1
32
 102:   c9 01           movw    r24, r18
33
 104:   08 95           ret
34
35
[...]

Allerdings bekommt man ohne einen modifizierten Linkerscript wohl
offenbar nur ladbare Sektionen auf diese Weise hin, also solche mit
Initialisierungsdaten, wobei die Initialisierungsdaten jedoch nicht
vom Startup-Code berücksichtigt werden (der kennt die ja nicht).  Ein
Äquivalent zu einer BSS-Sektion auf diese einfache Weise zu
generieren, ist mir nicht gelungen.

Wenn man nur wenige Daten auf festen Adressen hat und diese Adressen
mit der Hand verwalten kann/möchte, geht auch diese Variante:
1
$ cat test.c
2
#include <stdint.h>
3
4
extern volatile uint8_t var1;
5
volatile uint8_t var2;
6
7
int
8
main(void)
9
{
10
        return var1 + var2;
11
}
1
$ avr-gcc -Os -mmcu=atmega1281 -o test.elf test.c -Wl,--defsym=var1=0x805000
2
$ avr-objdump -dh test.elf
3
4
test.elf:     file format elf32-avr
5
6
Sections:
7
Idx Name          Size      VMA       LMA       File off  Algn
8
  0 .text         0000010a  00000000  00000000  00000074  2**1
9
                  CONTENTS, ALLOC, LOAD, READONLY, CODE
10
  1 .bss          00000001  00800200  00800200  0000017e  2**0
11
                  ALLOC
12
  2 .stab         000006cc  00000000  00000000  00000180  2**2
13
                  CONTENTS, READONLY, DEBUGGING
14
  3 .stabstr      00000054  00000000  00000000  0000084c  2**0
15
                  CONTENTS, READONLY, DEBUGGING
16
17
Disassembly of section .text:
18
19
00000000 <__vectors>:
20
   0:   0c 94 66 00     jmp     0xcc    ; 0xcc <__ctors_end>
21
   4:   0c 94 78 00     jmp     0xf0    ; 0xf0 <__bad_interrupt>
22
23
[...]
24
25
000000f4 <main>:
26
  f4:   20 91 00 50     lds     r18, 0x5000
27
  f8:   80 91 00 02     lds     r24, 0x0200
28
  fc:   30 e0           ldi     r19, 0x00       ; 0
29
  fe:   28 0f           add     r18, r24
30
 100:   31 1d           adc     r19, r1
31
 102:   c9 01           movw    r24, r18
32
 104:   08 95           ret
33
34
[...]

von Masl (Gast)


Lesenswert?

Danke dir,
das mit __attribute__((section(".alt"))) war mir aus der avr-libc Doku 
bekannt. Nur dachte ich bisher, ich müsste diese Sektion noch irgendwo 
"erstellen", z.B. im Linkerscript. Aber das wird ja anscheinend 
"automatisch" gemacht.

Das mit den Initialisierungsdaten ist mir noch bischen unklar.
Bedeutet das, die Daten die ich in meiner eigenen Sektion liegen habe 
werden "aufwendig" initialisiert, d.h. so wie auch bei .data der Fall?
Wenns nur ein paar Variablen sind sollte man ja damit leben können.

Nochwas: wie bekomme ich beim Linkeraufruf die erste freie Adresse? 
Sagen wir, ich möchte die Daten direkt zwischen .bss und dem Heap haben. 
Mein Makefile kennt ja die Größe von .data + .bss nicht.

Viele Grüße,
Masl

von Masl (Gast)


Lesenswert?

Ok, vergiss meine letzte Frage.
Die Daten immer direkt nach .bss zu platzieren ist natürlich 
Schwachsinn, dadurch liegen sie ja auch nicht "fest".

D.h. ich würde mir irgendeine Adresse ausdenken müssen, wo ich die Daten 
haben will.
Sagen wir mal, die Adresse liegt zufällig im Bereich .data.

Würde nun der Linker initialisierte Daten in .data legen, dann kommt 
irgendwann meine Sektion, und dann wird .data fortgesetzt?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Masl schrieb:
> Das mit den Initialisierungsdaten ist mir noch bischen unklar.
> Bedeutet das, die Daten die ich in meiner eigenen Sektion liegen habe
> werden "aufwendig" initialisiert, d.h. so wie auch bei .data der Fall?

Nein, sie landen zwar in der Objektdatei ("dem ELF-File"), aber
da der Startup-Code nichts davon weiß (das würde nur über
entsprechende Hilfsmarken im Linkerscript funktionieren), kann
er den RAM damit nicht vorladen.  Bleibt also der Platzverbrauch
in der Objektdatei übrig.

Masl schrieb:
> Würde nun der Linker initialisierte Daten in .data legen, dann kommt
> irgendwann meine Sektion, und dann wird .data fortgesetzt?

Nein, der Linker kann nichts teilen.  Er würde dir einen section
conflict anzeigen.

von Masl (Gast)


Lesenswert?

Dann bleibt ja eigentlich für so ein Vorhaben nur der Bereich vor .data, 
also direkt die erste verfügbare RAM-Adresse nach den memory-mapped 
registern?

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Masl schrieb:
> Dann bleibt ja eigentlich für so ein Vorhaben nur der Bereich vor .data,
> also direkt die erste verfügbare RAM-Adresse nach den memory-mapped
> registern?

Ist zumindest die sinnvollste Variante.  .data kannst du ja mit
-Wl,--section-start=.data=0x80xxxx problemlos nach hinten schieben.

Alternativ könntest du einen Bereich hinter dem Stack dafür anlegen,
dann musst du nur die Stackpointerinitialisierung ändern.  Geht bei
der avr-libc über das Symbol __stack, welches standardmäßig auf
RAMEND gesetzt wird.

von Masl (Gast)


Lesenswert?

Jörg Wunsch schrieb:
> Ist zumindest die sinnvollste Variante.  .data kannst du ja mit
> -Wl,--section-start=.data=0x80xxxx problemlos nach hinten schieben.

Muss ich das extra machen, oder reicht es wenn ich einfach meine eigene 
Sektion davor einfüge?

Alles Nachfolgende sollte ja automatisch verschoben werden, wenn nötig 
(zumindest wenn .data in den externen RAM verschoben wird werden .bss 
und der Heap mitverschoben).

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Masl schrieb:
> Muss ich das extra machen, oder reicht es wenn ich einfach meine eigene
> Sektion davor einfüge?

"davor einfügen" impliziert einen eigenen Linkerscript.  Ja, das geht.

Die andere Variante hat den Vorteil, sowas nicht zu brauchen, sondern
komplett mit Kommandozeilenargumenten auszukommen.

von Ralf (Gast)


Lesenswert?

Hi,

da hab ich wohl ein echt interessantes Thema angerissen :)

Ihr habt's jetzt von der AVR-Implementierung des GCC, ich brauch's 
konkret für Cortex-Controller. Ich hoffe, die bisherigen Beiträge lassen 
sich auf beides anwenden?

Kann man sich eigentlich ein "virtuelles" Segment anlegen? Also 
bestimmte Startadresse und Länge, Inhalt wird nicht initialisiert oder 
in irgendeiner anderen Weise durch den Startup-Code angefasst.

Ralf

von Jörg W. (dl8dtl) (Moderator) Benutzerseite


Lesenswert?

Ralf schrieb:
> Ich hoffe, die bisherigen Beiträge lassen
> sich auf beides anwenden?

Ja, im Großen und Ganzen schon.

> Kann man sich eigentlich ein "virtuelles" Segment anlegen? Also
> bestimmte Startadresse und Länge, Inhalt wird nicht initialisiert oder
> in irgendeiner anderen Weise durch den Startup-Code angefasst.

Per Linkerscript auf jeden Fall.  Da die ARM-Leute sowieso dazu
tendieren, dass jeder seinen eigenen (mehr oder minder buggigen :-)
Linkerscript in seiner Applikation mit herumschleppt, dürfte das
aber für dich kein Thema sein.

von Ralf (Gast)


Lesenswert?

@Jörg Wunsch:
> Per Linkerscript auf jeden Fall.  Da die ARM-Leute sowieso dazu
> tendieren, dass jeder seinen eigenen (mehr oder minder buggigen :-)
> Linkerscript in seiner Applikation mit herumschleppt, dürfte das
> aber für dich kein Thema sein.
Okay, dann muss ich mir das automatisch erzeugte Linker-Script mal 
angucken und entsprechend modifizieren.

So, dann kommt als nächstes auf die Prüfliste, wie denn Zugriffe über 
Pointer eigentlich im GCC realisiert werden :)
Da kommt mittlerweile eine schöne Stichwort-Sammlung raus, aber ist ja 
bald Wochenende, dann kann ich mal "nachforschen".

Ralf

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.