X86 的IDT and in Linux

X86在32bit保护模式和64bit的长模式下的中断处理依靠IDT,中断描述符表。

这个表是X86众多描述符表的一个,每一个表项都是一个中断门/陷阱门/任务门描述符,用来描述该表项对应的中断向量的处理。每个表项长度8Byte。

X86一共有256个向量,其中包括了中断和异常。前32个向量是X86体系架构预先定义好的,都有明确的含义,例如,向量2预留给NMI,向量14用于Page Fault,向量18预留给Machine Check异常等等。

IDT的操作需要依靠IDTR寄存器和两个指令(LIDT/SIDT),关系图请参考SDM 图6-1。

除了前32个预留的向量,其余的向量都是怎么用的呢?这个会根据系统不同而不同,例如Linux之前的系统调用是通过INT 80H来完成的,因此可以判断在向量0x80对应的描述符一定是指向了系统调用的入口。

下面就是在Linux-3.2.33系统当中dump出来部分的IDT表项。

(E4)[ 74895.380487] -------- test start ---------

(E4)[ 74895.380493] XXXXXXX idt.address = 0x8169e000,idt.size=0xfff. Gate Size=0x10

(E4)[ 74895.380495] === 0x00: ffffffff8169e000 ===

(E4)[ 74895.380497] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF8138FE40. (divide_error+0x0/0x20)

(E4)[ 74895.380509] === 0x01: ffffffff8169e010 ===

(E4)[ 74895.380511] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF81387D70. (debug+0x0/0x40)

(E4)[ 74895.380518] === 0x02: ffffffff8169e020 ===

(E4)[ 74895.380520] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF813880B0. (nmi+0x0/0x20)

(E4)[ 74895.380525] === 0x03: ffffffff8169e030 ===

(E4)[ 74895.380526] Interrupt gate. Present: 001. DPL: 003.Offset = 0xFFFFFFFF81387DB0. (int3+0x0/0x40)

(E4)[ 74895.380531] === 0x04: ffffffff8169e040 ===

(E4)[ 74895.380533] Interrupt gate. Present: 001. DPL: 003.Offset = 0xFFFFFFFF8138FE60. (overflow+0x0/0x20)

(E4)[ 74895.380538] === 0x05: ffffffff8169e050 ===

(E4)[ 74895.380539] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF8138FE80. (bounds+0x0/0x20)

(E4)[ 74895.380544] === 0x06: ffffffff8169e060 ===

(E4)[ 74895.380545] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF8138FEA0. (invalid_op+0x0/0x20)

(E4)[ 74895.380550] === 0x07: ffffffff8169e070 ===

(E4)[ 74895.380552] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF8138FEC0. (device_not_available+0x0/0x20)

(E4)[ 74895.380557] === 0x08: ffffffff8169e080 ===

(E4)[ 74895.380558] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF8138FEE0. (double_fault+0x0/0x30)

(E4)[ 74895.380563] === 0x09: ffffffff8169e090 ===

(E4)[ 74895.380564] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF8138FF10. (coprocessor_segment_overrun+0x0/0x20)

(E4)[ 74895.380570] === 0x0a: ffffffff8169e0a0 ===

(E4)[ 74895.380571] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF8138FF30. (invalid_TSS+0x0/0x30)

(E4)[ 74895.380576] === 0x0b: ffffffff8169e0b0 ===

(E4)[ 74895.380577] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF8138FF60. (segment_not_present+0x0/0x30)

(E4)[ 74895.380582] === 0x0c: ffffffff8169e0c0 ===

(E4)[ 74895.380584] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF81387DF0. (stack_segment+0x0/0x30)

(E4)[ 74895.380589] === 0x0d: ffffffff8169e0d0 ===

(E4)[ 74895.380590] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF81387E20. (general_protection+0x0/0x30)

(E4)[ 74895.380595] === 0x0e: ffffffff8169e0e0 ===

(E4)[ 74895.380596] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF81387E50. (page_fault+0x0/0x30)

(E4)[ 74895.380602] === 0x0f: ffffffff8169e0f0 ===

(E4)[ 74895.380603] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF8138FF90. (spurious_interrupt_bug+0x0/0x20)

(E4)[ 74895.380608] === 0x10: ffffffff8169e100 ===

(E4)[ 74895.380610] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF8138FFB0. (coprocessor_error+0x0/0x20)

(E4)[ 74895.380615] === 0x11: ffffffff8169e110 ===

(E4)[ 74895.380616] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF8138FFD0. (alignment_check+0x0/0x30)

(E4)[ 74895.380621] === 0x12: ffffffff8169e120 ===

(E4)[ 74895.380622] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF81387E80. (machine_check+0x0/0x20)

(E4)[ 74895.380627] === 0x13: ffffffff8169e130 ===

(E4)[ 74895.380629] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF81390000. (simd_coprocessor_error+0x0/0x20)

(E4)[ 74895.380634] === 0x14: ffffffff8169e140 ===

(E4)[ 74895.380635] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF815DA0C8. (early_idt_handlers+0xc8/0x140)

(E4)[ 74895.380645] === 0x15: ffffffff8169e150 ===

(E4)[ 74895.380647] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF815DA0D2. (early_idt_handlers+0xd2/0x140)

(E4)[ 74895.380652] === 0x16: ffffffff8169e160 ===

(E4)[ 74895.380654] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF815DA0DC. (early_idt_handlers+0xdc/0x140)

(E4)[ 74895.380659] === 0x17: ffffffff8169e170 ===

(E4)[ 74895.380661] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF815DA0E6. (early_idt_handlers+0xe6/0x140)

(E4)[ 74895.380666] === 0x18: ffffffff8169e180 ===

(E4)[ 74895.380667] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF815DA0F0. (early_idt_handlers+0xf0/0x140)

(E4)[ 74895.380673] === 0x19: ffffffff8169e190 ===

(E4)[ 74895.380674] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF815DA0FA. (early_idt_handlers+0xfa/0x140)

(E4)[ 74895.380680] === 0x1a: ffffffff8169e1a0 ===

(E4)[ 74895.380681] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF815DA104. (early_idt_handlers+0x104/0x140)

(E4)[ 74895.380687] === 0x1b: ffffffff8169e1b0 ===

(E4)[ 74895.380688] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF815DA10E. (early_idt_handlers+0x10e/0x140)

(E4)[ 74895.380694] === 0x1c: ffffffff8169e1c0 ===

(E4)[ 74895.380695] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF815DA118. (early_idt_handlers+0x118/0x140)

(E4)[ 74895.380700] === 0x1d: ffffffff8169e1d0 ===

(E4)[ 74895.380702] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF815DA122. (early_idt_handlers+0x122/0x140)

(E4)[ 74895.380707] === 0x1e: ffffffff8169e1e0 ===

(E4)[ 74895.380708] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF815DA12C. (early_idt_handlers+0x12c/0x140)

(E4)[ 74895.380714] === 0x1f: ffffffff8169e1f0 ===

(E4)[ 74895.380715] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF815DA136. (early_idt_handlers+0x136/0x140)

(E4)[ 74895.380721] === 0x20: ffffffff8169e200 ===

(E4)[ 74895.380722] Interrupt gate. Present: 001. DPL: 000.Offset = 0xFFFFFFFF8138EB00. (irq_move_cleanup_interrupt+0x0/0x70)

。。。。

(E4)[ 74895.381495] === 0x80: ffffffff8169e800 ===

(E4)[ 74895.381498] Interrupt gate. Present: 001. DPL: 003.Offset = 0xFFFFFFFF81390440. (ia32_syscall+0x0/0x50)

。。。。

(E4)[ 74895.382662] Interrupt gate. Present: 001. DPL: 000.

Offset = 0xFFFFFFFF8138FD60. (spurious_interrupt+0x0/0x70)

可见80H的IDT表项果然指向了ia32_syscall。Linux也是“诚不我欺也!”

X86的中断处理还是很复杂的,它涉及到了体系结构以及PIC(中断控制器)的进化。这里一句半句也说不明白,有机会再具体描述吧。有需要的还是读读SDM吧,里面应有尽有。

Linux里面可以查看特定中断发生的统计信息byreading /proc/interrupts。

从体系结构上来看,中断/异常处理最简单是PowerPC(PPC603E的核心)。它有256个中断向量,每个向量预留了0x100字节。reset向量是第一个,开始于0x100,上电初始化的代码就放在这里)。第二个向量开始于0x200,依此类推。

PowerPC预留了256字节给每一个中断向量,这是一个非常巧妙的而且简单直接的设计。对于简单的操作,256直接足够放下一个中断/异常处理函数。对于复杂的中断/异常处理,256字节也足够完成跳转操作。中断处理也是非常简洁。

而且PowerPC的通用寄存器有32个,因此ABI也是简单明了。它是big-endian的,寄存器的bit设置符合通常软件工程师的思维常理。

所以PowerPC是学习CPU相关的底层软件的好平台。

可惜现在PowerPC没落了。

为什么技术强的产品都没有坚持到最好,摄影界的Minolta,汽车里的雪铁龙,电脑里的DEC,软件里的Boland/Solaris……

唉,不说了。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 219,753评论 6 508
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 93,668评论 3 396
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 166,090评论 0 356
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 59,010评论 1 295
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 68,054评论 6 395
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,806评论 1 308
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,484评论 3 420
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,380评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,873评论 1 319
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 38,021评论 3 338
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 40,158评论 1 352
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,838评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,499评论 3 331
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 32,044评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 33,159评论 1 272
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,449评论 3 374
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 45,136评论 2 356