Forum: FPGA, VHDL & Co. woher kennt mmap() meine Hardware Adressen


von Mattias M. (brushless)


Lesenswert?

Hallo liebe Leute,
ich habe mal eine Verständnis frage...
Ich arbeite gerade mit dem RedPitaya (ein SoC von Xilinx). Das ist ein 
FPGA kombiniert mit 2 ARM9 Kernen. Zu dem RP gehört ein sogenanntes FPGA 
Memory Map Register. Das sieht in etwa so aus:
0x00000000    Beginn
0x40000000    House
0x40300000    Oszilloskop oder so...

Jetzt beinhaltet das FPGA schon diverse Register und Funktionen, wie im 
Memory Map beschrieben. Auf dem System läuft ein Linux. In dem Memory 
Map steht, dass sich an der Adresse 0x40000030 8 LEDs befinden. Jetzt 
habe ich gelernt, dass die virtuelle Datei /dev/mem den gesamten 
Arbeitsspeicher des Systems abbildet. Wenn ich diese Datei öffne 
(open(/dev/mem) kann ich ja mit mmap(4096, , , 0x40000000) einen Pointer 
auf diese Adresse im Arbeitsspeicher bekommen. Mit einem weiteren offset 
von 0x30 habe ich tatsächlich Zugriff auf die LEDs. Woher in aller Welt 
weiß aber mmap()  wo die Hardware Adressen von meinem FPGA stehen wenn 
/dev/mem meinen gesamten Arbeitsspeicher abbildet ??? Ich gebe doch 
lediglich den offset und die Pagegrösse an. Worauf bezieht sich dieser 
offset und wo im FPGA steht der ???

Danke schon im voraus
Mattias

von Antti L. (trioflex)


Lesenswert?

Bei Zynq ist es so

1) Die hardware wir zusammengebastelt mit Vivado IPI
2) HDF - Hardware Handout File wird exportiert
3) petalinux importiert die HDF und erzeigt device tree source code
4) ... build
5) linux bootet und die treiber holen die addressen von device tree 
binary

Antti
igg.me/at/zynq

von Georg A. (georga)


Lesenswert?

> Woher in aller Welt weiß aber mmap()  wo die Hardware Adressen von
> meinem FPGA stehen wenn /dev/mem meinen gesamten Arbeitsspeicher
> abbildet ???


mmap weiss gar nix. Was glaubst du gibst du mit dem 0x40000000 an?

von brushless (Gast)


Lesenswert?

Das weiss ich gerade nicht. Mir kommt es so vor,als würden meine 
Hardware Adressen bei Null beginnen. Deshalb die Frage, wie kann es 
sein, dass nur der offset ausreicht, um an die richtige Adresse zu 
kommen ???
Gruss Mattiad

von Markus F. (mfro)


Lesenswert?

Na ja, dein mmap()-Aufruf mapt den physischen Speicherbereich ab 
0x40000000 auf virtuelle Adressen ab 4096 (0x1000).

Greifst Du jetzt auf die (virtuelle) Adresse (0x1000 + 0x30) zu, geht 
der Speicherzugriff auf die physische Adresse 0x40000030 und damit auf 
dein im FPGA konfiguriertes Register.

Klar soweit?

von brushless (Gast)


Lesenswert?

Ich dachte die 4096 ist nur die Grösse, die im Arbeitsspeicher gemappt 
wird. Die Adresse die mir mmap zurück gibt, ist sehr gross. So ungefähr 
0x6B000000. Dann +0x30 komme ich an meine LEDs ran. Woher weiss mein 
Sytem ,dass Ox40000000 meine Hardware ist ?.
Gruss Mattias

von Antti L. (trioflex)


Lesenswert?

address Bereich 0x4000 0000

sind die "custom peripheres" die in FGPA implementiert sind.

was da sind ist abhanging welches bitstream geladen ist

von Georg A. (georga)


Lesenswert?

> Woher weiss mein Sytem ,dass Ox40000000 meine Hardware ist ?.

Deine Fragen drehen sich im Kreis... Die Basisadresse der HW wird in 
irgendeinem SoC-Builder-Tool festgelegt/ausgewürfelt. An der 
Schnittstelle CPU zum Rest-FPGA wird das dann auch so konfiguriert, dass 
die CPU Zugriffe in dem Bereich auf das externe Interface gibt. Das Tool 
schreibt das raus (Device-Tree, #defines, Text-Log, was auch immer) und 
wer da "dran" hängt, nimmt das. Wenn du die 0x40000000 beim mmap 
angibst, bist du derjenige, der das aus dem Log nimmt. Wenn die 
0x30000000 angeben würdest, würde das mmap das auch dumm mappen. Wäre 
halt vermutlich nichts sinnvolles dahinter...

Das ist ja eigentlich das schöne am mmap, man kann ohne Treiber und 
sonstiges Systemvorkehrungen wild in der HW rumstochern.

: Bearbeitet durch User
von Markus F. (mfro)


Lesenswert?

brushless schrieb:
> ...Ich dachte...

Das ist beim Programmieren immer schlecht. Wissen ist deutlich besser 
;).

Der erste Parameter bei mmap() ist (zumindest, solange Du nicht bei 
flags MAP_FIXED spezifizierst) lediglich (d)ein Vorschlag, wo im 
virtuellen Speicher Du den physikalischen Speicherbereich gerne gemappt 
hättest.

Wenn das System meint, es passe, ist er nachher da (Returnwert) oder 
eben woanders.

Das System weiß nichts von Hardware an Adresse 0x40000000. Das weißt 
nur Du selbst (hoffentlich) und deshalb gibst Du auch genau die Adresse 
bei mmap() an. Du solltest Dir klarmachen, daß alle Adressen, die dein 
Programm sonst so sieht, virtuelle Adressen sind, die die MMU 
"irgendwo" auf die Hardware mappt.

Lediglich der bei mmap() übergebene Offset beschreibt eine 
physikalische Hardwareadresse. Das ist der einzige Weg (abgesehen 
davon, einen Kernel-Treiber zu programmieren), an der virtuellen 
Speicherverwaltung vorbei auf physische Adressen zuzugreifen.

: Bearbeitet durch User
von Mattias M. (brushless)


Lesenswert?

Hallo  Antti,

das ist ja mal eine Aussage. Wenn die Adresse 0x4000 0000 wirklich immer 
fest ist, dann verstehe ich das. Ich habe mich übrigens oben 
verschrieben. Ich mappe mit mmap(0, Page, , , 0x40000000). Damit kann 
das BS den Bereich selber festlegen, wo es die Page hinlegt. Jetzt 
müsste ich nur noch wissen, wo das mit der festen "custom peripheres" 
steht. Ist das bei dem Zynq immer so ? oder kann man das bei Vivado 
einstellen ?

Gruß Mattias

von Mattias M. (brushless)


Lesenswert?

So,
vielen Dank für eure Hilfe, habe es jetzt gefunden.
Im "System-Level Address Map" auf Seite 113 im Technical Reference 
Manual steht das
"General Purpose Port #0 to the PL, M_AXI_GP0" von 0x4000 0000 bis
0x7FFF FFFF geht.

Gruß
Mattias

von Markus F. (mfro)


Lesenswert?

Wenn ich das richtig sehe, kann man das einstellen. Stellt man's nicht 
ein, vergibt die Software sinnvolle Defaults.

Beim "Dranrumdrehen" wär' ich vorsichtig: schließlich müssen sich ja 
beide Seiten (FPGA-Config + ARM Kernel) drüber einig sein, wo die 
Hardware zu finden ist.
Wenn der Linux-Kernel z.B. der Ansicht ist, daß da, wo Du Register 
hinkonfiguriert hast, Memory sein müsste, kracht's.

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.