This is an assembly code from linux arm64 (arch/arm64/kernel/head.S).(kernel source 5.4.21)

```
__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

```

I'll try to explain it and someone please give me light and correct me if I'm wrong.

* line 1 : x4 = (page address of init\_thread\_union). I found init\_thread\_union is a variable in the kernel linkerscript.(arch/arm64/kernel/vmlinux.lds). this vmlinux.lds is genearted from vmlinux.lds.S during kernel building.
* line 2 : sp = (x4 + #THREAD\_SIZE). looks like setting the stack pointer for this thread. (and looks like this thread is using init\_thread\_union memory region) (to use 4K bytes from location of init\_thread\_union as stack for this thread)
* line 3 : x5 = (address of init\_task struct), I found init\_task is a task\_struct for init task.(in init/init\_task.c). so this struct contains thread info.
* line 4 : sp\_el0 = x5. why set the stack pointer of exception level 0 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 in line 2 means sp\_el1). and x5 is later used in line 10.

I can't understand exactly what this code is doing. especially line 4. What is this code doing?