NX 池兼容性问题

在 Windows 8 的驱动程序二进制文件中使用 NX 非分页池时,如果在早期版本的 Windows 上运行这些二进制文件,则会出现兼容性问题。

Windows 8 是支持 NX 非分页池的第一个 Windows 版本。 但是,许多现有的内核模式驱动程序二进制文件适用于在 x86、x64 和 IA64 处理器体系结构上运行的 Windows 7 和早期版本的 Windows。 若要分配非分页内存,这些驱动程序使用可执行的非分页池,而不是 NX 非分页池。 为了向后兼容,在 Windows 7 和某些早期版本的 Windows 上运行的内核模式驱动程序二进制文件以及从非分页池分配内存的内核模式驱动程序二进制文件将在 Windows 8 上运行,而无需修改。 但是,这些驱动程序不利用 Windows 8 中 NX 非分页池的可用性。

在 Windows 8 上运行现有驱动程序二进制文件

为 Windows 7(或可能更早版本的 Windows)构建并使用 NonPagedPool 池类型的驱动程序二进制文件,在 Windows 8 上运行没有受到阻止。 为了启用向后兼容性,NonPagedPoolExecute 常量定义为在POOL_TYPE枚举中具有与 NonPagedPool 常量相同的值。 因此,在运行此驱动程序的任何 Windows 版本中,驱动程序从非分页池分配的内存始终是可执行的。

Windows 8 是支持 Arm 体系结构的第一个 Windows 版本。 因此,没有为较早版本的 Windows 构建并且需要向后兼容的 Arm 驱动程序二进制文件。 相反,在 Arm 上为 Windows 编写的所有驱动程序应指定 NonPagedPoolNx ,而不是非分页池分配中的 NonPagedPoolExecute ,除非它们显式需要可执行内存。

如果将驱动程序从 x86、x64 或 IA64 移植到 Arm,则驱动程序生成过程中会自动应用 POOL_NX_OPTIN_AUTO 选择加入机制。 默认情况下,此选择加入机制使用预处理器将 NonPagedPool 常量名称的所有实例替换为 NonPagedPoolNx。 如有必要,可以使用POOL_NX_OPTOUT选择退出机制,以覆盖此选择加入机制,并在每个文件的基础上进行操作。

其他兼容性问题

从 Windows 8 开始,支持 NonPagedPoolNx 池类型。 请勿在较早版本的 Windows 驱动程序中使用此池类型。 当驱动程序请求使用 NonPagedPoolNx 池类型的分配时,这些早期版本的 Windows 中的池分配器无法正常运行。

在 Windows 8 之前的 Windows 版本中, NonPagedPoolExecute 池类型可以自由用作 NonPagedPool 池类型的替代。 POOL_TYPE枚举定义了NonPagedPoolNonPagedPoolExecute具有相同的值。

NX 池类型移植指南

将驱动程序代码从早期版本的 Windows 移植到 Windows 8 或更高版本时,可通过多种方式添加对 NonPagedPoolNxNonPagedPoolExecute 池类型的支持。 从以下列表中,选择最符合要求的方法:

  • 如果驱动程序不打算在早于 Windows 8 的 Windows 版本上运行,请将 NonPagedPool 的大多数或全部实例替换为 NonPagedPoolNx。 开发人员应该很少将 NonPagedPool 的实例替换为 NonPagedPoolExecute。

  • 如果驱动程序源代码面向 Windows 8 及更早版本的 Windows,并且你为每个版本交付了不同的驱动程序二进制文件,请使用 POOL_NX_OPTIN_AUTO 选择加入机制。 此方法不需要替换驱动程序源中的 NonPagedPool 实例。 有关详细信息,请参阅 NX 池 Opt-In 机制

  • 如果你的驱动程序源代码同时面向 Windows 8 和早期版本的 Windows,并且你提供一个驱动程序二进制文件以在所有受支持的版本上运行,请使用POOL_NX_OPTIN选择加入机制。 此方法不需要替换驱动程序源中的 NonPagedPool 实例。 有关详细信息,请参阅 NX 池 Opt-In 机制

通过使用这三种方法之一,大多数驱动程序都可以快速并且轻松地移植。

避免仅仅将驱动程序代码中的NonPagedPool所有实例替换为NonPagedPoolExecute。 仅将 NonPagedPoolExecute 池类型用于必须执行的池分配(例如,运行由 JIT 编译器生成的代码)。