Bagikan melalui


Menggunakan I/O Langsung dengan PIO

Driver yang menggunakan I/O terprogram (PIO) daripada DMA harus memetakan buffer ruang pengguna menjadi rentang alamat ruang sistem. Gambar berikut menggambarkan bagaimana manajer I/O menyiapkan permintaan IRP_MJ_READ untuk operasi transfer PIO yang menggunakan I/O langsung.

diagram yang mengilustrasikan i/o langsung untuk perangkat yang menggunakan pio.

Gambar menunjukkan bagaimana perangkat yang menggunakan PIO menangani tugas yang sama.

  1. Beberapa rentang alamat virtual ruang pengguna mewakili buffer utas saat ini, dan konten buffer tersebut mungkin benar-benar disimpan di sejumlah halaman yang tidak disarankan secara fisik. Jika panjang buffer bukan nol, manajer I/O membuat MDL untuk menjelaskan buffer ini.

  2. Manajer I/O melayani permintaan baca utas saat ini, yang alurnya melewati berbagai alamat virtual ruang pengguna yang mewakili buffer.

  3. Manajer I/O atau FSD memeriksa buffer yang disediakan pengguna untuk aksesibilitas. Jika manajer I/O telah membuat MDL, manajer I/O memanggil MmProbeAndLockPages dengan MDL, yang menentukan rentang alamat virtual untuk buffer pengguna. MmProbeAndLockPages juga mengisi rentang alamat fisik yang sesuai di MDL.

  4. Manajer I/O menyediakan penunjuk ke MDL (MdlAddress) dalam IRP yang meminta operasi transfer. Hingga manajer I/O atau sistem file memanggil MmUnlockPages setelah driver menyelesaikan IRP, halaman fisik yang dijelaskan dalam MDL tetap terkunci dan ditetapkan ke buffer. Namun, alamat virtual dalam MDL seperti itu dapat menjadi tidak terlihat (dan tidak valid), bahkan sebelum IRP dikirim ke driver perangkat atau ke driver perantara yang mungkin berlapis di atas driver perangkat.

  5. Jika driver memerlukan alamat sistem (virtual), driver memanggil MmGetSystemAddressForMdlSafe dengan penunjuk MdlAddress IRP untuk memetakan alamat virtual ruang pengguna di MDL ke rentang alamat ruang sistem. Pada gambar di atas, AliasBuff mewakili MDL yang menjelaskan alamat yang dipetakan dua kali lipat.

  6. Driver menggunakan rentang alamat virtual ruang sistem dari MDL yang dipetakan ganda (AliasBuff) untuk membaca data ke dalam memori.

Ketika driver menyelesaikan IRP dengan memanggil IoCompleteRequest, manajer I/O atau sistem file merilis rentang ruang sistem MDL yang dipetakan ganda jika driver bernama MmGetSystemAddressForMdlSafe. Manajer I/O atau sistem file membuka kunci halaman yang dijelaskan dalam MDL, dan membuang MDL dan IRP atas nama driver. Untuk performa yang lebih baik, driver harus menghindari pemetaan alamat fisik MDL secara bergantian ke ruang sistem, seperti yang dijelaskan pada langkah 3, kecuali mereka harus menggunakan alamat virtual. Melakukannya menggunakan entri tabel halaman sistem yang tidak perlu dan dapat mengurangi performa dan skalabilitas driver. Selain itu, sistem mungkin crash jika kehabisan entri tabel halaman, karena sebagian besar driver yang lebih lama tidak dapat menangani situasi ini.

Buffer utas pengguna saat ini dan utas itu sendiri dijamin akan menjadi penghuni dalam memori fisik hanya saat utas tersebut terkini. Untuk utas yang ditampilkan pada gambar sebelumnya, konten buffer penggunanya dapat di-page out ke penyimpanan sekunder saat utas proses lain dijalankan. Ketika utas proses lain dijalankan, memori fisik sistem untuk buffer utas yang meminta dapat ditimpa kecuali manajer memori telah mengunci dan mempertahankan halaman fisik yang sesuai yang berisi buffer utas asli.

Namun, alamat virtual utas asli untuk buffernya tidak tetap terlihat saat utas lain saat ini, bahkan jika manajer memori mempertahankan halaman fisik buffer. Akibatnya, driver tidak dapat menggunakan alamat virtual yang dikembalikan oleh MmGetMdlVirtualAddress untuk mengakses memori. Penelepon rutin ini harus meneruskan hasilnya ke MapTransfer (bersama dengan penunjuk MdlAddress IRP) untuk mentransfer data menggunakan sistem berbasis paket atau DMA master bus.