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 版本。 因此,对于 Arm,没有为早期版本的 Windows 构建且需要向后兼容性的驱动程序二进制文件。 相反,所有为 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 编译器) 生成的代码。