question about arm64 __primary_switched code

ckim at ckim at
Sun Nov 29 20:08:23 EST 2020

Hi all,
My question on stackoverflow contained many questions so it was closed (I was going to split the questions).
Here I put the original question. I would be really grateful if someone gives me some clarification. Thanks!
There are too much to read but too small amount of time always.. so forgive me my asking without enough study.   
This is an assembly code from linux arm64 (arch/arm64/kernel/head.S).(kernel source 5.4.21)   

        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
I'll try to understand it here..(I have a book that may have some explanation for this part, but left it at work.. and I'm home now..)  
line 1 : x4 = (page address of init_thread_union). I found init_thread_union is a variable in the kernel linkerscrip.(arch/arm64/kernel/   
line 2 : sp = (x4 + #THREAD_SIZE). looks like setting the stack pointer for the init thread info?   
line 3 : x5 = (address of init_task), I found init_task is a task_struct for init task.(in init/init_task.c). so this is the thread info.   
line 4 : sp_el0 = x5.  why set the stack pointer of exeption level0 with the thread_info? 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)
line 5 : x8 = (address of trap vectors) I couldn't find where 'vectors' is defied in the kernel source.
line 6 : set the x8 value to vbar_el1 system register.  
line 7 : instruction synch barrier. why is it needed here?  
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.  
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..  
ah.. there are so many questions. Please someone give me the explanation or correct my understanding if I'm wrong.  

> -----Original Message-----
> From: Wonhyuk Yang <vvghjk1234 at>
> Sent: Monday, November 30, 2020 9:13 AM
> To: ckim at
> Cc: kernelnewbies <kernelnewbies at>
> Subject: Re: question about arm64 __primary_switched code
> On Sun, Nov 29, 2020 at 7:52 PM <ckim at> wrote:
> >
> > I’ll grateful if someone gives me some comments or answers. (it’s
> > about understanding arm64 assembly code)
> >
> >
> > bly-adr-l-ldr-l-str-l-in-a-linux-kernel-code?noredirect=1#comment11501
> > 2976_65051120
> >
> Hi,
> Your link doesn't work. Also, I think attaching the contents of the link
> to the mail will make it easier for others to see.

More information about the Kernelnewbies mailing list