Ескертпе
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Жүйеге кіруді немесе каталогтарды өзгертуді байқап көруге болады.
Бұл бетке кіру үшін қатынас шегін айқындау қажет. Каталогтарды өзгертуді байқап көруге болады.
Это важно
DDIs ExAllocatePool, изложенные в этом разделе, были признаны устаревшими в Windows 10 версии 2004 и были заменены ExAllocatePool2 и ExAllocatePool3. Дополнительные сведения см. в разделе Обновление устаревших вызовов ExAllocatePool к ExAllocatePool2 и ExAllocatePool3.
Драйверы могут использовать выделенное системой пространство в расширениях устройств в качестве глобальных областей хранения для сведений, относящихся к устройству. Драйверы могут использовать только стек ядра для передачи небольших объемов данных во внутренние подпрограммы. Некоторые драйверы должны выделять дополнительные, большие объемы системной памяти, как правило, для буферов ввода-вывода.
Чтобы выделить пространство буфера ввода-вывода, лучше всего использовать следующие подпрограммы выделения памяти: MmAllocateNonCachedMemory, MmAllocateContiguousMemorySpecifyCache, AllocateCommonBuffer (если устройство драйвера использует шину-мастер DMA или режим автоматической инициализации системного контроллера DMA), или ExAllocatePoolWithTag.
Непакетный пул обычно фрагментируется по мере работы системы, поэтому процедура DriverEntry драйвера должна вызывать эти процедуры для настройки любых долговременных буферов ввода-вывода, необходимых драйверу. Каждая из этих подпрограмм, за исключением ExAllocatePoolWithTag, выделяет память, выравненную на границу, специфичную для процессора (определяется размером строки кэша данных процессора), чтобы обеспечить максимальную производительность.
Драйверы должны выделять буферы ввода-вывода как можно более экономически, так как непагаченная память пула является ограниченным системным ресурсом. Как правило, драйвер не должен многократно вызывать эти вспомогательные процедуры для запроса выделения памяти менее PAGE_SIZE, так как каждое выделение менее PAGE_SIZE содержит заголовок пула, используемый для внутреннего управления выделением.
Советы по выделению буферного пространства драйвера экономически
Чтобы экономически выделить память буфера ввода-вывода, следует учитывать следующее:
Каждый вызов MmAllocateNonCachedMemory или MmAllocateContiguousMemorySpecifyCache всегда возвращает количество памяти, равное целому числу страниц системы, в некэшированной области системного пространства, независимо от размера запрошенного выделения. Таким образом, запросы на менее чем страницу округляются до полной страницы, и все оставшиеся байты на странице не используются, они недоступны драйвером, который вызвал функцию, и не могут использоваться другим кодом в режиме ядра.
Каждый вызов в AllocateCommonBuffer использует по крайней мере один регистр карты объектов адаптера, который сопоставляет по крайней мере один байт и по крайней мере одну страницу. Дополнительные сведения о регистрах карт и использовании общих буферов см. в разделе "Объекты адаптера" и "DMA".
Выделение памяти с помощью ExAllocatePoolWithTag
Драйверы также могут вызывать ExAllocatePoolWithTag, указав одно из следующих системных POOL_TYPE значений для параметра PoolType :
PoolType = NonPagedPool для любых объектов или ресурсов, которые не хранятся в расширении устройства или расширении контроллера, к которым драйвер может получить доступ при работе на уровне IRQL > APC_LEVEL.
Для этого значения PoolType функция ExAllocatePoolWithTag выделяет запрашиваемый объем памяти, если указанное NumberOfBytes меньше или равно PAGE_SIZE. В противном случае все оставшиеся байты на последней выделенной странице не используются: недоступны вызывающей стороне и непригодны для другого кода в режиме ядра.
Например, в x86 запрос на выделение 5 килобайт (КБ) возвращает две страницы размером 4 КБ. Последние 3 КБ второй страницы недоступны вызывающему или другому вызывающему объекту. Чтобы избежать потери недоступного пула, драйвер должен эффективно выделять несколько страниц. В этом случае драйвер может выделить два выделения, один для PAGE_SIZE и другой для 1 КБ, чтобы выделить в общей сложности 5 КБ.
Заметка Начиная с Windows Vista система автоматически добавляет дополнительную память, поэтому два выделения не нужны.
PoolType = PagedPool для памяти, которая всегда доступна на уровне IRQL <= APC_LEVEL и не используется в пути записи файловой системы.
ExAllocatePoolWithTag возвращает указатель NULL , если он не может выделить запрошенное число байтов. Драйверы всегда должны проверять возвращаемый указатель. Если значение равно NULL, подпрограмма DriverEntry (или любая другая подпрограмма драйвера, возвращающая значения NTSTATUS), должна возвращать STATUS_INSUFFICIENT_RESOURCES или обрабатывать условие ошибки, если это возможно.