This is difficult to track as some code is called through section magic and others via call backs and other mechanisms. Also, we have historic mechanisms and device tree initializationNote1.
There is a call back in init_irq
of the machine structure; these are typically defined in a board file. For example, imx6sl_init_irq()
calls irqchip_init()
from the machine description via the DT_MACHINE_START
macro which is a machine_desc in the .arch.info.init section. This code is called very early in boot and is required to get the IRQ hardware working; it typically include clocking mechanisms.
Linux supports several irqchip controllers. For instance, on some ARM systems there are multiple GIC chips. This is needed if there are more than ~1020 interrupt sources. As well, the GPIO hardware is often a sort of secondary IRQ chip that enables/disables GPIO interrupts.
A machine must declare the GIC in a device tree. This is matched versus a table entry in irq-gic.c which calls gic_of_init()
. The tables are use by the of_irq_init()
to initialize a GIC controller with hardware addresses and interrupt numbering. Ie, this takes the irq-gic driver and gives a concrete deviceNote2.
So now the code you found in start_kernel()
, which calls init_IRQ() should make sense? It will look like,
start_kernel ->
init_IRQ ->
machine_desc->init_irq (machine version)
irqchip_init ->
of_irq_init -> via *device tree* for address data
gic_of_init -> actual controller initialization.
The structure is all over the place because Linux is organized as sub-systems, so you have driver infrastructure (all need interrupts), device tree (to get the data), initialization and interrupt code (irqchip). The DT or device tree functionality is aimed at reducing the amount of board specific code in Linux. An example imx6 solo-lite device tree include shows how the data is coded. This text gets compiled to a flattened device tree binary which is passed from a boot loader (or attached to the image).
Note 1: Device tree is called by several names. OF for open firmware as per the original PowerPC spec. As FDT for 'flattened device tree', mostly by u-boot people. Also as just DT. So when you see one of the following prefixes, OF, DT, FDT it is often about 'device tree'.
Note 2: A device is a concrete piece of hardware. A driver is the code to handle the device. Linux allocates memory and provides this to driver code. In this way one piece of code can handle multiple devices (interrupt controllers in this case). It is an object oriented concept and ARM will handle it well with address+offset use of the load/store unit.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…