Chinaunix首页 | 论坛 | 博客
  • 博客访问: 480551
  • 博文数量: 76
  • 博客积分: 5196
  • 博客等级: 大校
  • 技术积分: 1414
  • 用 户 组: 普通用户
  • 注册时间: 2007-10-10 18:43
个人简介

转了个圈,又回来了

文章分类

全部博文(76)

文章存档

2013年(1)

2011年(8)

2010年(9)

2009年(22)

2008年(36)

我的朋友

分类: LINUX

2011-04-05 20:31:13

由前面一篇文章可以知道,其实在中断来了以后,会调用IRQ对应的struct irqdesc->handle_irq函数,这个函数又是怎么来的呢。

这里分别从系统和用户的角度来描述Linux系统对中断的处里。

系统角度

1.       Trap_init

该函数是将系统的异常处理函数的入口地址搬移到对应的向量地址。该函数由start_kernel函数调用。

2.       Init_irq

这个函数也由start_kernel函数调用,该函数就是用来给各个IRQ对应的struct irqdesc结构体中的handler_irq来赋值的。

在我所在的源代码包中,init_irq函数又调用了init_arch_irq函数。那init_arch_irq函数又在哪里定义呢,实际上这个函数指正是在setup_arch(该函数同样被start_kernel函数调用)中赋值的

init_arch_irq = mdesc->init_irq;

 

再看mdesc

struct machine_desc *mdesc;

mdesc = setup_machine(machine_arch_type); ---------最后会调用__lookup_machine_type__lookup_machine_type 函数根据平台代号会找出预订义在(.arch.info)区中编译配置时确定的Linux系统所支持的各种ARM硬件平台描述结构struct machine_desc

 

.\arch\arm\mach-mx27目录下有

MACHINE_START(MX27_MDK27V0, "Morninghan i.MX27 MDK27V0")

        /* maintainer: Freescale Semiconductor, Inc. */

#ifdef CONFIG_SERIAL_8250_CONSOLE

        .phys_io        = CS5_BASE_ADDR,

        .io_pg_offst    = ((CS5_BASE_ADDR_VIRT) >> 18) & 0xfffc,

#else

        .phys_io        = AIPI_BASE_ADDR,

        .io_pg_offst    = ((AIPI_BASE_ADDR_VIRT) >> 18) & 0xfffc,

#endif

        .boot_params    = PHYS_OFFSET + 0x100,

        .fixup          = fixup_mxc_board,

        .map_io         = mxc_map_io,

        .init_irq       = mxc_init_irq,

        .init_machine   = mxc_board_init,

        .timer          = &mxc_timer,

MACHINE_END

 

其中

#define MACHINE_START(_type,_name)                            \

static const struct machine_desc __mach_desc_##_type      \

 __attribute_used__                                             \

 __attribute__((__section__(".arch.info.init"))) = {         \

.nr             = MACH_TYPE_##_type,                   \

.name                = _name,

 

#define MACHINE_END                               \

};

 

上面就是定义了该硬件平台的struct machine_desc结构体。其中就包括

.init_irq       = mxc_init_irq,也就是上面所说的mdesc->init_irq

 

再看mxc_init_irq -------set_irq_handler(i, do_level_IRQ);

 

do_level_IRQ  ------- handle_level_irq 这就调到了我们前面文章中提到的函数了。

 

   Linux系统对中断的软件处理就是这样的:

   首先需要将硬件平台的结构体struct machine_desc的成员init_irq赋值,并且将该结构体放到(.arch.info)区。然后的动作都在start_kernel函数里执行:

   Setup_arch:struct machine_desc中找出mxc_init_irq

   Trap_init: 搬移异常处理函数入口到中断向量表。

   Init_IRQ: 执行mxc_init_irq,为各个irq对应struct irqdesc结构体的handler_irq赋值。

 

用户角度

从用户的角度看,就是需要给各个irq对应的struct  irqdesc . action.handler赋值,就是实现各个中断具体的处理函数,这个过程是有request_irq函数实现的。

 

阅读(2337) | 评论(0) | 转发(0) |
给主人留下些什么吧!~~