Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Jak poznać długośc funkcji w celu przepisania do RAM

12 views
Skip to first unread message

Sebastian Biały

unread,
Dec 7, 2009, 5:02:26 PM12/7/09
to
Witam.

Jest sobie procesor von Neumanna posiadający dwa rodzaje pamięci RAM i
ROM. Odczyt z ROM wymaga dwoch cykli zegara, odczyt z RAM jednego.

Program wykonuje się z ROM.

Było by jednak znacznie fajniej, gdyby krytyczną część programu
skopiować do RAM i tam ją wywołać. To kilkadziesiąt instrukcji asm.

Zakladamy, że przepisywany do RAM fragment programu nie woła innych
procedur oraz korzysta wyłacznie ze zmiennych globalnych (o ustalonych
podczas linkowania adresach).

Kompilator gcc/g++.

Wygląda na to ze muszę osiągnąć dwie rzeczy:

a) skompilować jedną z procedur tak, żeby posiadała wylacznie skoki
względne (przepisanie bajt-w-bajt w ram nie popsuje mi skoków)

b) w runtime programu wiedzieć ile bajtów i z jakiego adresu odczytać i
przenieść do ram.

c) zawolać poprzez wskaźnik na funkcje

Czy ktoś mógłby mi powiedzieć, czy takie możliwości są w zasięgu gcc
(inne kompilatory pomijam) wprost z kodu C? Chciałbym o ile to możliwe,
aby zarówno program jak i magiczna procedura znajdowały sie w jednym
pliku cpp. Nie upieram sie, ale gdyby się dało ...

Co powinienem doczytać? Najbardziej zastanawia mnie czy w ogole można
odczytac z poziomu C/gcc dlugość funkcji.

To hakowanie, ale akurat w moim przypadku ma ono sens i zanim zaczne
bawić się asm wole zapytać o mozliwości samego gcc w tym względzie.

Tomasz bla Fortuna

unread,
Dec 7, 2009, 5:14:23 PM12/7/09
to
Dnia Mon, 07 Dec 2009 23:02:26 +0100
Sebastian Biały <he...@poczta.onet.pl> napisał(a):

> Czy ktoś mógłby mi powiedzieć, czy takie możliwości są w zasięgu gcc
> (inne kompilatory pomijam) wprost z kodu C? Chciałbym o ile to
> możliwe, aby zarówno program jak i magiczna procedura znajdowały sie
> w jednym pliku cpp. Nie upieram sie, ale gdyby się dało ...

Hm. Nie wiem co to za architektura, ale może da się po instruować
linker by przeniósł całą funkcję do RAMu?
W kodzie byś dopisał wtedy
void fun (void) __attribute__((section ("nazwa sekcji")));

I albo wstawisz tam nazwę, która od razu zostanie przeniesiona, albo
stworzysz nową i przeniesiesz. Jeśli możesz wrzucić do osobnego pliku
to bez takiej magii i kompilujesz z -fPIC i linkerem mówisz gdzie ma
wstawić. W razie gdyby się tak nie dało linkował bym jako osobny .o
kompilowany wcześniej -fPIC skryptami budowania określał wielkość
sekcji w tym .o i robił z tego #define, który potem używał w kodzie C.

Pewnie ktoś wymyśli Ci coś fajniejszego.

pzdr.
--
Tomasz bla Fortuna
jid: bla(at)af.gliwice.pl
pgp: 0x90746E79 @ pgp.mit.edu
www: http://bla.thera.be

Sebastian Biały

unread,
Dec 7, 2009, 5:22:39 PM12/7/09
to
Tomasz bla Fortuna wrote:
> Hm. Nie wiem co to za architektura

Arm7.

>, ale może da się po instruować
> linker by przeniósł całą funkcję do RAMu?

Niezupełnie. Efektem linkowania jest plik zawierający obraz pamięci
FLASH (ROM). Po wlaczeniu zasilania ktoś będzie musial ręcznie przepisac
te bajty do RAM, wiec jakiś kod napisać muszę.

> W kodzie byś dopisał wtedy
> void fun (void) __attribute__((section ("nazwa sekcji")));
> I albo wstawisz tam nazwę, która od razu zostanie przeniesiona, albo
> stworzysz nową i przeniesiesz.

Bawie się sekcjami i ok, ale jak mówie efektem koncowym jest plik z
zawartością rom i wszelkie sztuczki z linkerem się o to rozbiją.

> Jeśli możesz wrzucić do osobnego pliku
> to bez takiej magii i kompilujesz z -fPIC i linkerem mówisz gdzie ma
> wstawić. W razie gdyby się tak nie dało linkował bym jako osobny .o
> kompilowany wcześniej -fPIC skryptami budowania określał wielkość
> sekcji w tym .o i robił z tego #define, który potem używał w kodzie C.

No właśnie skryptow chciałbym uniknąc jeśli istnieje jakakolwiek inna
sztuczka pozwalająca poznać długośc funkcji podczas kompilacji. Jeśli
nie ma, to wrzuce funkcję w jakąs sekcje, odczytam jej długość i ustawie
prawidłowe #define (o ile to zadziała, bo to tylko teoria) dla "ręcznego
relokatora".

Zbych

unread,
Dec 7, 2009, 5:59:35 PM12/7/09
to
Sebastian Biały przemówił ludzkim głosem:

> Czy ktoś mógłby mi powiedzieć, czy takie możliwości są w zasięgu gcc

Generalnie robi się to tak:
1. W skrypcie linkera robisz sekcję w RAMie (np. .ramcode)
2. Dodajesz drugą sekcję we flashu, która posłuży jako obraz sekcji w
RAMie (opcja "AT", możesz popatrzeć jak to jest robione z sekcją danych
inicjalizowanych)
3. Do pliku crt dodajesz memcpy (tudzież pętlę kopiującą) przepisującą
na starcie zawartość obrazu z ROMu do RAMu (trzeba się posłużyć
adresami, które definiujesz również w skrypcie linkera)
4. Do funkcji, która ma być w RAMie dodajesz atrybut z sekcją
5. Nie zapomnij w skrypcie linkera ustawić, które sekcje lądują w
binarce (zostaw tylko te z flasha, chyba, że chcesz mieć binarkę 4GB).
Ja do tego wykorzystuję "NOLOAD"

To podejście ma tą podstawową zaletę, że kod ma od razu wstawione
odpowiednie adresy i funkcja nie musi być relokowalna.
Co do prędkości, to nie oczekuj cudów - w końcu teraz z tej samej
pamięci (po tej samej magistrali) będą latały i dane, i rozkazy.

Sebastian Biały

unread,
Dec 7, 2009, 6:13:59 PM12/7/09
to
Zbych wrote:
> Generalnie robi się to tak:

Ok, dzięki za opis, będe siedział nad skryptem linkera.

> Co do prędkości, to nie oczekuj cudów - w końcu teraz z tej samej
> pamięci (po tej samej magistrali) będą latały i dane, i rozkazy.

Oczekuje przyspieszenia, choć nie 2x. W zasadzie potrzebuje to jako
eksperyment bardziej, czy w ogole oplaca sie przerzucać niektóre
krytyczne fragmenty do ram.

0 new messages