Forum: Compiler & IDEs Befehle in anderen Speicher umkopieren und ausführen


von Wazaaab (Gast)


Lesenswert?

Hallo Leute,

ich zerbreche mir jetzt schon seit Stunden den Kopf, wie man folgenden
Sachverhalt bewerkstelligen könnte :

Ich programmiere einen ARM in C (++).
Weil ich am setting des Programmspeichers, in dem das Programm läuft,
herumfeilen möchte, muss ich die entsprechenden Befehle ins RAM
umkopieren, und dort ausführen. Anschließend soll das Programm wieder
zurück in den ursprünglichen Speicher zurückhüpfen und normal
weitermachen.

Ich wollte die kritischen Befehle in eine Funktion packen, und mit
memcpy ins SRAM schieben. Anschließend den Programmcounter umstellen
und gut ist.

Nun aber die Probleme dieser herangehensweise :
1. Wieviel muss ich umkopieren, bzw. wie groß ist diese Funktion. Gibt
es vielleicht etwas wie sizeof() für Funktionen ?

2. Wie springe ich wieder zurück ins RAM ? Wo ist die Rücksprungadresse
? Wie komme ich wieder dahin ?

Oder fällt euch da spontan was wesentlich besseres ein ?

Bin für alles offen !

von Karsten Brandt (Gast)


Lesenswert?

Welchen Prozessor und welche Entwicklungsumgebung setzt Du ein?

Karsten

von Wazaaab (Gast)


Lesenswert?

Ich benutze einen ATMEL AT91RM9200 und benutze das ARM-elf-GCC Paket.
Aber wieso sollte das relevant sein ?

von Heinz M. (Gast)


Lesenswert?

Du solltest Dich
- mit Linker-Scripten (->GNU ld doc)
- evtl mit PIC (position-independent code)
beschaeftigen.

Sprung ins RAM per Funktionsaufruf?
Zurueck per return?

h.

von Wazaab (Gast)


Lesenswert?

Hallo Heinz,

danke für die Antwort. Ich werde mich mal in diese Richtung schlau
machen.

Über das LinkerScript habe ich bereits nachgedacht. Wenn ich die
Funktion in den RAM linke habe ich jedoch Probleme sie im BootROM mit
dem Funktionspointer für das Umkopieren zu finden, oder ? Schließlich
sollte der ja dann auf das RAM zeigen.

Wie der Sprung ausgeführt werden soll ist eigentlich egal. Wichtig ist
nur, dass ein gewisses Codestück nicht aus dem BootROM läuft.

von Stefan (Gast)


Lesenswert?


von Wazaab (Gast)


Lesenswert?

@ Stefan

Klasse, genau was ich suche ! Manchmal fehlt einem einfach nur das
richtige Schlagwort.

@ all

Tausend dank euch allen :)

von Wazaaab (Gast)


Lesenswert?

So, habe das Teil entsprechend eingebunden.
Funktioniert insoweit einwandfrei :))

Nun möchte ich die Umkopierfunktion in C bewältigen, was ja auch weiter
nicht sonderlich schwer ist.

Was mir aber leider nach ein einigem Rumprobieren nicht gelungen ist,
ist die Adresse des in den RAM gelinken Teils herauszufinden.

Wie kann ich denn generell aus C die Adressen der im Linkerscript
definierten Speicherbereiche herausbekommen ? bzw. auf die dort
definierten Labels zugreifen ?

von Heinz M. (Gast)


Lesenswert?

Es ist moeglich, auf im Linkerscript definierte Symbole zuzugreifen, wie
auf
in anderen C Modulen definierte Variablen.

Wie das geht, sollte z.B. in
http://sourceware.org/binutils/docs-2.16/ld/index.html zu finden
sein...

Du interessierst Dich fuer "LMA" (nicht LMAA!;-) und "VMA".

h.

von Stefan (Gast)


Lesenswert?

Im Moment werden DATA und Ramfunktionen komplett kopiert, da im
angegebenen Beispiel keine Unterteilung Data<->Funktionen vorhanden
ist.

Die betreffenden globalen Symbole (_etext, _data und _edata) aus dem
ASM Startup-Code könnte man durchaus als externe Adressen in eine
lowlevel C-Kopierfunktion übernehmen. Du könntest über _my_own_symbol =
.; bestimmt auch eigene Symbole vor/nach deinen Funktionen
initialisieren...

Die Startadresse der Ramfunktionen nach dem Umkopieren kannst du über
den Adressoperator & herausfinden herausfinden. Du machst quasi einen
Funktionspointer. Mit der Endadresse der Funktion ist es kitzliger. Mir
fällt als Endadresse auf die Schnelle nur eine Dummyfunktion nach dem
Ende der Nutzfunktion(en) ein.

Aber ehrlich gesagt, ich verstehe allerdings den Sinn der angefragten
Aktion nicht.

von Wazaaab (Gast)


Lesenswert?

@Heinz

Genau das wars :)) Es läuft ! 2^10 Dank !
Wäre natürlich schön, wenn man direkt die LMA herausbekäme und nicht
die Krücke mit den Symbolen anderer Bereiche benutzen müßte.
Aber wenns läuft, läuft es !

@Stefan

>Die Startadresse der Ramfunktionen nach dem Umkopieren kannst du über
>den Adressoperator & herausfinden herausfinden. Du machst quasi einen
>Funktionspointer. Mit der Endadresse der Funktion ist es kitzliger.
>Mir
>fällt als Endadresse auf die Schnelle nur eine Dummyfunktion nach dem
>Ende der Nutzfunktion(en) ein.

Genau das waren auch meine ersten Ansätze. Ist alles zu kompliziert.

Die Funktion wird mit _attribute_ ((long_call, section
(".ramcopy")) einem selbstdefinierten Speicherbereich ramcopy
zugeordnet. Dieser wird im Linkerscript virtuell in den RAM gemappt.
Mit Hilfe eines Symboles am Ende des Bereichs davor, kann in C mit
extern variablen auf diese Bereiche bzw. Adressen zugegriffen werden.
Das Umkopieren geht damit super einfach.

Der Rücksprung geschieht dann einfach beim beenden der Funktion
automatisch. Ist ja auch ne ganz normale Funktion, die nur in einem
speziellen Speicherbereich liegt.

Ein entsprechendes C-Beispiel ist in dem Link von Heinz.

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.