question about arm64 __primary_switched code

Wonhyuk Yang vvghjk1234 at
Mon Nov 30 00:48:51 EST 2020

On Mon, Nov 30, 2020 at 10:08 AM <ckim at> wrote:

>     __primary_switched:
>         adrp    x4, init_thread_union   -- line 1
>         add sp, x4, #THREAD_SIZE        -- line 2
>         adr_l   x5, init_task           -- line 3
>         msr sp_el0, x5          // Save thread_info   -- line 4
>         adr_l   x8, vectors         // load VBAR_EL1 with virtual  -- line5
>         msr vbar_el1, x8            // vector table address  -- line 6
>         isb                    -- line7
>         stp xzr, x30, [sp, #-16]!            -- line8
>         mov x29, sp                   -- line9
>         str_l   x21, __fdt_pointer, x5      // Save FDT pointer   -- line10
> line 2 : sp = (x4 + #THREAD_SIZE). looks like setting the stack pointer for the init thread info?

Yes. Setting the stack and it will be used for C code.

> line 4 : sp_el0 = x5.  why set the stack pointer of exeption level0 with the thread_info?

In early time sp_el0 is not used, so it used just for saving some values.

> and is this sp_el0 different from the sp in line 2? (I guess we are now in el 1, so sp means sp_el1 in line 2)

Yes it is different.

> line 5 : x8 = (address of trap vectors) I couldn't find where 'vectors' is defied in the kernel source.

You can find it in the entry.S.

> line 7 : instruction synch barrier. why is it needed here?

I find it was introduced Commit : 2bf31a4a05f5b. Sadly, I can't understand too.

> line 8 : store 0 to [sp - 16], and store x30 at [sp - 8]. I know x30 is used to keep the address to return after function(called function sets PC with x30). But here zero and x30 is saved in the stack. What is it doing here?
> line 9 : and frame pointer (x29) is set with sp. The stack address obtained in line 2 is set to x29. I think the this is the stack start for this frame and sp grows down as stack is used.

It seems like making stack frame. stp with "!" means the preindex.
stp xzr, x30, [sp, #-16]! is same as,

sp = sp - 0x16
*sp = xzr                  <- frame
*(sp+0x8) = x30       <- return

> line 10 : I know x21 was keeping the device tree address here, so here the address is stored in a global address __fdt_pointer for later use.  I guess str_l is store-relative-long but I can't figure out how x5(addr of init_task) is used here..

x5 is used as a temporary register.

More information about the Kernelnewbies mailing list