В настоящее время я играю с драйвером ядра Windows, чтобы лучше понять внутренности Windows. Как игрушечный проект, я написал драйвер ядра, роль которого заключается в распределении памяти, которая может быть разделена между процессами.
Приложение может попросить драйвер создать буфер памяти любого размера. Затем драйвер создает этот буфер в KernelSpace с помощью MmAllocatePagesForMdl, а затем сопоставить этот буфер в режиме пользователя с MmMapLockedPagesSpecifyCache. Полученный указатель возвращается обратно приложению, которое может напрямую писать в него, как в любом обычном буфере. Затем другое приложение может попросить драйвер обратиться к этой памяти, чтобы прочитать ее (или даже записать); водитель просто должен позвонить MmMapLockedPagesSpecifyCache на уже существующий буфер в контексте нового процесса. Пока все работает очень хорошо.
После этого небольшого успеха я хотел создать больший буфер в пространстве ядра, и я ударил стену. MDL может управлять только до «4Go — PAGE_SIZE».
Моей первой идеей было создать несколько леев, используя MmAllocatePagesForMdl пока я не выполню запрос размера, соедините MDL, используя следующий указатель, а затем вернуть указатель на пространство пользователя, используя MmMapLockedPagesSpecifyCache. Но MmMapLockedPagesSpecifyCache не работает с цепочечным MDL, он только отображает в пользовательском пространстве первый MDL.
До сих пор я не нашел способа вернуть более 4Go непрерывной виртуальной памяти из пространства ядра в пользовательское пространство. Выделение в Пространстве ядра не является проблемой, поскольку я использую память с постраничной подкачкой, поэтому физическая память не должна быть непрерывной, но я не могу найти, как отобразить их в непрерывной виртуальной памяти для использования в Пространстве пользователя.
Так я жадный и это невозможно? Или я что-то упустил, чтобы сделать это?
Для справки: это только 64-битный драйвер и 64-битные приложения, поэтому здесь нет 32-битных ограничений.
Так что после просмотра везде невозможно использовать MDL. Чтобы иметь больше 4Go, я должен создать раздел в моем драйвере. Это эквивалент CreateFileMapping в пользовательском режиме. Но я не хотел полагаться на SharedMemory, так как у меня была некоторая блокировка во время выделения / отображения памяти.
А потом Алекс дал мне замечательный совет форум osr чтобы решить мою начальную проблему; используйте CreateFileMapping с опцией SEC_LARGE_PAGES. Блокировка памяти исчезла, и я так же быстр, как и с моим драйвером, без всех проблем, которые могут быть вызваны таким развитием событий.
Других решений пока нет …