Heim >Computer-Tutorials >Fehlerbehebung >Gibt es Quellcode für den DMA-Windows-Treiber?
Die zugehörigen Vorgänge von DMA werden auf Seite 545 von „Detailliertes Verständnis des Linux-Kernels“ vorgestellt. Wenn wir über DMA sprechen, müssen wir das Problem des Caches erwähnen. Das Buch zitiert das folgende Beispiel, um das Cache-Konsistenzproblem zu beschreiben:
Angenommen, der Gerätetreiber füllt einige Daten in den Speicherpuffer und weist dann das Hardwaregerät sofort an, die Daten mithilfe der DMA-Übertragung zu lesen. Wenn DMA auf diese physischen RAM-Speicherzellen zugreift und der Inhalt der entsprechenden Hardware-Cache-Zeile noch nicht in den RAM geschrieben wurde, liest das Hardware-Gerät höchstens den alten Wert im Speicherpuffer.
Es gibt jetzt zwei Möglichkeiten, mit DMA-Puffer umzugehen:
Konsistente DMA-Zuordnung:
Das Buch ist abstrakter: Jede Neuschreibung des DMA-Puffers wird direkt im Speicher aktualisiert, was auch als „Es ist“ bekannt ist ein Land, das synchron ist oder ein Land, das konsistent ist.
Streaming-DMA-Zuordnung:
Nach persönlichem Verständnis ist der Stream hier der Eingabe- und Ausgabestream. Wir müssen die Richtung des DMA-Puffers im Voraus angeben, z. B. ob der Puffer gelesen oder geschrieben werden soll. Es wird auch als asynchron oder inkonsistent bezeichnet. Einzelheiten finden Sie weiter unten.
Da in der x86-Architektur der Hardware-Gerätetreiber selbst den Zugriff auf den Hardware-Cache überwacht, gibt es in der x86-Architektur kein DMA-Konsistenzproblem. Für andere Architekturen wie MIPS, SPARC und POWERPC (einschließlich ARM) ist es notwendig, deren DMA-Konsistenz in der Software sicherzustellen.
Im Buch gibt es einen passenden Vorschlag, wie man zwischen den beiden oben genannten wählen kann. Wenn die CPU und der DMA-Prozessor auf unvorhersehbare Weise auf einen Puffer zugreifen, muss die Verwendung der konsistenten DMA-Zuordnungsmethode erzwungen werden (hier spreche ich). (Verstehen Sie, dass es nicht möglich ist, zu bestimmen, wann auf den Puffer zugegriffen wird.) In anderen Fällen ist die Streaming-DMA-Zuordnung vorzuziehen, da der Umgang mit einer konsistenten DMA-Zuordnung auf einigen Architekturen umständlich ist und zu einer geringeren Systemleistung führen kann.
Hier finden Sie eine detaillierte Einführung in das Streaming von DMA:
Der Puffer, auf den zugegriffen werden muss, muss vor der Datenübertragung zugeordnet werden (die Zuordnung hier bedeutet, dass einige Funktionen aufgerufen werden müssen, um den Kernel darüber zu informieren, dass der Puffer gestreamt wird). und wird nach der Übertragung abgebrochen.
Das Starten einer Streaming-DMA-Datenübertragung ist in die folgenden Schritte unterteilt:
1.
Wenn das DMA-Gerät nicht den S/G-Modus (Scatter/Gather) verwendet, muss sichergestellt werden, dass der Puffer physisch kontinuierlich ist. Der Linux-Kernel verfügt über zwei Funktionen, um kontinuierlichen Speicher zuzuweisen: kmalloc() und __get_free_pages( ). Beide Funktionen weisen den Maximalwert für die Zuweisung von Bytes als Einheit auf, der Maximalwert liegt bei etwa 64 KB, __get_free_pages() weist Seiten als Einheit zu und kann maximal 2^ Seiten zuweisen Der Bestellparameter wird durch das Makro MAX_ORDER in der Datei include/linux/Mmzone.h bestimmt (in der Standardkernelversion 2.6.18 ist dieses Makro als 10 definiert. Das heißt, theoretisch kann die Funktion __get_free_pages für up gelten
Nachdem Sie den Lese- und Schreibzugriff auf den DMA-Puffer gestartet haben, aktivieren Sie die Funktion dma_map_single(), um die Streaming-DMA-Zuordnung einzurichten Geben Sie die lineare Adresse des Puffers als Parameter ein und geben Sie die entsprechende Busadresse zurück.
Wenn die DMA-Übertragung abgeschlossen ist, müssen Sie die Funktion dma_unmap_single() freigeben (1). Um Konsistenzprobleme zu vermeiden, sollte der Treiber die Funktion dma_sync_single_for_device() aufrufen, um die Cache-Zeile entsprechend dem DMA-Puffer zu aktualisieren Greifen Sie auf den Speicherpuffer zu, bevor eine DMA-Datenübertragung abgeschlossen ist. Bei Bedarf sollte der Treiber jedoch die Funktion dma_sync_single_for_cpu() aufrufen, um die entsprechende Hardware-Cache-Zeile ungültig zu machen, bevor der Puffer gelesen wird
(3). wird auch mit __get_free_pages implementiert, die Freigabepufferfunktion, die kmalloc entspricht, ist kfree, und die Freigabepufferfunktion, die __get_free_pages entspricht, ist free_pages. Die spezifischen Anwendungs- und Freigabefunktionen im Zusammenhang mit __get_free_pages sind wie folgt:
Anwendungsfunktion:
alloc_pages(gfp_mask ,order) gibt die Adresse des ersten zugewiesenen Seitenrahmendeskriptors zurück, oder NULL, wenn die Zuweisung fehlschlägt. __get_free_pages(gfp_mask,order) ähnelt alloc_pages(), gibt jedoch den ersten Seitenrahmendeskriptor zurück. Wenn Sie die der linearen Adresse entsprechende Seitenrahmennummer erhalten müssen, müssen Sie das Makro virt_to_page(addr) aufrufen, um die lineare Adresse zu generieren. Die Freigabefunktion: __free_pages(page, order) betont hier hauptsächlich, dass die Seite freigegeben werden soll der Puffer. Die Seitenrahmennummer, in der sich die lineare erste Adresse befindet. free_pages(page, order) Diese Funktion ähnelt __free_pages(page, order), aber der Parameter, den sie empfängt, ist die lineare Adressadresse des ersten freizugebenden Seitenrahmens
Das obige ist der detaillierte Inhalt vonGibt es Quellcode für den DMA-Windows-Treiber?. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!