ARM-Linux s3c2440 之中断分析(二)
上一篇文章回顾了s3c2440的中断控制器原理的相关硬件知识,有了这个基础再来分析Linux中的软件分析方式,心里就有底了。面对浩瀚如海的Linux源代码,s3c2440的中断到底是怎样呢,如何处理,如何实现的呢?一步一步来揭开它神秘的面纱吧,当然需要从Linux内核源码入手!
在Linux中start_kernel()时会进行体系结构的初始化:init_IRQ(), 故名思议,其源代码如下:
[cpp]view plaincopy
- void__initinit_IRQ(void)
- {
- intirq;
- for(irq=0;irq
- irq_desc[irq].status|=IRQ_NOREQUEST|IRQ_NOPROBE;
- #ifdefCONFIG_SMP
- cpumask_setall(bad_irq_desc.affinity);
- bad_irq_desc.cpu=smp_processor_id();
- #endif
- init_arch_irq();//这里是系统初始化irq的入口
- }
init_arch_irq()初始值为:void (*init_arch_irq)(void)__initdata = NULL; 相当于一个变量函数(函数就像变量一样,被赋值),默认值为NULL,那么在其他地方应该被再次赋值。其实在setup_arch()中init_arch_irq()已经有所指向了,在arch/arm/kernel/setup.c中setup_arch进行体系平台相关初始化:
- void__initsetup_arch(char**cmdline_p)
- {
- structtag*tags=(structtag*)&init_tags;
- structmachine_desc*mdesc;
- char*from=default_command_line;
- unwind_init();
- setup_processor();
- mdesc=setup_machine(machine_arch_type);
- machine_name=mdesc->name;
- …
- cpu_init();
- …
- init_arch_irq=mdesc->init_irq;//这里是init_arch_irq()指向的函数
- system_timer=mdesc->timer;
- init_machine=mdesc->init_machine;
- …
- early_trap_init()//初始化中断向量表
- }
mdesc是一个struct machine_desc的数据结构,msdesc 通过 setup_machine(machine_arch_type) 获取平台体系的MACHINE_START相关参数。
- #defineMACHINE_START(_type,_name)\
- staticconststructmachine_desc__mach_desc_##_type\
- __used\
- __attribute__((__section__(".arch.info.init")))={\
- .nr=MACH_TYPE_##_type,\
- .name=_name,
- #defineMACHINE_END\
- };
这个参数如下:
- MACHINE_START(S3C2440,"SMDK2440")
- /*Maintainer:BenDooks
*/ - .phys_io=S3C2410_PA_UART,
- .io_pg_offst=(((u32)S3C24XX_VA_UART)>>18)&0xfffc,
- .boot_params=S3C2410_SDRAM_PA+0x100,
- .init_irq=s3c24xx_init_irq,//这里是目标CPU的irq初始化函数
- .map_io=smdk2440_map_io,
- .init_machine=smdk2440_machine_init,
- .timer=&s3c24xx_timer,
- MACHINE_END
可见s3c24xx_init_irq()才是所要找得中断初始化入口程序,所以执行init_arch_irq()实际是执行s3c24xx_init_irq()程序。中断的初始化工作:首先,清空各interrupt pending的值,然后再向系统注册主要的中断,从上篇中我们知道s3c2440有60个中断,但系统中主要用了58个中断,
注册中断主要用下面三个函数:
- intset_irq_chip(unsignedintirq,structirq_chip*chip)
- staticinlinevoidset_irq_handler(unsignedintirq,irq_flow_handler_thandle)
- staticinlinevoidset_irq_chained_handler(unsignedintirq,irq_flow_handler_thandle)
至此,中断的初始化过程完成了,那么它是怎样工作的,具体的流程由如何,各中断函数的回调函数怎么理解,下文将继续深入探讨。。
ARMLinuxs3c2440中断分 相关文章:
- ARM-Linux s3c2440 之中断分析(一)(11-19)
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)