2016-11-03 6 views
4

Ich verwende PCI-e-Port auf Freescale MPC8308-Prozessor (die auf PowerPC-Architektur basiert) und ich habe einige Probleme, wenn Sie versuchen, es zu verwenden. Der Endpunkt PCI-e-Gerät verfügt über Speicherplatz von 256 MB. Mit dem Paket "pciutils" kann ich den Konfigurationsbereich des Endpunktgeräts einfach lesen und schreiben.PCI-e Speicherplatz Zugriff mit mmap

Nach dem Schreiben von korrekten Werten in Konfigurationsregistern und dem Abrufen der Berechtigung zum Zugriff auf den Speicherbereich; Ich versuchte Speicherraum zuzugreifen, indem „mmap()“ Funktion in C verwenden und verwendet, um die Deskriptor-Datei befindet sich auf:

„/sys/devices/pci0000:00/0000:00:00.0/resource0“

Das war genau 256 MB (entspricht Speicherplatz des Endpunkt-Geräts), so scheint es, dass ich den richtigen Pfad für den Dateideskriptor verwende. Hier können Sie meinen Code mit „mmap()“ wie erwähnt in https://github.com/billfarrow/pcimem finden:

https://github.com/billfarrow/pcimem/blob/master/pcimem.c

Aber leider, wenn ich versuche, um Speicherplatz zu verwenden, indem Sie zurück Adresse von „mmap()“ mit der Funktion; Ich kann die schreibgeschützten Register des Endpunktgeräts nicht richtig lesen. Wenn ich Adressen lese, die größer als "0x7FFFFFC" sind, startet der MPC8308 neu. Unter Berücksichtigung der obigen Situation, vermisse ich irgendwelche Schritte zur Initialisierung der PCI-e-Schnittstelle? Sollte ich irgendetwas im Linux-Kernel-Image oder U-Boot-Code ändern? Gibt es etwas anderes für die Verwendung von PowerPC PCI-e mit mmap()? Haben Sie einen Beispielcode, mit dem ich PCI-e-Speicherplatz lesen kann?

Dank

+0

256 MB Speicherplatz für einen Endpunkt scheint zu groß zu sein. Auf meinem Prozessor (i.MX6) kann ich keinen Endpunkt größer als 16MB haben. Haben Sie einen Init-Fehler beim Booten von Linux für PCIe? Was ist Ihr PCIe-Speichergerät? Ist es ein FPGA? – FabienM

+0

ja es schien mir auch zu viel, aber ich habe keinen Fehler beim Booten von Linux und es hat 256 MB Speicher für das Gerät gewidmet, wie ich in/proc/iomem sehen kann. Das Endpunktgerät ist kein FPGA. Es ist ein ASIC mit PCI-e-Schnittstelle. –

+1

Eine andere Route besteht darin, die physikalische Adresse des Geräts und sein Limit zu finden und in/dev/mem abzubilden. (Ehrlich gesagt kann nicht garantieren, dass dies funktioniert. Ich bin gespannt, ob es tut.) – ruthafjord

Antwort

1

mmap() ist eine sehr nützliche, aber einfache Möglichkeit, auf PCIe-Geräte aus dem Benutzerbereich zuzugreifen.

Ich bemerke, dass Sie 0 als erstes Argument an mmap übergeben. In meinem Fall einer FPGA-Karte, die an einen x86-Computer angeschlossen ist, rufe ich lspci an, um die physikalische Adresse der Karte in den PCIE-Steckplatz zu bekommen. Dann benutze ich diese physikalische Adresse als erstes Argument für mmap. Ich weiß, dass Sie die BARs im Konfigurationsbereich des Geräts schreiben, aber vielleicht überprüfen Sie es mit lspci.

$ sudo lspci -s 02:00 -v 
02:00.0 Memory controller: Xilinx Corporation Device 8028 
    Subsystem: Xilinx Corporation Device 0007 
    Flags: bus master, fast devsel, latency 0, IRQ 11 
    Memory at f7e00000 (32-bit, non-prefetchable) [size=1M] 
    Capabilities: [80] Power Management version 3 
    Capabilities: [90] MSI: Enable- Count=1/1 Maskable- 64bit+ 
    Capabilities: [c0] Express Endpoint, MSI 00 
    Capabilities: [100] Advanced Error Reporting 
0

Vorwarnung: Vorbereitung für eine Nicht-Antwort. Es hört sich so an, als ob du das vom Userspace aus machst. Das MMAPing von Geräten in den Benutzerbereich ist keine gängige Praxis (dies hätte schwerwiegende Auswirkungen auf die Sicherheit, es sei denn, Sie sind sich der Architektur sehr bewusst). Ehrlich gesagt bin ich mir nicht einmal sicher, ob das möglich sein soll. Ich habe Mühe, an Fälle zu denken, in denen dies geschieht. Normalerweise werden Geräte nur im Kernel verwendet, und ich würde empfehlen, einen Treiber oder ein Kernel-Modul zu schreiben, anstatt im Benutzerbereich herumzuspielen.

+1

Vielen Dank für Ihr Feedback. Sie können mmap() als eine allgemeine Lösung verwenden, die speziell für den Zugriff auf Geräte eingeführt wurde, wenn Sie PCI-e verwenden. zum Beispiel in "Linux Gerätetreiber" Buch Kapitel 15 wird erwähnt, dass mmap() für den Zugriff auf PCI-e Speicherplatz verwendet werden kann.Ich stimme jedoch zu, dass das Schreiben eines Kernel-Moduls für diesen Zweck eine eher strategische Lösung ist; es hat auch seine Herausforderungen im Vergleich zur einfachen mmap-Verwendung, insbesondere wenn Ihr Gerät vom Kernel bekannt ist und entsprechende Speicherbereich-Regionen dem Endpunkt-Gerät gewidmet sind. –

+0

Ich denke, ich bin verwirrt, was du vorhast. ¯ \ _ (ツ) _/¯ Wenn Sie einen Gerätetreiber haben, der die mmap-Aufrufe bereits vermittelt (was anscheinend durch dieses Buch angeregt wird, von einem schnellen Skimming), dann kann das vernünftig sein (z. B. was jede Nvidia-Grafik) Karte tut, um Bounce-Puffer zu vermeiden). Das Stück, das mich nervös macht, ist die Abbildung der gesamten MMIO-Region eines Geräts (die dem Benutzerraum vermutlich die vollständige Kontrolle über das Gerät gibt und den gesamten Punkt der Benutzer-Kernel-Trennung unterläuft). – ruthafjord