question about arm64 __primary_switched code
Hello, I have put a question on stackoverflow but nobody answers there yet. I'll grateful if someone gives me some comments or answers. (it's about understanding arm64 assembly code) https://stackoverflow.com/questions/65051120/understanding-arm64-assembly-ad r-l-ldr-l-str-l-in-a-linux-kernel-code?noredirect=1#comment115012976_6505112 0 Thank you. Chan
On Sun, Nov 29, 2020 at 7:52 PM <ckim@etri.re.kr> wrote:
I’ll grateful if someone gives me some comments or answers. (it’s about understanding arm64 assembly code)
https://stackoverflow.com/questions/65051120/understanding-arm64-assembly-ad...
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.
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) __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 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/vmlinux.lds.S). 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@gmail.com> Sent: Monday, November 30, 2020 9:13 AM To: ckim@etri.re.kr Cc: kernelnewbies <kernelnewbies@kernelnewbies.org> Subject: Re: question about arm64 __primary_switched code
On Sun, Nov 29, 2020 at 7:52 PM <ckim@etri.re.kr> wrote:
I’ll grateful if someone gives me some comments or answers. (it’s about understanding arm64 assembly code)
https://stackoverflow.com/questions/65051120/understanding-arm64-assem 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.
On Mon, Nov 30, 2020 at 10:08 AM <ckim@etri.re.kr> 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.
participants (2)
-
ckim@etri.re.kr -
Wonhyuk Yang