硬件监控计时器

概览

硬件监控计时器 (WDT) 是一种特殊的硬件,负责在发生硬系统级锁定时重置系统。它们经常出现在系统芯片 (SoC) 设计中,尤其是在面向小型嵌入式系统应用的 SoC 中。它们可能是系统设计的一个重要方面,它们可能会触发系统重新启动,而系统完全锁定,已无法管理任务关键任务(例如主动热管理),之后系统遭受不可修复的损害。此外,它们无需用户干预即可自动重置硬锁定系统,从而帮助缓解嵌入式系统中糟糕的用户体验。没有人愿意处理锁定的设备,但如果发生最坏的情况,最好是让系统自动重置,而不是强制用户不得不让用户受到无响应系统的影响,直到他们决定重启设备,然后必须实际拔下设备才能恢复设备。

监控计时器(简称“监控计时器”或“WDT”)通常配置为以特定速率进行计数,直至达到阈值计数。如果计数器在软件重置之前达到阈值,则 WDT 会自动在不正常的情况下重新启动系统。从软件重置 WDT 的行为通常称为“抚摸”监控计时器。系统中硬件监控计时器的持续时间往往会很长(一个或多个秒),因为这种机制绝对是最糟糕的故障安全机制。系统在监控计时器触发之前应已完全锁定。

Zircon 中的用法

Zircon 中的 WDT(如果有)会用于保护系统的绝对最低级别。启用后,它名义上会受内核级计时器的 1/4 到 1/2 之间的某个时间循环执行,这意味着它在独立于线程的硬 IRQ 上下文中被触发。照顾监控计时器不受线程权重、截止时间或任何其他调度器行为的约束。为了让硬件监控计时器触发并重新启动系统,系统需要锁定到无法对计时器 IRQ 进行处理的程度。

如上所述,监控计时器是硬件专用实体。无论是否存在,它能够执行的操作,具体而言,如何操作(如果存在)在 x64 或 ARM64 等架构中并不常见。考虑到“pet”操作在 Zircon 内核的绝对最低级别的位置,由内核来“抚摸狗狗”,而不是由任何硬件特有的用户模式驱动程序。

因此,引导加载程序应正确配置监控计时器,并通过 ZBI 向内核传达以下重要详细信息:是否存在 WDT、是否启用 WDT、必须多久关联一次以及如何管理、启用或停用 WDT。只有当引导加载程序告知运行 zircon 的系统有 WDT 以及如何操作时,该系统才“具有”WDT。虽然引导加载程序在启用并启用时,必须告知内核如何“轻触”监控计时器,但可能不会告知内核如何停用监控计时器。这可能是由于系统设计决策造成的,也可能是因为无法从内核停用 WDT。

通常,硬件 WDT 会在将控制权交给内核之前由引导加载程序配置和启用。这样一来,如果内核在启动期间完全锁定,WDT 就会重置系统。在栅栏的另一端,内核会尝试在启动序列中尽早识别 WDT。之后,一旦启动进程进入到可以设置计时器的程度,它就会渐渐形成一种定期抚摸狗狗的模式。

在开发期间控制监控计时器的方法

绝大多数开发者都不需要对监控计时器计时器执行任何操作,甚至不需要意识到它的存在。如果事件在正常操作期间触发,表示出现了严重错误。但在某些情况下,开发者在调查 bug 或其他性能问题的过程中,可能需要长时间推迟硬中断请求 (IRQ)。在这些情况下,最好了解一下存在哪些选项来控制监控计时器,以及如何在不恰当的时间不被任何因素控制。

使用内核 shell 扩展

如果您可以访问内核 shell,并且系统足够稳定,可以启动到可以访问内核 shell 的点,则可以使用 shell 扩展来操控 WDT。运行 k wdt help 可查看可用命令的列表。运行 k wdt status 以查看内核是否知道任何硬件 WDT,如果知道,则了解 WDT 是否启用、标称宠物期是多久,以及计时器是多久之前上次触发时间的。如果需要,您可以运行 k wdt disable 来停用监控计时器。只有当引导加载程序已告知内核如何停用 WDT 时,您才能停用 WDT。

使用内核命令行

您可以传递内核命令行参数来控制监控计时器。您可以发送 kernel.force-watchdog-disabled=true,以告知内核在启动期间尽早强制停用监控计时器。如果问题导致监控计时器在它到达内核 shell 易于访问的程度之前触发,这会非常有用。不过,只有当引导加载程序已告知内核如何停用监控计时器时,才能选择此选项。