【问题标题】:Linux kernel detecting the pre-boot environment for watchdogLinux内核检测看门狗的预引导环境
【发布时间】:2015-04-19 18:51:31
【问题描述】:

因此,我正在为嵌入式 Linux 系统进行开发,但我们在使用外部看门狗芯片时遇到了一些问题,需要在启动过程的早期进行馈送。

更具体地说,据我们所知,当内核在预引导环境中解压缩其映像时,这个外部看门狗会导致重置。在开始需要喂食之前没有足够的停机时间,这可能应该在硬件中分类,因为它是外部的,但需要内部软件解决方案。

我们的一位开发人员的解决方案是将一些额外的代码放入...

int zlib_inflate(z_streamp strm, int flush)lib/zlib_inflate/inflate.c 内核代码中

这个新代码在解压过程中周期性地切换看门狗引脚。

现在除了我觉得这有点肮脏的黑客之外。它确实有效,它在我脑海中提出了一个有趣的观点。因为这个库也在启动后使用。那么有没有一种很好的方法来检测您是否处于预启动环境中?所以它只能执行这种切换预启动,而不是在以后使用 lib 时。

顺便说一句,我也有兴趣从一开始就避免黑客攻击的任何想法。

【问题讨论】:

  • “因为这个库也是在启动后使用的。” -- 启动解压器不会有它自己的这个库代码的副本吗?否则,您将面临鸡与蛋的局面。
  • 如果您在启动序列中使用 U-Boot,则不要使用 zImage 内核映像,而是使用压缩的 Image 文件.并使用 U-Boot 内置的解压缩器。 u-boot-2014.07/lib/zlib/inflate.c 似乎有执行看门狗重置的钩子。请参阅 Wolfgang Denk 在stackoverflow.com/questions/22322304/image-vs-zimage-vs-uimage/… 中的引用
  • 我确定它有自己编译的二进制副本,但据我所知,它是从同一源编译的。其中有 hack 编码。我们正在使用 u-boot,我会研究一下。谢谢。

标签: linux-kernel embedded-linux u-boot watchdog compression


【解决方案1】:

那么有没有一种很好的方法来检测你是否处于预启动环境中?

您在问一个 XY 问题。
如果你使用U-Boot,X问题的解决方案可以干净利落地解决。
(顺便说一句,而不是“pre-boot”,即在启动之前,您可能的意思是“启动”,即在内核启动之前。)

如果您在引导序列中使用 U-Boot,那么您不必破解任何引导或内核代码。显然,您正在 zImage(或 uImage 中的 zImage)文件中启动自解压压缩内核。 U-Boot 的作者/维护者 Wolfgang Denk 描述了免破解解决方案:

使用普通(未压缩)内核映像要好得多,压缩它 仅使用 gzip,并将其用作 mkimage 的 poayload。这边走 U-Boot 进行解压缩而不是包含另一个 对每个内核映像进行解压缩。

所以不要使用make uImage,而是使用简单的make
压缩 Image 文件,然后使用 U-Boot 包装器使用 mkimage 将其封装(并指定应用的压缩算法,以便 U-Boot 可以使用其内置的在解压器​​中)生成您的 uImage 文件。

当 U-Boot 加载这个 uImage 文件时,包装器会指出它是一个压缩文件。
U-Boot 将执行其内部解压缩器库,该库(在最近的版本中)已经支持看门狗。

【讨论】:

  • 确认了这个答案,并且在我们使用的版本(即 v2012.10)中,u-boot 解压缩是看门狗感知的。谢谢@sawdust。
  • 抱歉,您说得对,我的术语“预启动”可能会造成混淆。我试图表示解压缩图像的时间点,正如您正确所说的那样,从技术上讲,它仍然是“启动”的一部分。尽管内核源代码中的 cmets 似乎将执行解压缩的代码称为“预引导环境”中的代码。
【解决方案2】:

快速而肮脏的解决方案让我一头雾水:

在初始化为 1 的文件中创建一个全局静态变量,只要是 1,就认为是“预启动”。

添加一个 *_initcall(选择适合您需要的。我不确定内核何时解压缩)将其设置为 0。

请参阅内核树中的 include/linux/init.h 以了解 initcall 级别。

【讨论】:

  • 与我们提出的类似。在特定于引导的部分代码中定义了一个全局 int 标志 = 1,在用于内核其余部分的部分代码中定义了相同的 int 标志 = 0。然后将其定义为解压代码中的 extern int 并用它来控制看门狗切换。它的工作原理是链接器仅在链接期间为每个实例找到一个。只是感觉很脏,所以认为可能有更清洁的方法。
【解决方案3】:

请参阅@sawdust 答案,了解如何在不破解内核代码的情况下实现看门狗喂食。

然而,这并没有完全解决如何检测代码正在“预引导环境”中编译的原始问题,因为它在内核源代码中被调用。

内核中的文件,例如...

include/linux/decompress/mm.h

lib/decompress_inflate.c

并且在较小程度上(没有明确评论)......

lib/decompress_unlzo.c

似乎检查 STATIC 定义以设置“预启动环境”差异。比如这段摘自include/linux/decompress/mm.h...

#ifdef STATIC

/* Code active when included from pre-boot environment: */

...

#else /* STATIC */

/* Code active when compiled standalone for use when loading ramdisk: */

...

#endif /* STATIC */

【讨论】:

    【解决方案4】:

    另一个想法是从引导加载程序中禁用看门狗,并在系统完全启动后从用户空间启用它。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-04-09
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-08-06
      • 1970-01-01
      相关资源
      最近更新 更多