通过GDK8观察ARM框架下的中断向量表

article/2025/9/13 23:11:13

一、中断向量表介绍

        中断是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行。
以上是中断在百度百科中些较为浅显的解释,中断实际上是操作系统中较为重要的一种概念及机制,关于中断的一些详细的说明可以在由张银奎老师主讲的《在调试器下理解计算系统》中观看到(视频在nano code中;下载链接:Nano Code下载)。
        上面提到“转入处理新情况的程序”,那么中断后,该如何确定这个新程序呢?这时候就需要系统的中断向量表了,中断描述符表中存储了中断的相关信息,当CPU被中断后,CPU会获取中断向量,然后查阅这张表,找到对应的中断信息,然后根据中断信息跳去相应的位置处理事情。
        今天我们就来详细研究一下ARM框架下的中断向量表。并编写代码把向量表以友好的方式解析出来。


二、查看中断向量表

那么该如何查看中断向量表呢?在ARM框架下系统寄存器VBAR_EL1(Vector Base Address Register)指向的就是中断向量表。

1 . 在Nano Code中获取VBAR_EL1寄存器的地址。

rdmsr VBAR_EL1

  

2 . 解析这个地址,获取该地址处指令和函数。

ln ffffff8008081800

3 . 此时,我们可以在代码中根据这个函数找到它的地址,编写跨内核版本的代码。

ULONG64 VBAR_EL1_ADDR;
// 获取 lk!vectors 函数的地址,并把地址存储到 变量 VBAR_EL1_ADDR 中
GetExpressionEx("lk!vectors", &VBAR_EL1_ADDR, NULL);

三、解析中断向量表

参考和引用

寄存器VBAR_EL1指向的是中断向量表。其中不同向量表间的偏移量、中断类型、中断级别可以参考下图。

referenceAnatomy of Linux system call in ARM64 | East River Village

Offset from VBAR_EL1

Exception type

Exception set level

+0x000

Synchronous

Current EL with SP0

+0x080

IRQ/vIRQ

+0x100

FIQ/vFIQ

+0x180

SError/vSError

+0x200

Synchronous

Current EL with SPx

+0x280

IRQ/vIRQ

+0x300

FIQ/vFIQ

+0x380

SError/vSError

+0x400

Synchronous

Lower EL using ARM64

+0x480

IRQ/vIRQ

+0x500

FIQ/vFIQ

+0x580

SError/vSError

+0x600

Synchronous

Lower EL with ARM32

+0x680

IRQ/vIRQ

+0x700

FIQ/vFIQ

+0x780

SError/vSError

稍加分析,可以看到,总共有16张中断向量表,其中:

  • 每个表都占用128字节(十六进制0x80就是十进制128),
  • 每张向量表最多存放32条大小为4字节的汇编指令,
  • 每张向量表的起始地址都是VBAR_EL1 + n * 0x80 (n的取值范围 [0, 15])。

再对照下图内核源码:可以看到源码和上图表格中的分析是一一对应的。

源码Website:kernel/entry.S at main · gdk8/kernel (github.com)

ENTRY(vectors)kernel_ventry   1, sync_invalid         // Synchronous EL1tkernel_ventry   1, irq_invalid          // IRQ EL1tkernel_ventry   1, fiq_invalid          // FIQ EL1tkernel_ventry   1, error_invalid        // Error EL1tkernel_ventry   1, sync                 // Synchronous EL1hkernel_ventry   1, irq                  // IRQ EL1hkernel_ventry   1, fiq_invalid          // FIQ EL1hkernel_ventry   1, error                // Error EL1hkernel_ventry   0, sync                 // Synchronous 64-bit EL0kernel_ventry   0, irq                  // IRQ 64-bit EL0kernel_ventry   0, fiq_invalid          // FIQ 64-bit EL0kernel_ventry   0, error                // Error 64-bit EL0#ifdef CONFIG_COMPATkernel_ventry   0, sync_compat, 32      // Synchronous 32-bit EL0kernel_ventry   0, irq_compat, 32       // IRQ 32-bit EL0kernel_ventry   0, fiq_invalid_compat, 32   // FIQ 32-bit EL0kernel_ventry   0, error_compat, 32     // Error 32-bit EL0
#elsekernel_ventry   0, sync_invalid, 32     // Synchronous 32-bit EL0kernel_ventry   0, irq_invalid, 32      // IRQ 32-bit EL0kernel_ventry   0, fiq_invalid, 32      // FIQ 32-bit EL0kernel_ventry   0, error_invalid, 32    // Error 32-bit EL0
#endif
END(vectors)

开始解析

1、第一层解析:解析第一层向量表。

向量表之所以称之为表,说明他们内部含有其他数据,数据排列像表格一样。这里我们把sync看作第一层向量表,并对表sync进行解析。

a . 查看向量表的详情信息,根据偏移量0x200确定某个表的的起始地址,表sync的起始地址为VBAR_EL1+0x200,也就是 ffffff8008081800+0x200 。

b . 使用命令u来逐页查看该地址处的汇编指令。

u uffffff8008081800+0x200

        
再次输入u,会按照每页8条指令继续解析。

         

2、在表sync中寻找第二层向量表。

在表sync中所有汇编指令中,我们要找的是与函数跳转挂钩的指令,例如 b 或者 b.eq 或者 bl,解析b 的参数,解析出的函数名就是我们寻找的第二层向量表。

        

这里以解析黄圈内的地址为例

// 根据地址来获取函数名
ln 0xffffff8008082ac0// 解析地址处的汇编指令
u 0xffffff8008082ac0

        

此时我们了解到 地址 0xffffff8008082ac0处存放的是 el1_sync函数,该函数就是我们寻找的第二层向量表。

3、第二层解析:对照Linux内核源码,按照内核的逻辑解析第二层向量表el1_sync。

a . 在内核源码中查找该函数,查看其结构和逻辑。

        

         

b . 使用指令u在Nano Code中找到与源码对应的部分。

        

在解析向量表时,我们要显示出内核原本的逻辑和结构,例如解析 el1_sync函数时可以按照以下格式输出:

0x25: lk!el1_da
0x21: lk!el1_ia

按照这种输出格式,依次解析剩余的部分。

c . 到这里我们已经解析了三层了,当然还可以继续追根溯源,但是对于错误向量表的研究,这三层已经足够了。

4、根据以上研究,我们可以把向量表看作树形结构,并按照以下格式来输出。

        

        

5 . 每张向量表的处理方式都相似,我们按照上述方法依次处理16张总的向量表。


四、开发调试环境

  • 软件:NanoCode调试软件 (Website:Nano Code下载
  • 设备:GDK8套件(Website:GDK8) 挥码枪NTP(Website:NTP)
  • 关于NanoCode和GDK8的搭配使用,可以参考博客(GDK8——强大的Linux内核调试工具)
  • 代码中相关函数的使用可以参考微软官方:调试器概述 - Windows drivers | Microsoft Learn

五、牵扯到的函数

在NanoCode中可以使用 u、ln、x等命令可以很方便的解析相关信息,在代码中也有特定的函数与其对应。

函数的更多信息请参考微软官方:调试器概述 - Windows drivers | Microsoft Learn

下面是一些简单的用法:

typedef unsigned long long ULONG64;
void test(void)
{// GetExpressionEx :传入函数名称,获取该函数的地址。对应着NanoCode命令 xULONG64 VBAR_EL1_ADDR = 0;GetExpressionEx("lk!vectors", &VBAR_EL1_ADDR, NULL);dprintf("VBAR_EL1_ADDR: %p\n", VBAR_EL1_ADDR);// GetSymbol :根据传入的地址,获取函数名。对应着NanoCode命令 lnULONG64 FuncAddr = 0xffffff8008081800, SymOffset;char FuncName[50] = "";GetSymbol(FuncAddr, FuncName, &SymOffset);// Disasm :根据传入的地址,获取该地址处的一条汇编指令。对应着NanoCode命令 uchar Assembly[100] = "";ULONG64 Address = 0xffffff8008081800;Disasm(&Address, Assembly, 100);
}


http://chatgpt.dhexx.cn/article/tePlhv4q.shtml

相关文章

【STM32】中断向量表

我是通过这个进行学习的,我觉得讲的很好,这里我稍加修改,作为自己的学习笔记: 嵌入式杂谈之中断向量表 前言 STM32根据boot引脚的配置方式有3种启动方式,但是无论哪一种方式,对于STM32来说都是从0x0000 0000启动 ST…

Cortex M4 中断向量表

前言 重新学习Cortex M4的中断向量表内容。中断向量表是Cortex M4自带的功能,厂家可以根据需要自行定义,所以需要学习该内容,直接看Cortex M4内核相关即可。我这查看的是《Cortex M3与M4权威指南.pdf》。 一、中断向量 中断向量是什么&…

中断向量表

关于中断向量的几点注释 1. 系统引导时,中断向量表放在内存何处? 系统刚引导时,内存0x00000到0x0003FF共1KB的空间用于存放中断向量表。每个中断向量占用4个字节,共可存储256个中断向量。 2. 系统引导时,处在实模式下,只可寻址1MB,为什么要用4个字节来寻址中断呢处理程…

TF_REPEATED_DATA ignoring data with redundant timestamp for frame left_wheel at time

使用urdf和xacro编写机器人仿真模型的时候,同时开启gazebo和rviz的时候遇到的问题 ubuntu20.04 ros noetic 开启gazebo并启动rviz时,rviz终端会一直产生一个警告:TF_REPEATED_DATA ignoring data with redundant timestamp for frame left…

ProtoBuf(Google Protocol Buffers)—— repeated 修饰字段注意点(packed修饰)

ProtoBuf—— (repeated 修饰 ) repeated1、定义2、使用事项 参考 repeated 1、定义 repeated类型相当于STL的vector,可以用来存放N个相同类型的内容。proto2 中还有 repeated 可选,在proto3 中则已经被摒弃并且默认格式为pack。…

Responder

在hack the box 最后一个sql注入题时,有这个工具的使用,之前没有接触过,看write up上是需要利用两个IP地址,似乎与内网渗透有关,马上查找相关资料,看到底是个什么东东。 什么是Responder 在攻防领域&…

Reverse

IDA中文不显示解决 参考链接 VScode中文乱码解决参考链接 (1 ~ 10攻防世界)(11~20为Buu,近乎为shift F12查找字符串) 1. xxxorrr 题目链接 题目WP 心得:可能会有其它隐藏函数对所需结果进行操作 2. SignIn RSA算法介绍 c是密文,m是明文…

java中@Repeatable的理解

Repeatable是jdk8中新增的注解,使用如Spring中的ComponentScan注解。在没有Repeatable注解的的注解中,在同一个地方使用相同的注解会报错,有了此元注解注解的注解,就可以在同一个地方使用相同的注解。其官方文档如下 The annotati…

TS:解决docker无法启动,报:start request repeated too quickly for docker.service错误-2021.12.08(已解决)

目录 文章目录 目录1、报错现象2、解决办法3、总结关于我最后 1、报错现象 首先,我当前的环境是:docker 20.10.11,vmworkstation虚机 很奇怪,自己的docker用着用着就出现问题了,查看服务发现起不来,重启docker服务也…

【已解决】TF_REPEATED_DATA ignoring data with redundant timestamp for frame

目录 1 问题背景2 问题探索3 问题解决4 告别Bug 1 问题背景 环境:Ubuntu20.04 ROS-noetic 现象:打开Rviz与Gazebo加载机器人模型时,终端不停刷新警告TF_REPEATED_DATA ignoring data with redundant timestamp for frame,且在未施…

已解决(一分钟)TF_REPEATED_DATA ignoring data with redundant timestamp for frame base_footprint at time解决方案

<1>问题描述 前言-仿真实验需求&#xff1a;获取小车的全局坐标系下的位姿信息&#xff0c;因此使用gmapping建图&#xff0c;并使用地图服务调用发布&#xff0c;自己写了个节点将map坐标系添加到现有的TF树上&#xff0c;最终TF树见最后截图。 进入正题&#xff0c;想…

【Protocol Buffer】Protocol Buffer入门教程(五):repeated限定修饰符

00. 目录 文章目录 00. 目录01. 限定修饰符介绍02. 字段API分析03. 测试代码04. 编译和测试05. 参考 01. 限定修饰符介绍 repeated 代表可重复&#xff0c;我们可以理解为数组 syntax "proto3";//指定版本信息&#xff0c;不指定会报错message Person //message为…

protobuf入门教程(四):repeated限定修饰符

限定修饰符说明 repeated 代表可重复&#xff0c;我们可以理解为数组&#xff1a; syntax "proto3";//指定版本信息&#xff0c;不指定会报错message Person //message为关键字&#xff0c;作用为定义一种消息类型 {string name 1; //姓名int32 id 2; …

一个真·菜鸟理解的springmvc工作原理

1 springmvc的映射器和适配器 1.1springmvc的映射器 根据客户端请求的url&#xff0c;找到处理本次请求的handler&#xff08;处理器&#xff09;&#xff0c;将url和controller关联起来 1.2springmvc的适配器 对映射器查找到的controller中的方法进行调用。 第一种&#xff1…

【转】SpringMVC的工作原理图

SpringMVC的工作原理图&#xff1a; ##SpringMVC流程 1、 用户发送请求至前端控制器DispatcherServlet。 2、 DispatcherServlet收到请求调用HandlerMapping处理器映射器。 3、 处理器映射器找到具体的处理器(可以根据xml配置、注解进行查找)&#xff0c;生成处理器对象及处理…

SpringMVC工作原理及执行流程

一、SpringMVC简介 SpringMVC是一种基于Spring实现了Web MVC设计模式的请求驱动类型的轻量级Web框架&#xff0c;使用了MVC架构模式的思想&#xff0c;将web层进行职责解耦&#xff0c;并管理应用所需对象的生命周期&#xff0c;为简化日常开发&#xff0c;提供了很大便利。  …

SpringMVC工作原理图

1.用户发送请求至前端控制器DispatcherServlet(也叫中央处理器). 2.DispatcherServlet收到请求调用HandlerMappering处理器映射器 3.处理器映射器找到具体的处理器&#xff08;可以根据xml配置、注解进行查找&#xff09;&#xff0c;生成处理器对象及处理器拦截器&#xff08;…

servlet — SpringMVC工作原理

如下图&#xff0c;所有实线的部分都由 SpringMVC 框架实现&#xff0c;我们的代码只需要处理虚线的部分&#xff1a; 【总结】&#xff1a; DispatchServlet(请求分发器 / 前端控制器), 是SpringMVC的核心 1. 用户发起请求的时候调用前端控制器 DispatcherServlet&#xff1b…

SpringMVC 工作原理

0x00:请求流程图 首先,来看一下 SpringMVC 的整个请求流程,如下图: 0x01:步骤解析 SpringMVC 整体流程步骤解析: 1,用户去单击了某个请求路径,发起了一个 request 请求,这个请求会被 DispatcherServlet 前端控制器处理。 2,前端控制器 DispatcherServlet 去请求处…

SpringMVC工作原理nbsp;及注解说明

Spring MVC工作原理 及注解说明 SpringMVC框架介绍 1) spring MVC属于SpringFrameWork的后续产品&#xff0c;已经融合在SpringWeb Flow里面。 Spring框架提供了构建 Web 应用程序的全功能 MVC 模块。使用 Spring 可插入的MVC 架构&#xff0c;可以选择是使用内置的Spring Web …