Nuta
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować się zalogować lub zmienić katalog.
Dostęp do tej strony wymaga autoryzacji. Możesz spróbować zmienić katalogi.
Sterownik obsługujący interaktywne lub powolne urządzenie, lub taki, który zwykle przesyła stosunkowo małe ilości danych naraz, powinien używać metody transferu buforowanego I/O. Użycie buforowanych operacji we/wy w przypadku małych, interaktywnych transferów poprawia ogólne użycie pamięci fizycznej, ponieważ menedżer pamięci nie musi blokować pełnej strony fizycznej dla każdego transferu, podobnie jak w przypadku sterowników, które żądają bezpośredniego we/wy. Ogólnie rzecz biorąc, wideo, klawiatura, mysz, szeregowe i równoległe sterowniki żądają buforowanych operacji we/wy.
Menedżer wejścia/wyjścia określa, że operacja I/O używa buforowanego wejścia/wyjścia w następujący sposób:
W przypadku żądań IRP_MJ_READ i IRP_MJ_WRITE DO_BUFFERED_IO jest ustawiana w elemencie Flags struktury DEVICE_OBJECT . Aby uzyskać więcej informacji, zobacz Inicjowanie obiektu urządzenia.
W przypadku żądań IRP_MJ_DEVICE_CONTROL i IRP_MJ_INTERNAL_DEVICE_CONTROL wartość kodu IOCTL zawiera METHOD_BUFFERED jako wartość TransferType w wartości IOCTL. Aby uzyskać więcej informacji, zobacz Definiowanie kodów kontrolnych I/O.
Na poniższej ilustracji pokazano, jak menedżer we/wy konfiguruje żądanie IRP_MJ_READ dla operacji transferu, która używa buforowanych operacji we/wy.
Na rysunku przedstawiono przegląd sposobu używania wskaźnika SystemBuffer w IRP do przesyłania danych dla żądania odczytu, gdy sterownik wykonuje operację OR na flagach obiektu urządzenia z DO_BUFFERED_IO.
Pewien zakres wirtualnych adresów przestrzeni użytkownika reprezentuje bufor bieżącego wątku, a jego zawartość może być przechowywana w pewnym zakresie adresów fizycznych opartych na stronach (ciemne cieniowanie na poprzedniej ilustracji).
Menedżer we/wy obsługuje żądanie odczytu bieżącego wątku, w ramach którego wątek przekazuje zakres adresów wirtualnych przestrzeni użytkownika reprezentujących bufor.
Menedżer we/wy sprawdza bufor dostarczony przez użytkownika pod kątem dostępności i wywołuje ExAllocatePoolWithTag, aby utworzyć niestronicowany bufor przestrzeni systemowej (SystemBuffer) o rozmiarze odpowiadającym buforowi dostarczonemu przez użytkownika.
Menedżer I/O zapewnia dostęp do nowo przydzielonego SystemBuffer w IRP, który wysyła do sterownika.
Jeśli na rysunku pokazano żądanie zapisu, menedżer we/wy skopiuje dane z buforu użytkownika do buforu systemu przed wysłaniem IRP do sterownika.
W przypadku żądania odczytu pokazanego na poprzedniej ilustracji sterownik odczytuje dane z urządzenia do buforu przestrzeni systemowej. Pamięć dla tego buforu jest niestronicowana, a sterownik może bezpiecznie uzyskać dostęp do buforu bez konieczności wcześniejszego zablokowania. Gdy żądanie odczytu zostało spełnione, sterownik wywołuje funkcję IoCompleteRequest w odniesieniu do IRP.
Gdy oryginalny wątek jest ponownie aktywny, menedżer we/wy kopiuje dane odczytywane z bufora systemowego do bufora użytkownika. Wywołuje również funkcję ExFreePool , aby zwolnić bufor systemu.
Po utworzeniu buforu przestrzeni systemowej dla sterownika przez menedżera we/wy, wątek trybu użytkownika może zostać zamieniony, a jego pamięć fizyczna może zostać ponownie użyta przez inny wątek, prawdopodobnie przez wątek należący do innego procesu. Jednak zakres adresów wirtualnych przestrzeni systemowej podany w IRP pozostaje prawidłowy, dopóki sterownik nie wywoła IoCompleteRequest z IRP.
Sterowniki, które przesyłają duże ilości danych w danym momencie, w szczególności sterowniki, które wykonują transfery wielostronicowe, nie powinny próbować używać buforowanych operacji we/wy. W trakcie działania systemu pula niestronicowana może zostać rozdrobniona, co uniemożliwia menedżerowi we/wy przydzielenie dużych, ciągłych buforów przestrzeni systemowej do wysyłania w IRP dla takiego sterownika.
Zazwyczaj sterownik używa buforowanych operacji we/wy dla niektórych typów IRP, takich jak żądania IRP_MJ_DEVICE_CONTROL, nawet jeśli używa również bezpośrednich operacji we/wy. Sterowniki korzystające z bezpośrednich operacji we/wy zazwyczaj robią to tylko dla żądań IRP_MJ_READ i IRP_MJ_WRITE, a także dla ewentualnych żądań IRP_MJ_INTERNAL_DEVICE_CONTROL zdefiniowanych przez sterownik, które wymagają dużych transferów danych.
Każde żądanie IRP_MJ_DEVICE_CONTROL i IRP_MJ_INTERNAL_DEVICE_CONTROL zawiera kod sterowania wejścia/wyjścia. Jeśli kod kontrolny we/wy wskazuje, że IRP musi być obsługiwany z użyciem buforowanego we/wy, menedżer we/wy używa pojedynczego bufora systemowego do reprezentowania buforów wejściowych i wyjściowych aplikacji użytkownika. Sterownik obsługujący taki kod kontrolny we/wy musi odczytywać dane wejściowe (jeśli istnieją) z buforu, a następnie dostarczać dane wyjściowe (jeśli istnieją), zastępując dane wejściowe. Aby uzyskać więcej informacji, zobacz Definiowanie kodów kontrolnych I/O.