一、中断向量表介绍

中断是指计算机运行过程中,出现某些意外情况需主机干预时,机器能自动停止正在运行的程序并转入处理新情况的程序,处理完毕后又返回原被暂停的程序继续运行。
以上是中断在百度百科中些较为浅显的解释,中断实际上是操作系统中较为重要的一种概念及机制,关于中断的一些详细的说明可以在由张银奎老师主讲的《在调试器下理解计算系统》中观看到(视频在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指向的是中断向量表。其中不同向量表间的偏移量、中断类型、中断级别可以参考下图。

(reference:Anatomy 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);
}

通过GDK8观察ARM框架下的中断向量表相关推荐

  1. x86和arm框架下的centOS

    1 CPU架构分为 X86 , ARM ,MIPS , power , ia64 AMD64 = X86_64 = x64 ,是64位的CPU 架构,区分ARM64 1.x86 : 复制指令集cisc ...

  2. 如何在敏捷框架下做好工作交接

    这是一篇我最不想写的博客了.不过,随着部门里面一个可爱的小姑娘为了爱情不得不去上海工作同时也成功的拿到了SAP的offer,我不得不思考如何作好工作上的交接,毕竟法律规定的期限只有一个月的时间. 先说 ...

  3. Caffe使用step by step:caffe框架下的基本操作和分析

    Caffe使用step by step:caffe框架下的基本操作和分析 时间:2015-10-16 11:40:09      阅读:808      评论:0      收藏:0      [点我 ...

  4. 【阿里妈妈数据科学系列】第二篇:在线分流框架下的AB Test

    背景 AB Test 是为同一目标制定两个方案,在同一时间维度,保证其他条件一致的情况下,分析实验组跟对照组的区别,根据不同的实验类型以及应用场景,产生了不同分桶逻辑的AB Test,包括在线分流及离 ...

  5. 在线分流框架下的AB Test

    背景 AB Test 是为同一目标制定两个方案,在同一时间维度,保证其他条件一致的情况下,分析实验组跟对照组的区别,根据不同的实验类型以及应用场景,产生了不同分桶逻辑的AB Test,包括在线分流及离 ...

  6. Keras 和 Tensorflow 框架下五种视频分类

    目前视频分类是机器学习模式中独树一帜的挑战.今天我们就要来看看在Keras 和 Tensorflow 框架下的不同的视频行为识别策略,我们将会学着如何使用五深度学习的模式去学习UCF101数据组,具体 ...

  7. 深入剖析 RabbitMQ —— Spring 框架下实现 AMQP 高级消息队列协议

    前言 消息队列在现今数据量超大,并发量超高的系统中是十分常用的.本文将会对现时最常用到的几款消息队列框架 ActiveMQ.RabbitMQ.Kafka 进行分析对比. 详细介绍 RabbitMQ 在 ...

  8. 第14篇:Struts2框架下Log4j2漏洞检测方法分析与总结

     Part1 前言  Log4j2漏洞出现有大半年的时间了,这个核弹级别的漏洞危害很大,但是这个漏洞检测起来却很麻烦,因为黑盒测试无法预判网站哪个应用功能在后台调用了log4j2记录日志功能.目前通用 ...

  9. Scrapy框架下的海贼王漫画自动爬虫

    从小就是个海贼迷,学了爬虫后第一个上手自己写的爬虫自然而然就想到了爬海贼的漫画. 是在scrapy框架下写的爬虫,至于scrapy框架的安装就不多说了,网上有很多的安装教程. 前提准备 进到放置文件的 ...

最新文章

  1. 《系统集成项目管理工程师》必背100个知识点-62采购管理
  2. python 关闭 定时开启_Python爬虫邮箱定时自动发送
  3. python获取当前路径和上一层路径_python获取当前路径和上一级路径
  4. 语法制导定义 SDD
  5. Delphi2007下cxComboBox乱码.
  6. au计算机内录音乐,电脑中如何使用 Audition 内录声音
  7. MySQL存储过程实例
  8. vue 前端 增加取色器/拾色器
  9. 手机验证码实现注册功能
  10. PDF格式转JPG格式怎么转?掌握方法其实很简单
  11. Day004--MySQL中的多表查询
  12. SAP MM 采购订单中“Delivery Completed“ Indicator
  13. 计算机在化学中的应用免费论文,计算机在化学化工中的应用
  14. Unity做360度的全景照片
  15. 贫富分化是生产力发展的必然趋势 zz
  16. 物联网常见通信模块介绍
  17. 刚开始做软件测试,一般工资范围是多少?
  18. 用友系统服务器,用友财务系统需要什么云服务器
  19. 工业类计算机主板维修,工控机电脑主板坏了如何维修
  20. 【微服务】如何实现微服务集群的高可靠?

热门文章

  1. python excel数据处理 空格替换_Python/Excel/SPSS/SQL数据处理方法比较之5 - 空格清理...
  2. Ubuntu cp命令
  3. 锤子选择以激光电视进军电视市场可能是一种错误
  4. LFTP连接FTPS
  5. php幻灯片的插件,jQuery幻灯片插件Flickerplate
  6. 【CV秋季划】生成对抗网络GAN有哪些研究和应用,如何循序渐进地学习好(2022年言有三一对一辅导)?...
  7. 除了Multi-Touch和3D变换效果外,手机中另一重量级:力反馈。
  8. 开发一个c语言程序要经过,开发c程序的基本步骤
  9. XxlJob(一) 分布式定时任务XxlJob用法及核心调度源码详解
  10. Android UI优化—从Android渲染原理理解UI卡顿