2、linux kernel arm64的中斷函式處理流程
1、linux kernel arm32的中斷函式處理流程
我們從irq_handler巨集函式看起
(1)、irq_handler巨集
注意config_multi_irq_handler巨集表示"允許每台機器在執行時指定它自己的irq處理程式",當前預設是不開啟的.
所以走else的arch_irq_handler_default邏輯
(2)、arch_irq_handler_default 巨集(arch/arm/kernel/entry-armv.s)
/* * interrupt handling.
*/.macro irq_handler
#ifdef config_multi_irq_handler
ldr r1,
=handle_arch_irq
mov r0, sp
badr lr,
9997f
ldr pc,
[r1]
#else
arch_irq_handler_default
#endif
9997
:.endm
arch_irq_handler_default 巨集 呼叫了asm_do_irq或do_ipi
(3)、呼叫了asm_do_irq(arch/arm/include/asr/entry-macro-multi.s)
/* * interrupt handling. preserves r7, r8, r9
*/.macro arch_irq_handler_default
get_irqnr_preamble r6, lr
1: get_irqnr_and_base r0, r2, r6, lr
movne r1, sp
@ @ routine called with r0 = irq number, r1 =
struct pt_regs *
@ badrne lr,
1b bne asm_do_irq
#ifdef config_smp
/* * ***
* * this macro assumes that irqstat (r2) and base (r6) are
* preserved from get_irqnr_and_base above
*/alt_smp
(test_for_ipi r0, r2, r6, lr)
alt_up_b
(9997f
) movne r1, sp
badrne lr,
1b bne do_ipi
#endif
9997
:.endm
asm_do_irq()—>handle_irq()—>__handle_domain_irq()—>generic_handle_irq()—>呼叫使用者request_irq註冊的中斷處理函式
void
handle_irq
(unsigned
int irq,
struct pt_regs *regs)
/*
* asm_do_irq is the inte***ce to be used from assembly code.
*/asmlinkage void __exception_irq_entry
asm_do_irq
(unsigned
int irq,
struct pt_regs *regs)
int
__handle_domain_irq
(struct irq_domain *domain,
unsigned
int hwirq,
bool lookup,
struct pt_regs *regs)
else
irq_exit()
;set_irq_regs
(old_regs)
;return ret;
}
(kernel/irq/irqdesc.c)
intgeneric_handle_irq
(unsigned
int irq)
export_symbol_gpl
(generic_handle_irq)
;
2、linux kernel arm64的中斷函式處理流程(kernel/include/linux/irqdesc.h)
static
inline
void
generic_handle_irq_desc
(struct irq_desc *desc)
我們依然從irq_handler巨集函式看起
(1)、irq_handler巨集 呼叫handle_arch_irq
(2)、handle_arch_irq(arch/arm/kernel/entry.s)
/* * interrupt handling.
*/.macro irq_handler
ldr_l x1, handle_arch_irq
mov x0, sp
irq_stack_entry
blr x1
irq_stack_exit
.endm
handle_arch_irq是在set_handle_irq()設定的handle位址
(3)、gic_handle_irq()void __init set_handle_irq
(void
(*handle_irq)
(struct pt_regs *))
在gic_of_init初始化的時候,將gic_handle_irq()位址賦給了handle_arch_irq
進入gic中的gic_handle_irq處理函式static
int __init gic_of_init
(struct device_node *node,
struct device_node *parent)
在這裡會呼叫handle_domain_irq函式或者handle_ipi函式
(4)、handle_domain_irq()---->__handle_domain_irq()---->generic_handle_irq()---->generic_handle_irq_desc()static asmlinkage void __exception_irq_entry gic_handle_irq
(struct pt_regs *regs)
else
}continue;}
if(irqnr <16)
}while
(irqnr != icc_iar1_el1_spurious)
;}
int
__handle_domain_irq
(struct irq_domain *domain,
unsigned
int hwirq,
bool lookup,
struct pt_regs *regs)
else
irq_exit()
;set_irq_regs
(old_regs)
;return ret;
}
int
generic_handle_irq
(unsigned
int irq)
export_symbol_gpl
(generic_handle_irq)
;static
inline
void
generic_handle_irq_desc
(struct irq_desc *desc)
Linux kernel的中斷子系統之(一) 綜述
一 前言 乙個合格的linux驅動工程師需要對kernel中的中斷子系統有深刻的理解,只有這樣,在寫具體driver的時候才能 1 正確的使用linux kernel提供的的api,例如最著名的request threaded irq request irq 介面 2 正確使用同步機制保護驅動 中的...
linux kernel中timer的使用
在kernel中如果想週期性的幹些什麼事情,或者某個特定時間幹些什麼事情,可以使用timer。例如像周期性地dump某段buffer的資料等等。先來看看使用方法。先定義乙個struct timer list的物件。eg struct timer list dump t 這個物件相當於乙個鬧鐘,其中包...
Linux kernel中module相關命令集
linux的kernel能夠以動態的方式載入,解除安裝模組,以達到減小核心的大小,複雜度,以及增加核心的靈活性。目前,我知道的有lsmod,insmod,rmmod,modprobe四條命令,現在分別總結記錄這四條命令,命令後的模組名稱均不加字尾 如.ko或.o 1 lsmod 即list modu...