【盛格塾】使用GDK7观察LINUX内核的中断描述符表(IDT)

本文介绍了计算机中的中断机制及其核心组件IDT(中断描述符表)的作用与实现原理。通过GDK7工具观察Linux系统中的IDT表项,了解不同中断向量对应的处理函数。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

069c0c224991ec7bb202526aa0d7ab42.png

4b0e651a6a9afcd4523d136655db9e16.png

2021.09.17

GDK7 IDT

1.中断描述符表概述

中断应该是一个覆盖范围较广的概念,在很多时候我们都会需要“中断”。

例如:当你用水壶烧水时,你并不需要一直盯着它,可以抽身去做一些别的的事情,当水壶完成烧水的任务,它可能会发出“嘟嘟嘟”的声音来告诉你水烧好了。这样你既完成了一些别的事情,同时又有了热水喝。

在计算机中,中断也是如此,CPU的时间较为宝贵,并不可能所有的事情都亲历亲为,也不可能只盯着一件事情,等这件事情结束后再去做下一件事情。因此,CPU会通过下达任务的方式给其他执行单元,在执行单元做任务的过程中,CPU可以抽身去做其他的事情。当该执行单元完成任务后,通知CPU即可,这样任务也完成了,CPU也可以利用宝贵的时间去做其他的事情。

在计算机中,中断机制可以让CPU随时被打断,然后去出来其他事情,当事情处理好后再回来做原来的事情;中断通常可以分为内部中断(异常)和外部中断(硬件中断)。

824d7834e5d76fb3f9c2a7571f9c09cc.png

《在调试器下理解计算机系统》课程截屏

上面只是关于中断及中断机制的一些较为浅显的解释,中断实际上是操作系统中较为重要的一种概念及机制,关于中断的一些详细的说明可以在由张银奎老师主讲的《在调试器下理解计算系统》中观看到。(视频在Nano Code中)

Nano Code下载链接:

https://nanocode.cn/#/download

4f7246571275f84180420c8a761964ac.png

《在调试器下理解计算机系统》课程截屏

在上面的截屏中我们可以看到CPU在当前操作系统三大机制(中断、陷阱、任务)之下,CPU所发生的旅途轨迹。

当CPU可以被中断后,又出现了另一个问题,即CPU应该去哪里执行事情呢,总要有个目标吧,而且这个目标应该非常精确才行,不然差之毫厘,CPU就去处理其他的事情了。因此我们就非常的需要IDT中断描述符表了,IDT中断描述符表内存储了中断的相关信息,当CPU被中断后,CPU会获取中断向量,然后查阅这张表,找到对应的中断信息,然后根据中断信息跳去相应的位置处理事情。

IVT中断向量表可以理解为“迷你版”的IDT中断描述符表,里面存储的中断向量是中断服务程序的入口地址;该入口地址由IDT中断描述符表内的segmen字段和offset_low字段组合形成的(段地址+低16位偏移地址)。

0ad74e30f2823053c05a597090adf79e.png

GDK7 IDT

2.使用GDK7观察IDT

关于如何使用GDK7与调试机建立连接的过程,可以参照下方链接中的文章,在此不再过多赘述。

https://mp.youkuaiyun.com/mp_blog/creation/editor/118387446

使用GDK7观察IDT,首先要让GDK7与我们的调试机建立连接,如下所示。

e2bcd2a52d62e26cc48b9cc69b1ce127.png

55dff80e388731f304204fe2cbe88cee.png

打开nano code,载入ndx扩展,并输出!idt扩展命令。

966801380894dd8d005afb329e31a3f2.png

执行完成后输出以下结果。

1cc5de74c4d09a574df2937f49199e61.png

从执行的结果中。我们可以看到,第一列是向量号,第二列是门描述符,第三列是函数地址,第四列是函数名。

中断向量号   异常事件   函数名

0   除法错误   Divide_error

1   调试异常   Debug

2   非屏蔽中断   Nmi

3   断点中断   Int 3

4   溢出中断   Overflow

5   边界监测中断  Bounds

6   无效操作码   Invalid_op

7   设备不可用   Device_not_available

8   双重故障   Double_fault

9   协处理器段溢出  Coprocessor_segment_overrun

10   无效    TSS Incalid_tss

11   缺段中断   Segment_not_present

12   堆栈异常   Stack_segment

13   一般保护异常  General_protection

14   页异常    Page_fault

15    intel保留   Spurious_interrupt_bug

16   协处理器出错  Coprocessor_error

17   对齐检查中断  Alignment_check

18   机器检查中断  Machine_check

19   不可屏蔽中断  Simd_coprocessoe_error

9f7a442eb6dba81ec833defc5328077c.png

GDK7 IDT

3.!idt的实现原理

idt_table在Linux中被定义成了一个数组,每个数组所指向的均是gate_struct结构体,因此显示数组信息亦相当于显示gate_struct结构体的信息,只不过因为地址的不同,gate_struct结构体所含有的信息也会有所差别;想要从idt_table内获取对应的元素的信息应该先从idt_table全局变量中获取idt_table的基地址,然后获取gate_struct结构体的偏移值,根据偏移值来显示不同是数组信息。

当获取到基地址以后,应该根据此地址从gate_struct结构体内获取信息,我们要输出的信息有中断向量号、门描述符、函数地址、函数名;中断向量号只需要顺序向下排即可,门描述符则可以在idt_bits结构体内找到,函数地址由gate_struct结构体内的offset_low字段、offset_middle字段及offset_high字段组合而成,可以在Linux中通过[cat /proc/kallsyms | grep 函数名]来确认获取的函数地址是否正确,函数名则可以根据函数地址获取。

做循环,不断在基地址的基础上累加偏移地址,从而得到下一个数组元素所对应的地址,然后再利用此地址显示gate_struct结构体的信息,直至完部完成显示。

获取函数名示例:GetSymbol(函数地址[传入], 函数名[接受], 偏移值[接受])。

关于偏移值的说明:偏移值 = 函数实际地址 – 传入函数地址;因为即使传入一个不准确的地址,GetSymbol也会根据这个地址定位到附近的符号,从而获取函数名;如果你输入的是一个准确的函数地址,那么偏移值就会等于0。

GDK7 IDT

4.中断处理全局变量的获取

假如想要获取中断处理有关的全局变量(apic_idts、def_idts、early_idts、ist_idts、dbg_idts)的相关信息,那么我们首先知道这些全局变量在Linux内核中也被定义成了数组的形式,其数组所对应的均为idt_data结构体;因此想要显示中断处理有关全局变量的信息,也就是显示数组元素对应地址的idt_data结构体信息。

首先我们需要两个函数,一个显示idt_data结构体的信息,另一个做循环,接受全局变量名,并获取数组地址及数组个数,利用数组个数循环显示数组的不同元素的信息,当然是要传递地址给显示结构体的函数的。

需要注意的一点是,这些中断处理有关的全局变量只能在启动早期观察到,系统完成启动之后,便会释放这些全局变量;以后调试启动过程的时候,会再单独介绍。

static const __initconst struct idt_data apic_idts[]
static const __initconst struct idt_data def_idts[]
static const __initconst struct idt_data early_idts[]
static const __initconst struct idt_data ist_idts[]
static const __initconst struct idt_data dbg_idts[]
struct idt_data {
  unsigned int  vector;
  unsigned int  segment;
  struct idt_bits  bits;
  const void  *addr;
};

GDK7 IDT

5.!idt扩展命令的介绍

!idt扩展命令用于在Linux调试的时候,显示IDT中断描述符表内的相关信息。

!idt扩展命令格式:!idt [IDT的地址] [显示选项]

IDT的地址说明:

可以选择是否指定地址,若没有指定地址则地址会从Linux内核中的idt_table全局变量内获取IDT的基地址。

显示选项的含义:

-a:显示Idt表内全部的256个表项的相关信息。

-?:显示命令选项的说明。

空::没有指定显示选项,则只显示大于等于32且非空的表项。

盛格塾

正心诚意,格物致知

人文情怀审视软件,以软件技术改变人生

47e7dec13ed2e9ffae5679397d9c0288.png

c0e27f3d81c11ba2f718e370a78ece39.png

格友公众号

盛格塾小程序

扫描上方二维码或在微信中搜索“盛格塾”小程序

可以阅读更多文章和有声读物

文字:淳于智强

排版:韩俊

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值