【问题标题】:Designing a boot loader for simple Z80 system via UART, Where To Load the Program通过 UART 为简单的 Z80 系统设计引导加载程序,加载程序的位置
【发布时间】:2012-10-06 02:38:50
【问题描述】:

我已经开始为我的 z80 系统编写引导加载程序。 到目前为止,程序可以通过串口接受十六进制并将其加载到内存中的某个位置。

我遇到的问题是引导加载程序位于内存的开头并使用中断, 如何在不覆盖引导加载程序的情况下加载新程序?

(加载的程序也可能想要使用中断)

【问题讨论】:

  • 你需要决定你可以加载什么。您可以禁止加载到低内存,定义“加载区域的开始”,并且加载的程序必须在启动时初始化中断向量吗?或者您的加载程序可以使用中断并将任何寻址到低内存的加载数据重新定位到特殊区域。在程序启动之前,禁用int并将特殊区域复制到low mem。

标签: c assembly embedded bootloader z80


【解决方案1】:

最好和最广泛使用的方法是将您的应用拆分为一个永不更新的稳定引导加载程序,以及您可以不时替换的应用。

AFAIK,在 Z80 中只有中断向量,不支持在 CPU 本身中替换它们。你需要在你的硬件中有一些东西来替换你的内存块。

否则,您需要具有引导加载程序在下载期间不使用应用程序部分中的任何内容的功能,并阻止任何可以调用应用程序中任何内容的中断。

【讨论】:

  • 是的,我想我有一个解决方案,将主引导加载程序代码放在内存末尾。使用中断并将代码临时存储在内存中,然后要接收整个程序,禁用中断并将临时存储的代码移动到 0000H 并复位 PC。我不认为这是最有效的方法,但至少是一个开始。
  • 我 1983 年的 Z80 CP/M 系统在引导 EPROM 和覆盖整个 64KB 地址空间的动态 RAM 之间切换第一个 4KB 块。 IIRC 它从 EPROM 启动并在 4KB 之外的第一个指令访问时切换到 RAM。
  • 是的,但是指向 0038H 和 0066H (NMI) 的中断呢?如果程序是 ROM,则无法访问这里
【解决方案2】:

W.r.t.位置,您可以将引导加载程序放在地址空间的顶部,并在地址空间的开头加载程序。

您还可以在协议中包含程序的位置和大小,以便引导加载程序能够检查这对值是否与引导加载程序的位置和大小兼容(IOW,程序是否会覆盖引导加载程序如果已加载)。

另一种选择是在程序中包含重定位信息,并在引导加载程序中包含一个简单的重定位器。这样,如果有足够的可用内存,您就可以在任何位置加载程序。这是许多操作系统在加载程序时所做的。

至于中断,我认为没有问题。谁或什么不允许程序使用中断?还是您希望引导加载程序说常驻并继续在后台执行某些操作或能够从程序返回到它?如果您不需要任何这些,只需让程序使用中断(您可能甚至不需要做任何事情来允许它)。

OTOH,如果您确实希望引导加载程序保持正常运行,您可以通过维护一个额外的中断向量表来引入一个额外的间接层。主 ISR 将从该中断向量表中提取辅助 ISR 并跳转到那里。然后,您的引导加载程序和程序需要执行此操作才能添加新 ISR 或覆盖现有 ISR:

  1. 禁用中断
  2. 从附加中断向量表中获取旧的 ISR 地址
  3. 将新的 ISR 地址放入表中
  4. 启用中断

删除 ISR 很明显,与上述类似。

然后新的 ISR 可以:

  1. 在工作之前调用旧的 ISR(地址在上面的步骤 2 中保留)
  2. 完成工作后调用旧 ISR
  3. 只做它的工作而不调用旧的 ISR

您需要要求程序和引导加载程序使用此表并在不再需要在其中包含自己的 ISR 时恢复它。

如果您通过在新 ISR 之前/之后执行旧 ISR 来链接 ISR,我不知道您可能需要解决哪些问题。但在某些系统中,这是一种可能的设计。许多 x86 PC 程序和驱动程序都是在 MSDOS 中实现的。

【讨论】:

  • 是的,感谢第一个提示,我肯定会进行检查,以便在程序太大时引导加载程序可以返回,因为它可能只有 16kB。我在想如果我想返回引导加载程序,我可以在程序结束时发出一个返回调用,然后引导加载程序可以将这些位置的中断代码重写到适当的位置(将只是一个禁用中断和跳跃)
猜你喜欢
  • 2014-08-22
  • 1970-01-01
  • 1970-01-01
  • 2014-01-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-03-25
相关资源
最近更新 更多