I am using Linux kernel 3.0.35 on Freescale i.MX6 (ARM Cortex-A9). After running into a kernel OOPS I tried to understand the exception stack initialization. Here is what I
tl;dr - We switch modes to supervisor and use that stack.
You are missing the key point of where control is handed to the CPU via the vector table and the mode is switched. See: entry-armv.S and __vectors_start. The vector stubs is the code where control is initially sent after the b
ranch in the main vector table. The vector_stub
macro saves three items; a corrected lr
, r0
and the spsr
of the excepted mode (as you noted).
The point you miss is, after this all exceptions switch to SVC_MODE
and as such use the current
tasks stack, which also has the thread_info
structure. mode switching is a tough concept to get in ARM system level assembler. Registers that were previously set are now completely different. Pay attention to msr
and cps
type instructions. Things can change completely after them; I have been confused by this dozens of times.
The spsr
is used as an index into a vector_stub
table, which will normally jump to either __irq_svc
or __irq_usr
. Just scroll down to look at the bottom of the entry-arm.S which you already found.
Related: Physical address of ARM-Linux vector table