驱动程序如何导致 BSOD?

驱动程序如何导致 BSOD?

驱动程序如何导致 BSOD?最好能举一些实际生活中的例子。我知道一些基本的东西,比如当操作系统遇到 Divide-Fault 之类的严重错误时就会发生这种情况。我希望知道的是遇到上述错误时与内核内存或内核行为相关的更多技术细节。

答案1

考虑一下,当操作系统遇到此类错误时,它的正常做法是终止有问题的进程。

问题是,如果发生错误该怎么办在内核边界内?您不能简单地终止内核,因为即使可能,也会立即导致系统崩溃,导致操作系统无法报告出了什么问题、无法重新启动(例如,在没有独立于内核的内核看门狗的情况下)、无法存储诊断数据或任何在操作系统崩溃时被认为有用的其他东西。

因此,操作系统只能退而求其次:它首先显示并可能存储诊断信息,然后进入某种状态,其中控制权永远不会从内核的特定部分移出。实际上,系统随后被冻结,因为在系统重新启动之前不会执行任何其他操作。内核可以执行类似HLT操作说明,进入无限循环,禁用输入中断,触发系统重启,或者做任何其他适当的事情。

根据操作系统的不同,不同的情况可能会触发内核崩溃。一个可能的例子是在关闭中断的情况下执行时发生页面错误;另一个例子是内核调用未通过先决条件或健全性检查(这就是IRQL_NOT_LESS_OR_EQUAL是关于什么的,例如)。有关在 Windows 中可能触发 BSOD 的事物列表,请参阅例如Windows 2000 上的 STOP 错误代码列表在 MSDN 上。

在这种情况下,考虑内核边界内运行的程序之间的差异也很重要,因此有可能导致致命的系统崩溃,而不是简单地崩溃单个进程。内核之外运行的任何程序(或更准确地说,在英特尔上,在环 0 之外)都可能受到内核的限制,这就是为什么进程间内存保护和交换甚至是可能或实用的一个重要原因(每个进程都设置为只能访问自己的内存,由 CPU 强制执行,任何违规都会导致页面错误,由内核处理,并可能导致请求的页面从交换中重新加载,或者内核抛出内存保护错误并终止有问题的进程)。在单内核操作系统中,许多东西都在内核边界内运行——这样做通常是为了提高性能,因为上下文切换进出内核的成本特别高,但它给驱动程序程序员带来了巨大的负担,因为任何错误(在不合适的时间,或者永远,取决于错误类型)在内核模式下执行时都是系统关键的。相比之下,在微内核操作系统中,只有最少的代码在 ring 0(或同等级别)中运行——通常,这仅限于内存管理等事情,进程调度还有一些其他需要对整个系统进行该级别访问的事情——其余部分在用户模式下运行并通过明确定义的接口与内核通信。这样做允许使用与用户空间进程相同的访问控制来保护与内核相关的代码,并且使用正确定义的接口(例如,任何驱动程序都必须能够在正在运行的系统上加载时重新初始化相应的硬件,即使驱动程序之前已加载并且硬件设备处于潜在的未知状态),这也可以工作。缺点是所有这些进出内核的上下文切换都会降低系统性能,据称这也是为什么在 Windows NT 4.0(与 NT 3.x 相比)中,Microsoft 将设备驱动程序移至 ring 0 而不是 ring 3 中执行的一个重要原因。

答案2

与内核中的用户模式不同,所有驱动程序都共享相同的内存。如果驱动程序在这里做错了事(访问无效的内存位置),它们会影响其他组件。内核会检测到它们,并漏洞nt!KeBugCheckEx)系统保护系统和数据不被破坏。

*nix 类系统以内核恐慌

答案3

导致 BSOD 的原因有很多种。我通常在更新驱动程序时遇到这些问题,如果更新错误,有时会与旧的驱动程序文件发生冲突。其他时候,我注意到更新过程中出现损坏。我相信,但不要引用我的话,它也可能取决于其他硬件和驱动程序。例如,可能是旧硬件与新硬件以及不再支持旧硬件的驱动程序更新。

相关内容