linux - 为什么我们需要创建一个中断向量表?

标签 linux arm interrupt avr bootloader

我在网上读到一些教程,说中断的分支地址已经硬连线了。
他们为什么我们需要在引导加载程序中创建ivt?

最佳答案

问题是,您希望让不同的硬件检测到事件或异常,或者中断您想调用它们的任何内容。而且您希望有机会基于该事件运行单独的代码。硬件必须以某种方式把控制权交给那些独立的程序。所以对于每个处理器架构都有一个解决方案。通常我们称之为基于历史的中断向量表,但有些人可能称之为异常表,而对于arm(大多数不是所有arm),它真的是一个表吗,因为它不是地址列表,而是实际的指令?
在arm是的情况下,代码执行的地址通常不是硬编码的,但通常中断向量表是地址列表,该表的位置和表中的每个条目是固定地址,但在某种程度上,软件人员用要编码的地址填充该表。这些情况下的硬件检测事件,基于事件从内存中读取的已知位置,该位置包含一个地址,并开始在该地址获取/运行。要执行的硬编码地址最终会出现ARM情况或类似的情况,例如重置为0x0000,预取中止为0x1000,数据中止为0x2000等都没有意义。您希望指令或地址表美观紧凑。除非获得专利,否则您可以为几乎任何体系结构创建一个arm类型的表,每个异常可能超过4个字节,但您仍然可以这样做。或者只做地址的事。
ARM已经切换到Cortex-M中的传统地址,但与传统地址不同的是,有几十到几百个单独的向量(在微控制器中!)每件小事都有一个切入点。原因是,如果你在他们的文档行内或行间阅读,cortex-m的设计是这样的,你不需要将程序集包装在你的c处理器上,对于传统的处理器,中断返回是特殊的,需要特殊的指令,例如,中断的输入通常涉及保存所有寄存器,而该处理器的c调用约定可能没有保存所有寄存器。所以需要一些程序集和/或特定于编译器的指令才能让编译器为您执行此操作。有了Cortex M,你可以有一个正常的,根本不是特殊的C函数,只需把C函数的地址放在正确位置的巨大中断向量表中。
为什么在引导加载程序中。
引导加载程序通常是非易失性代码,flash/rom。
引导加载程序处理重置事件
为了能够引导处理器,您至少需要足够的flash/rom中的ivt来找到重置处理程序。
因此,您通常会在该体系结构的向量表地址及其周围划出一块地址空间,并将非易失性内存放在那里。通常在附近但不是必需的地方,您需要一块地址空间来为重置处理程序放置非易失性内存,否则您无法启动处理器(如果处理器使用表中的地址来查找重置处理程序,这是典型的解决方案)。
由于flash/rom中已经有一个向量表项,所以把其余的放在那里。把整个过程称为引导加载程序。一旦启动,您可能希望向量表是易失性的,这样您就可以让中断指向引导加载程序加载的基于操作系统的处理程序,而不是非易失性的引导加载程序处理程序或空间中的一些硬编码地址。有很多不同的方法可以解决这个问题,一般的方法是将内存控制器切换到指向ram(在启动和运行之后),让引导加载程序处理程序使用某种间接的方式到一些ram位置,除了重置。你实际上是如何实现这一点的,等等各不相同。例如,使用系统中的MMU,可以轻松地将矢量表重新映射到RAM…

关于linux - 为什么我们需要创建一个中断向量表?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21912951/

相关文章:

linux - 将 VxWorks intConnect API 移植到 linux

c++ - c++中的段错误(核心转储)

linux - 在 linux(CentOS)/多处理器设置中,如何将 CPU 内核分配给 NUMA 节点?

linux - hexdump 并将二进制文件读取为文本

c - ARMv6 之前的 ARM 架构上的无锁原子操作

assembly - 如果前32个中断是为异常保留的,定时器中断怎么可能是0x08?

linux - 如何调用任何内核函数?

arm - 什么是 armel 以及 armel 与 arm 的关系?

c - 编译 ARM 演示项目时出现链接器错误

c - STM32F1xx CAN2 接收中断未被调用