当前位置: 首页 > 产品中心 > lcd显示屏-总成

Arm调试架构基础知识详解

发表时间: 2024-01-14 作者: lcd显示屏-总成
产品详情

  调试是软件开发的一个重要组成部分,通常是最消耗时间的(也因此非常昂贵)。错误可以是很难察觉、重现和修复的,而且也难以预料解决一个缺陷需要多长的时间。

  在产品交付给客户后,处理问题的成本明显地增加。在很多情况下,一个产品的销售只有一个很小的时间窗口,如果产品晚了,它可能错过市场的机会。因此,对于任何研发人员,系统所提供的调试工具是要考虑的一个重要因素。

  许多实用的嵌入式系统只有有限的输入/输出设备。这在某种程度上预示着可能没办法使用传统的台式机的调试方法(如实用printf()函数)。

  在过去,在这样的系统中,研发人员可能会使用昂贵的硬件工具,如逻辑分析仪和示波器来观察程序的行为。

  本书所描述的处理器是有高速缓存的一个复杂的片上系统,包含内存和许多其他功能模块。在片外也许无法看到处理器的内部信号,因此无法通过连接逻辑分析仪等设备来监测它的行为。

  出于这个原因,ARM系统一般包含专门的硬件,以便为调试提供广泛的控制和观测模块。

  Cortex-A系列处理器提供的硬件功能能使调试工具提供可以显著提升处理器控制活动和非入侵性地收集大量的有关程序执行数据的水平。我们大家可以将硬件的功能分为两类:入侵性和非入侵性。

  入侵性调试提供了能够停止程序并单步执行的工具(在C源代码或通过汇编语言指令单步执行),它能够最终靠一个外部设备连接到处理器芯片的JTAG引脚或(较少见)系统ROM中的调试监视代码。

  JTAG是JointTeston Group的简写,是IEEE 1149.1规范,它最初设计用来测试电路板上的电子设备,但现在大范围的使用在连接处理器调试。

  一个典型的JTAG连接有5个引脚:2个输入、1个时钟、1个复位和1个输出。

  调试器提供了控制执行程序的能力,使我们也可以运行到某一点的代码时暂停处理器、单步执行代码和继续执行,也可以在指定的指令上设置断点(当处理器到达这条指令时,让调试器控制它)。这些工作能够正常的使用两种不同的方法。

  (1)采用BKPT指令替代需要停止的指令可以产生软件断点。显然,这只能用于存储在RAM中的代码,但优点是可设为非常多的软件断点。该调试器软件必须跟踪记录放置软件断点的位置和该位置的原始操作码,这样当希望执行该断点处的指令时,它可以放回原始代码。

  (2)硬件断点,使用处理器内置的比较器,当执行到指定地址时自动停止执行。这可以用在代码空间中的任何地方,因为它们不需要修改代码,但硬件只能提供数量有限的硬件断点单元(Cortex-A系列通常只有4个)。调试工具能支持更复杂的断点(例如在一个地址范围内的任意指令,或仅当指定序列事件发生或硬件在指定的状态时停止任意指令)。数据观察点让调试器能控制当一个特定的数据地址或地址范围被读取或写入访问时,产生调试控制。这些也可以称为数据断点。

  调试事件是指进程的某些部分正在被调试导致系统通知调试器的事件。调试事件可以是同步或异步的,断点、BKPT指令和观察点都是同步调试事件。当任何这些事件之一发生时,该处理器能以以下方式之一响应。

  (1)停止调试模式。在停止调试模式中,一个调试事件会使处理器进入调试状态,该处理器被停止,并从系统的别的部分分离出来。这在某种程度上预示着,调试器可以显示处理器所能看到的内存,内存管理和缓存操作的影响将变得可见。

  在调试状态下,处理器从程序计数器指定的位置停止执行指令,并通过外部调试接口控制,尤其是使用错误指令转移寄存器(Debug Instruction Transfer Register, DBGITR),这启用了外部控制器,例如调试器来查询处理器的现场,并控制所有后续的指令执行。处理器和系统状态都是可以被修改的,因为处理器已经停止,它无法处理任何中断,直到调试器重新再启动代码执行。

  (2)监视调试模式。在监控调试模式中,调试事件会产生一个调试异常,无论是关于指令的执行产生的预取中止异常,还是数据访问时产生的数据中止异常,这些都必须由软件调试监视器处理。由于处理器仍然在运行,中断仍旧能被响应。

  非侵入性调试(在ARM文档中通常称为跟踪)可以在执行时观察处理器的行为,它可以记录内存访问的执行(包括地址和数据),并生成一个程序运行的跟踪,查看外设访问,堆和栈访问以及变量的改变。

  对于许多实时体统,**不可以使用入侵性调试的方法。**例如,考虑一个引擎管理系统,也许能够在特定的地方停止处理器,但引擎将继续运行,所以将无法做有用的调试,即使是在不太繁重的实时要求环境中,跟踪也是很有用的。

  非侵入性调试,或称为“跟踪”,是一种在不干扰或影响目标系统运行的前提下,观察和记录目标系统运行时行为的方法。这种方法非常适合于实时系统或那些不能接受中断的系统。

  侵入式调试是一种在调试过程中需要直接干预和介入目标系统运行的调试方式。这种调试方式需要在目标系统的源代码级别或汇编语言指令中停止程序并逐行执行它们。利用芯片JTAG引脚连接到内核的外部设备,或者通过调试监控代码,研发人员可以实现对目标系统的直接控制和干预。

  侵入式调试的优点是能够进一步探索目标系统的底层细节和运作时的状态,帮助研发人员准确地定位和解决实际问题。但是,这种调试方式也存在一些缺点。首先,它需要对目标系统来进行直接干预和介入,可能会对系统的正常运行造成干扰或破坏。其次,侵入式调试需要对目标系统的源代码或汇编语言指令做相关操作,这需要较高的技术水平和经验,并且可能会引入新的错误或问题。

  因此,在选择调试方式时,应该要依据真实的情况进行权衡和选择。对于一些复杂或关键的系统,侵入式调试可能是必要的,但在大多数情况下,非侵入式调试或跟踪可能是更合适的选择。

  通常,跟踪由连接到处理器的外部硬件模块提供,这是所谓的嵌入式跟踪宏单元(Embedded Trace Macrocell, ETM)或程序跟踪宏单元(Program Trace Macrocell, PTM),是基于ARM处理器系统的一个可选部分,SoC在设计时可以去除这个模块以降低成本。

  这个模块可以观察(但不影响)处理器的行为,并能监视指令的执行和数据的访问。

  第一个问题与如今非常高的处理器主频有关,即使几秒的操作也可能执行数万亿周期。显然,要查询如此多的信息将是十分艰难的。

  第二个问题是,如今的处理器在一个周期中可能执行一个或多个64 bit缓存访问,要记录数据地址和数据值就需要非常大的宽带。

  这就带来一个的问题,芯片上可能只能提供少数引脚,并且这些输出引脚只能用一个比处理器主频更低的时钟。如果处理器以速度为1 GHz的时钟,每个周期生成100 bit的信息,但芯片只能以200MHz的速度输出4 bit的跟踪信息。

  为了解决这一个问题,跟踪宏单元将尝试压缩信息,以减少所需的宽带。然而,处理这样一些问题的主要方法是控制跟踪模块,以便只收集所选择的跟踪信息。

  例如,我们可能只跟踪执行流,而不记录数据值,或我们只跟踪一个特定外设或特定函数执行的数据访问。

  由于处理器的速度和复杂性,捕获其所有操作的信息是十分艰难的和带宽密集型的。因此,常常要采用特定的策略和方法来仅捕获所需的信息,从而有效地解决调试和故障排除问题。

  此外,将跟踪信息存储在芯片的内存缓冲区(嵌入式跟踪缓冲区(ETB))是常见的办法,这将缓解芯片获取信息的速度问题,但在硅片面积(对应芯片的价格)会有额外的成本,并且会限定一个固定的可被捕获的跟踪信息量。

  ETB以循环方式存储压缩的跟踪信息,连续的捕获跟踪信息直到停止。ETB的大小依据芯片的实现不同而变化,但通常8KB或16KB的缓冲区就足以容纳对几千行程序的跟踪。

  在程序发生故障时,如果启动了跟踪缓冲区,则能够正常的看到部分程序的历史记录,通过程序的历史记录,很容易通过程序查回去,看看在故障点前发生了什么。

  这对于调查间歇和实时故障特别有用,而这对传统的需要停止和启动处理器执行的调试方法是很难的。

  使用硬件跟踪可以显著地减少寻找故障所需的时间,跟踪信息精确地显示执行了什么,何时产生的以及访问了什么数据。

  这种技术能用于生成程序的calltrace,即记录程序执行过程中函数或方法的调用序列。

  通过calltrace,可以了解在故障点前程序执行的具体流程和函数调用关系。这有助于分析问题的根本原因,确定是哪个函数或方法导致了故障,以及故障是如何产生的。

  ARM的CoreSight技术通过ETM提供了扩展功能,在特定的系统中它的存在和功能是由芯片设计者定义的。

  最近在找一个课程,看看能不能让我去学习一下Verilog的实现,到时候有机会的话,可以分享的更加深入一点。

  CoreSight提供了一个非常强大的调试功能,它可以调试多处理器系统(非对称和SMP),共享调试和跟踪的引脚,在一段跟踪时间内,具有对处理器的完全控制。

  嵌入式交叉触发机制让工具可以同步控制多个内核,例如,当一个内核遇到一个断点,也将停止所有其他的内核。

  商业的调试工具可以使用跟踪数据提供诸如处理器寄存器、内存及外设的实时视图等功能,允许用户对程序流进行单步向前或向后执行。

  OS信息调试器可以使用跟踪信息(在某些情况下,额外的代码插装)提供高级别的系统上下文信息。

  像DS、劳特巴赫这些其实都是细分赛道,做的很深,国内这样的企业好少~~~期待。

  。DAP是ARM的CoreSight系统的一个可选部分,不是每个设备都包含DAP,

  。在没有DAP情况下,要读取或写入可能需要调试器停止处理器,并执行加载或存储指令。DAP提供了一个外部调试工具来访问系统中的所有的JTAG扫描链(因此可以访问处理器的所有调试和跟踪寄存器)(2)嵌入式交叉触发(ECT)。

  。例如,我们可以有两个相互独立的运行内核,在一个内核的运行程序上设置一个断点时,如果可以在一个内核在断点处停止时,让另一个内核也停止下来(无论当前正在执行什么指令),那么将对调试工作非常有帮助。ECT中的交叉触发矩阵和接口可以在内核和跟踪宏单元之间传递调试状态和控制信息。(3)AHB跟踪宏单元。

  AMBA AHB跟踪宏单元可以让调试器看到系统内存总线上发生了什么。此信息不是直接从处理器ETM得到的,因为集成的内核无法确定这个数据来自缓存还是外部存储器。

  CoreSight串行线调试通过使用调试访问端口(DAP)给出了一个2引脚的连接,它的功能相当于5引脚的JTAG接口。

  。系统中任何主设备运行的软件都能够通过使用非常简单的代码片段访问STM通道,而无须知道其他软件的使用,它会使能内核和用户代码的仪器化软件的时间标记。时间标记的信息提供了相对于先前的事件的一个变化偏移量,这是非常有用的。(6)跟踪内存控制器(TMC)。

  添加额外的引脚会显著地增加其成本。在多个内核设备(或其他模块能产生跟踪信息)的情况下,为经济考虑很可能排除提供多个跟踪端口的可能性。CoreSight跟踪内存控制器可用于将多个跟踪源合并到一个单一的总线上。控制可以在多个输入源之间进行优先级考虑和选择。跟踪信息可以使用专门的跟踪端口导出,通过JTAG或SWI串行线接口或通过复用SoC的I/O端口,可以存储在一个ETB或系统内存中。

  应该查阅所使用的设备的文档,以确定哪些跟踪功能和工具可以使用。调试监视器

  ARM架构为外部调试器提供了多种访问的功能,这些功能模块也可用于处理器的代码,即所谓的调试监视器,它驻留在目标系统。

  监视系统是比较便宜的,因为它们可能并不需要额外的硬件。然而,它们需要占用系统的存储器空间,而且

  。如果执行了BKPT指令,或一个硬件断点单元匹配,系统在监视模式下会有不同的行为。相比在外部硬件调试器控制下停止处理器,在监视模式下处理器会产生一个中止异常,并且它可以识别这是不是由调试事件产生的中止,然后调用监视代码。

  想要在某个特定的代码行上设置一个断点。在监视模式下,开发者可以在目标系统上运行一个特殊的指令来编程断点单元。当程序执行到这一行时,断点单元会触发并产生一个异常。处理器可以识别这个异常是由断点引起的,然后执行预定义的监视代码。这个监视代码能够适用于收集调试信息、记录程序状态或执行其他必要的调试任务。总的来说,

  ,允许开发者在不停止系统运行的情况下检查程序状态和行为。通过使用断点和观察点硬件,开发者可以在目标系统上设置断点、观察点或执行其他调试操作,从而更好地理解程序的执行流程和潜在问题。很多编写源码的IDE工具大概就是利用这个操作来实现的。所以说做编译器真的有点东西。

  ,其每一个进程都有自己的进程地址空间,并完成私有页表的映射,这会让调试一些问题比较麻烦。我们大家可以大致定义两个不同的调试Linux系统所使用的方法。

  ,这种调试方法不会使用所提供的内置硬件调试设备,目标系统永久处于运作时的状态,服务器接收到主机调试器的请求,然后接收命令,并提供数据传回主机。主机调试器将加载请求发送给GDB服务器,

  ,这个进程中的所有信号被转发到GDB服务器。任何发送到应用程序的信号将会进入GDB服务器,它能处理信号或将其转发给正在被调试的应用程序。

  当执行该代码时,GDB服务器被调用,然后执行调试器任务,如检查调用栈信息,变量或寄存器内容。

  Kgdb是一个Linux内核的源代码级调试器,它与GDB协同工作在单独的机器上工作,可拿来检查堆栈跟踪和内核状态视图(如PC值、

  由于存储器映射取决于哪个进程是活动的,因此软件断点通常只能设置在一个特定进程进行映射时。

  调试器能够最终靠gdbserver调试应用程序,通过JTAG调试Linux内核和Linux内核模块。还有Trace32工具。

  的“CoreSight(内核景象)”调试架构,对处理器上总线逻辑的控制使用另外的总线接口,即通过所谓的“调试访问端口(Debug Access Port,DAP)”,把JTAG或串行线协议都转换成DAP总线接口协议,再控制DAP来执行调试动作。CoreSight架构的另一部分用于跟踪,在跟踪踪过程中,由跟踪源产生的数据被裹成数据包,然后被送到“高级跟踪总线(

  vanced Tracking Bus,ATB)”上进行传送。如果某SoC含有多个跟踪源(如多核系统),则需要一种硬件(在CoreSight架构中,这种硬件被称为ATB funnel)水平的ATB归并器(merger),把各ATB数据流归并成一条。

  U(Trace Port Interface Unit,跟踪端口接口单元),TPIU再把数据导出到片外的跟踪硬件设备数据总线和指令总线通过总线接口与代码存储器,外部存储器,外部设备和内部设备做连接。

  的CoreSight架构。不同于以往的ARM处理器,内核本身不再含有JTAG接口。取而代之的是CPU提供称为“调试访问接口(DAP)”的总线接口。通过这一个总线接口,可以访问芯片的寄存器,也可以访问系统存储器,还可以在内核运行时访问。

  商可以从中选择一个,以提供具体的调试接口(通常都是选SWJ-DP)。Cortex-M3还能挂载一个所谓的“嵌入式跟踪宏单元(ETM)”。

  ETM可以不断地发出跟踪信息,这一些信息通过一个被称为“跟踪端口接口单元(TPIU)”的模块送到内核的外部,再在芯片外面使用一个“跟踪信息分析仪”,

  在Cortex-M3中,调试动作能由一系列的事件触发,包括断点、数据观察点、fault条件或者是外部调试请求输入的信号。

  当调试事件发生时,Cortex-M3可能会停机,也可能进入调试监视器异常handler。具体如何反应,则根据与调试相关寄存器的配置。

  与调试相关的还有别的的绝活。现在要介绍的是“指令追踪宏单元(ITM)”,它也有自己的办法把数据送往调试器。

  。此法不但容易使用,而且比JTAG的输出速度更快。所有这些调试组件都可以由DAP总线接口来控制,Cortex-M3内核提供DAP接口。此外,运行中的程序也能控制它们,所有的跟踪信息都能通过TPIU进行访问。

  ,允许用户使用行业标准的第三方调试工具。Xilinx TAP控制器在标准的JTAG功能上添加了一些支持PL的特性,包括PL调试、熔丝/BBRAM编程、片上X

  访问等。更重要的是,它通过共享跟踪缓冲及PL和PS的交叉触发接口,达到允许在使用DAP调试ARM上的软件的同时,使用TAP调试PL硬件。

  联合测试行动小组(JTAG)国际标准测试协议已被业界大范围的应用。JTAG接口的基本功能在于将固件

  到设备芯片,并在程序运行时对软件执行过程做多元化的分析监测,监测内容有CPU中的寄存器和内存中存储的值,以实现对芯片内部测试及系统仿真、调试。芯片厂商通常将JTAG接口作为片上系统的一部分。例如,ARM公司在其处理器芯片的CoreSight调试架构中集成了这一接口。

  JTAG的使用提高了移动终端固件开发的便利性。但由于JTAG接口通常是开放的,因此,攻击者能够找到芯片上JTAG接口的引脚并接入工具,实现对移动终端的攻击。

  例如,可以破坏或禁用系统组件,提取固件代码或加/解密密钥,也可以插入没有经过授权的功能函数,获得攻击系统的后门,传输攻击程序及分析设备漏洞等。由于通过JTAG可以同时访问内存和处理器的信息,

  的安全防护方法抵御基于JTAG接口的攻击。(1)基于电路特性隐匿的JTAG接口攻击防护

  这种防护的核心技术思想是在芯片的硬件电路上做必要的修改,使攻击者难以从物理层面接入。

  例如,修改芯片上JTAG的默认输入电压,使得攻击者难以使用有效的电压激活JTAG接口;

  修改引脚映射,即修改芯片上面JTAG引脚的布局,使攻击者难以辨认哪些管脚被用于JTAG;

  ,并以删除输入/输出端口的方式来禁用JTAG端口,使得开发者无法再使用JTAG。(2)基于认证的JTAG接口攻击防护

  ,通过“验证-挑战”的方式对接入的JTAG器件的权限进行认证。通过接收固定的字符,微控制器将会验证当前的JTAG端口连接请求是不是满足身份。在通过验证后,微控制器将把当前外部器件发送的调试指令转发给实际芯片的JTAG端口。

  另外,也可以在使用JTAG接口之前,强制要求要输入密码或者使用JTAG带有密钥进行身份认证。

  其实一直都是停留于使用者的角度来认识Coresight以及调试软件与工具,期待站在设计者的角度来认识Coresight。