Linux 时钟中断处理(一)

最近想研究下Linux下的时钟中断,因为时钟中断算是一个操作系统下最频繁的中断事件了吧(个人认为)。

以4.5 x86_64 Linux内核为例。

面对庞大的代码量,无从下手啊。不如从中断号看起吧微笑Linux 源码中有这样的定义(arch/x86/include/asm/irq_vectors.h):

#define LOCAL_TIMER_VECTOR              0xef

如果没猜错的话,应该就是Linux下的时钟中断向量了(0xEF=239)。为了保险起见,验证一下吧,不过该怎么验证呢?参考CPU硬件的中断处理过程,可按如下方法找到239号中断的处理函数入口地址:

    1)先通过idtr寄存器,找到IDT(中断描述符表)的地址(线性地址),然后读取该描述符表的第239个entry。

idtr和中断描述符表IDT中entry的格式分别如下:

                                         IDTR

Offset Size Description
0 2 Limit - Maximum addressable byte in table
2 8 Offset - Linear (paged) base address of IDT


IDT Descriptor
Offset Size Description
0 2 Offset low bits (0..15)
2 2 Selector (Code segment selector)
4 1 Zero
5 1 Type and Attributes (same as before)
6 2 Offset middle bits (16..31)
8 4 Offset high bits (32..63)
12 4 Zero


    2)从 IDT Descriptor 中提取出 Segment selector和Offset。

    3)根据gdtr寄存器找到GDT的地址,再结合第2步中的段选择符,找到相应的段描述符。

    4)从段描述符中提取基地址,再结合第2步中的Offset,便得到中断处理函数入口的线性地址。

需要注意的是,在64位模式中,AMD64的技术手册上有这样的描述:

Segmentation is disabled in 64-bit mode, and code segments span all of virtual memory. In this mode, code-segment base addresses are ignored. For the purpose of
virtual-address calculations, the base address is treated as if it has a value of zero.

原来,在64位系统中,早就不使用代码段和数据段的概念了(不过有些段还是在用的,例如TSS段),逻辑地址直接等于线性地址。因此以上步骤中的3、 4都是不必要的。只要从IDT descriptor中提取出 Offset,这便是中断处理函数的入口地址了(线性地址)。

下面来看看实际是怎么操作的吧:

    1)读取idtr寄存器。额。。。得需要内嵌汇编了,本人不是很熟,写了下面很ugly的几句代码吐舌头

#include <stdio.h>

struct idtr
{
        unsigned char byte[10];
};

int main(int argc, char* argv[])
{
        struct idtr idtr;
        int i;

        __asm__ __volatile__ ("SIDT %0" : "=m"(idtr) );
        for (i = 0; i < 10; i++)
                printf("byte %02d: 0x%hhx\n", i, idtr.byte[i]);

        return 0;
}
结果如下:
  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值