ARM-Linux s3c2440 之中斷分析(二)
上一篇文章回顧了s3c2440的中斷控制器原理的相關(guān)硬件知識,有了這個基礎(chǔ)再來分析Linux中的軟件分析方式,心里就有底了。面對浩瀚如海的Linux源代碼,s3c2440的中斷到底是怎樣呢,如何處理,如何實現(xiàn)的呢?一步一步來揭開它神秘的面紗吧,當然需要從Linux內(nèi)核源碼入手!
本文引用地址:http://www.ex-cimer.com/article/201611/318129.htm在Linux中start_kernel()時會進行體系結(jié)構(gòu)的初始化:init_IRQ(), 故名思議,其源代碼如下:
- 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();//這里是系統(tǒng)初始化irq的入口
- }
init_arch_irq()初始值為:void (*init_arch_irq)(void)__initdata = NULL; 相當于一個變量函數(shù)(函數(shù)就像變量一樣,被賦值),默認值為NULL,那么在其他地方應(yīng)該被再次賦值。其實在setup_arch()中init_arch_irq()已經(jīng)有所指向了,在arch/arm/kernel/setup.c中setup_arch進行體系平臺相關(guān)初始化:
- 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()指向的函數(shù)
- system_timer=mdesc->timer;
- init_machine=mdesc->init_machine;
- …
- early_trap_init()//初始化中斷向量表
- }
mdesc是一個struct machine_desc的數(shù)據(jù)結(jié)構(gòu),msdesc 通過 setup_machine(machine_arch_type) 獲取平臺體系的MACHINE_START相關(guān)參數(shù)。
- #defineMACHINE_START(_type,_name)
- staticconststructmachine_desc__mach_desc_##_type
- __used
- __attribute__((__section__(".arch.info.init")))={
- .nr=MACH_TYPE_##_type,
- .name=_name,
- #defineMACHINE_END
- };
這個參數(shù)如下:
- 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初始化函數(shù)
- .map_io=smdk2440_map_io,
- .init_machine=smdk2440_machine_init,
- .timer=&s3c24xx_timer,
- MACHINE_END
可見s3c24xx_init_irq()才是所要找得中斷初始化入口程序,所以執(zhí)行init_arch_irq()實際是執(zhí)行s3c24xx_init_irq()程序。中斷的初始化工作:首先,清空各interrupt pending的值,然后再向系統(tǒng)注冊主要的中斷,從上篇中我們知道s3c2440有60個中斷,但系統(tǒng)中主要用了58個中斷,
注冊中斷主要用下面三個函數(shù):
- intset_irq_chip(unsignedintirq,structirq_chip*chip)
- staticinlinevoidset_irq_handler(unsignedintirq,irq_flow_handler_thandle)
- staticinlinevoidset_irq_chained_handler(unsignedintirq,irq_flow_handler_thandle)
至此,中斷的初始化過程完成了,那么它是怎樣工作的,具體的流程由如何,各中斷函數(shù)的回調(diào)函數(shù)怎么理解,下文將繼續(xù)深入探討。。
評論