Jam*_*han 14
BSOD 只是 Windows 所谓的错误检查的视觉错误消息。错误检查(或者,正如 *nix 所称的,内核恐慌)发生是因为操作系统无法“处理它”。
例如 - 一条指令试图从一个不存在的地址读取。或者在无法解决页面错误的情况下引发尝试读取内存的页面错误。
您究竟会向需要读取操作结果的代码提供哪些数据,以便它可以“继续”?
这些错误的发生通常是因为有问题的指令访问了错误的地址。重试时你会把它改成什么地址?你怎么知道它应该是什么?
当然,写入内存时也会出现这些错误。好吧,你不能不写就继续。但是代码并不仅仅因为感觉而写入内存。其他一些代码稍后将需要应该写入内存的信息,然后它会遇到与“继续执行”相同的问题。稍后会详细介绍。
一种可能的解决方法是更好地隔离组件。假设这个错误发生在你的声卡驱动程序中——对于我们在机器上做的许多事情来说,这是一个相当不重要的设备。您可能会说“让我们报告错误并停止使用声卡,直到下次重新启动,也许用户会更新驱动程序或更换声卡。”
问题是内核模式下的所有代码和数据都是同等信任的。在内核模式是指所有在内核模式下的代码和数据,由证据刚看到,引发的错误不值得信赖的。在引发操作系统注意到的错误之前,没有办法知道它没有造成更微妙的损害。(这导致口头禅“受害者并不总是罪魁祸首。”发现引发错误的代码之所以这样做是很常见的,因为内核模式中的某些其他组件损坏了内存内容。通常很难找到其他组件.)
错误检查方法的另一个方面:一旦发现这些错误(通常是因为它们导致无法处理的异常),就会“报告”(通过崩溃)。在一些错误检查原因中,实际上可以做一些看似合理的事情并继续。然而,这掩盖了错误或发生的事实。内核模式中的错误最终可能会导致“我真的无法继续”的情况。
在上面给出的内存写入失败示例中,是的,您可以说“所以不要进行写入”。但最终有些东西将需要未写入的数据,然后该代码就会失败。
在内核模式中出现错误的第一个迹象时崩溃,即使是一种可恢复的错误,也会让您获得尽可能接近问题的内存转储。长期的经验(操作系统可以追溯到 NT 首次发布之前的几十年;BSD 和 VMS 都可以追溯到 70 年代末/ 80 年代初)表明,即使您确实设法修复并继续进行,系统也会崩溃以后发现问题就会困难得多。
问题不太可能是您“破坏了良好的硬件”。只是没有任何方法可以耸耸肩并继续前进,这可能会带来快乐的结果。这就像到达了一个岔路口,但您的 GPS 告诉您直行,一条不存在的路径。没有办法遵循那个方向,也没有关于采取哪个叉子的提示。您可以随机选择一条路径……这不太可能到达您想去的地方。(或稳定的操作系统。)
但是,假设,如果每个驱动程序都在其自己的某种沙箱或内存分区中,那么我们可以假设它在该分区之外没有造成任何损坏,对吧?
其实,是!现在的问题是您没有描述 x86/x64 架构或操作系统通常使用它的方式。
但是,嗯……如果您可以在自己的进程中运行每个驱动程序会怎样?进程彼此隔离,对吗?如果其中一个犯了这样的错误,我们可以关闭该进程,而操作系统的其余部分继续运行。
事实证明,对于速度不太重要的设备,您可以!这就是 Windows 的“用户模式驱动程序框架”。
但是调用这些用户模式驱动程序涉及非常长的代码路径,其中包含许多环转换和进程到进程的上下文切换。(好吧,与调用内核模式驱动程序相比,时间长了。)您不会希望将 UMDF 用于您的磁盘或视频卡。你可以把你的 HID 驱动程序移到那里,但 HID 驱动程序几乎解决了问题。
尽管如此,还是有一些设备可以容忍延迟(尤其是在当今快速的 CPU 上),并且您将在未来看到越来越多的驱动程序转向用户模式。对于真正需要 USB 3 速度的设备,UMDF 驱动程序可能会太慢,但可以在 USB 1.1 上正常工作的设备(如串行端口适配器)可能不介意使用 UMDF 功能驱动程序。随着 Win 8.1 附带的 UMDF 体系结构的改进,您将看到越来越多的设备使用 UMDF。
至少处理所有 USB 设备的 USB 主机控制器接口的“总线驱动程序”的一部分仍处于内核模式,因为它必须接触 I/O 端口和寄存器,而这些东西只能在内核模式下访问;改变这将把所有的安全都抛在脑后。
这导致了这一点:对于核心操作系统和内核模式驱动程序,他们将不得不保持在内核模式下才能做一些他们必须做的事情——使用特权指令、响应中断和可处理的异常,访问 I/O 硬件...... x86/x64 指令集参考的“系统编程”部分中的所有内容。对于内核模式代码中无法处理的异常,恐怕“继续下去”的答案仍然是“到底要做什么?”
抱歉,坦率地说,在内核模式下尝试未定义的操作只会导致错误消息和“处理它”,这是误解了内核模式的含义。你不能只是编造一个结果,并有任何理由认为后续代码会对此感到满意。
| 归档时间: |
|
| 查看次数: |
127 次 |
| 最近记录: |