Operasi DMA yang berkaitan diperkenalkan pada halaman 545 "Pemahaman Mendalam tentang Kernel Linux". Apabila bercakap tentang DMA, kita perlu menyebut isu Cache. Buku itu memetik contoh berikut untuk menerangkan masalah ketekalan Cache:
Anggap bahawa pemacu peranti mengisi beberapa data ke dalam penimbal memori, dan kemudian segera mengarahkan peranti perkakasan untuk membaca data menggunakan pemindahan DMA. Jika DMA mengakses sel memori RAM fizikal ini, dan kandungan baris cache perkakasan yang sepadan belum lagi ditulis kepada RAM, maka peranti perkakasan membaca paling banyak nilai lama dalam penimbal memori.
Kini terdapat dua cara untuk menangani penimbal DMA:
Pemetaan DMA yang konsisten:
Buku ini lebih abstrak Dari segi orang awam, sebarang penulisan semula penimbal DMA akan dikemas kini terus ke dalam ingatan, juga dikenali sebagai It is. tanah yang disegerakkan atau tanah yang konsisten.
Strim pemetaan DMA:
Menurut pemahaman peribadi, aliran di sini ialah aliran input dan output Kita perlu menentukan arah penimbal DMA terlebih dahulu, seperti sama ada untuk membaca penimbal atau menulis penimbal. Ia juga dipanggil tak segerak atau tidak konsisten Sila lihat di bawah untuk mendapatkan butiran.
Oleh kerana dalam seni bina x86, pemacu peranti perkakasan itu sendiri akan mengintip cache perkakasan yang diakses, jadi tiada masalah konsistensi DMA dalam seni bina x86. Untuk seni bina lain seperti MIPS, SPARC dan POWERPC (termasuk ARM), adalah perlu untuk memastikan konsistensi DMA mereka dalam perisian.
Terdapat cadangan yang sesuai dalam buku tentang cara memilih antara dua di atas Jika CPU dan pemproses DMA mengakses penimbal dengan cara yang tidak dapat diramalkan, maka kaedah pemetaan DMA yang konsisten mesti dipaksa untuk digunakan (di sini saya bercakap. tentang yang tidak dapat diramalkan Memahami bahawa tidak mungkin untuk menentukan bila mereka mengakses penimbal). Dalam kes lain, kaedah pemetaan DMA penstriman adalah lebih baik, kerana menangani pemetaan DMA yang konsisten adalah menyusahkan pada sesetengah seni bina dan boleh mengakibatkan prestasi sistem yang lebih rendah.
Berikut adalah pengenalan terperinci kepada penstriman DMA:
Penimbal yang perlu diakses perlu dipetakan sebelum penghantaran data (pemetaan di sini bermakna beberapa fungsi perlu dipanggil untuk memaklumkan kernel bahawa penimbal distrim), dan dibatalkan selepas pemetaan.
Memulakan pemindahan data DMA terbahagi kepada langkah berikut:
1.
Apabila peranti DMA tidak menggunakan mod S/G (scatter/gather), ia mesti dipastikan bahawa buffer adalah berterusan secara fizikal Kernel Linux mempunyai dua fungsi untuk memperuntukkan memori berterusan: kmalloc() dan __get_free_pages( ). Kedua-dua fungsi mempunyai nilai maksimum untuk memperuntukkan memori berterusan kmalloc memperuntukkan bait sebagai unit, maksimum ialah kira-kira 64KB, __get_free_pages() memperuntukkan halaman sebagai unit, dan boleh memperuntukkan maksimum 2^ nombor pesanan halaman parameter pesanan Ditentukan oleh makro MAX_ORDER dalam fail include/linux/Mmzone.h (dalam versi kernel lalai 2.6.18, makro ini ditakrifkan sebagai 10. Maksudnya, secara teori, fungsi __get_free_pages boleh memohon sehingga kepada 1
2 pada satu masa. Wujudkan pemetaan Penstriman
Selepas membaca dan menulis akses kepada penimbal DMA, dan sebelum memulakan pemindahan peranti DMA, dayakan fungsi dma_map_single() untuk mewujudkan pemetaan DMA penstriman ini alamat linear penimbal sebagai parameternya dan Kembalikan alamat bas yang sepadan
3 Lepaskan pemetaan penstriman
Apabila pemindahan DMA selesai, kami perlu melepaskan fungsi dma_unmap_single()
(1). Untuk mengelakkan caching. Untuk masalah konsisten, pemacu harus memanggil fungsi dma_sync_for_device() untuk menyegarkan talian cache yang sepadan dengan penimbal DMA jika perlu
(2). akses penimbal memori sebelum pemindahan data DMA selesai, tetapi jika perlu, pemacu harus memanggil fungsi dma_sync_single_for_cpu() untuk membatalkan baris cache perkakasan yang sepadan sebelum membaca penimbal
(3). juga dilaksanakan menggunakan __get_free_pages, fungsi penimbal keluaran yang sepadan dengan kmalloc ialah kfree, dan fungsi penimbal keluaran yang sepadan dengan __get_free_pages ialah free_pages Beberapa fungsi aplikasi dan keluaran yang berkaitan dengan __get_free_pages adalah seperti berikut:
Fungsi aplikasi:
alf_p_pages. order) mengembalikan alamat deskriptor bingkai halaman pertama yang diperuntukkan, atau NULL jika peruntukan gagal __get_free_pages(gfp_mask,order) adalah serupa dengan alloc_pages(), tetapi ia mengembalikan deskriptor bingkai halaman pertama. Jika anda perlu mendapatkan nombor bingkai halaman yang sepadan dengan alamat linear, anda perlu memanggil makro virt_to_page(addr) untuk menjana alamat linear Fungsi keluaran: __free_pages(halaman, pesanan) di sini terutamanya menekankan bahawa halaman itu akan dikeluarkan. penimbal. Nombor bingkai halaman di mana alamat pertama linear terletak free_pages(halaman, pesanan) Fungsi ini serupa dengan __free_pages(halaman, pesanan), tetapi parameter yang diterima ialah penambah alamat linear bagi bingkai halaman pertama yang akan dikeluarkan
Atas ialah kandungan terperinci Adakah terdapat sebarang kod sumber untuk pemacu Windows DMA?. Untuk maklumat lanjut, sila ikut artikel berkaitan lain di laman web China PHP!