如何理解__swtich“to”;用于ARM linux中的contex交换机
我试图了解linux的上下文切换是如何工作的,它是基于ARM的 所以我想了解以下代码 条目(切换到) 我知道这些代码用于存储当前进程的cpu上下文,并恢复下一个进程(即当前进程)的cpu上下文。但它不会保存和恢复ip、r1、r2、r3、r4,尤其是cpsr(当前程序状态寄存器) 我认为它应该为上下文切换保存和恢复cpsr寄存器。但它并没有在上面的代码中保存cpsr。我不明白。我为这个问题挣扎了一周。但是我找不到答案。如果有人能给我答案,我将不胜感激。这只是一个常规的函数调用。ABI不要求在函数调用期间保留r0-r3、r12或CPSR中的条件标志,因此它们不需要保存在调用任务的上下文中,因为它不关心它们最终被重新调度并在从如何理解__swtich“to”;用于ARM linux中的contex交换机,linux,arm,context-switch,Linux,Arm,Context Switch,我试图了解linux的上下文切换是如何工作的,它是基于ARM的 所以我想了解以下代码 条目(切换到) 我知道这些代码用于存储当前进程的cpu上下文,并恢复下一个进程(即当前进程)的cpu上下文。但它不会保存和恢复ip、r1、r2、r3、r4,尤其是cpsr(当前程序状态寄存器) 我认为它应该为上下文切换保存和恢复cpsr寄存器。但它并没有在上面的代码中保存cpsr。我不明白。我为这个问题挣扎了一周。但是我找不到答案。如果有人能给我答案,我将不胜感激。这只是一个常规的函数调用。ABI不要求在函数调
switch_to()
返回时再次拾取
关键是,thread\u info
中的cpu\u上下文
,即此处切换的内容,是最终调用\u schedule()
的内容的内核状态。实际(用户空间)进程状态*,即r0-r15、SPSR等,位于任务的pt_regs
——该状态在进入内核时立即保存(参见vector_swi
),并在退出时以您期望的方式恢复(ret_-u-user
)
*假设有一个,即调用上下文不是内核线程。当,它只是一个常规函数调用。ABI不要求在函数调用期间保留r0-r3、r12或CPSR中的条件标志,因此它们不需要保存在调用任务的上下文中,因为它不关心它们最终被重新调度并在从switch_to()
返回时再次拾取
关键是,thread\u info
中的cpu\u上下文
,即此处切换的内容,是最终调用\u schedule()
的内容的内核状态。实际(用户空间)进程状态*,即r0-r15、SPSR等,位于任务的pt_regs
——该状态在进入内核时立即保存(参见vector_swi
),并在退出时以您期望的方式恢复(ret_-u-user
)
*假设有一个,即调用上下文不是内核线程。ARM32有存储寄存器。异常输入时,
CPSR
保存到SPSR
,并通过异常返回进行恢复。我建议阅读架构参考手册以了解更多信息。“我认为它应该为上下文切换保存和恢复cpsr寄存器”-你为什么这么认为?这是切换任务的内核端上下文;谁能说它到底是不是一个用户线程呢?在内核中调用schedule()
的任何人都不会期望参数寄存器和条件标志被保留。听起来你可能把这与ret\u to\u user()
混为一谈。首先感谢你的评论。我不确定linux中是否只有用户进程。如果是这样,我认为不拯救cpsr是可以的。然后系统调用处理程序(svc处理程序)使用内核堆栈保存和恢复cpsr,如“ret_to_user”。但是,如果有多个内核进程,那么这些内核进程之间就存在上下文切换的情况。所以我认为它需要保存和恢复CPSR。您对此有何看法?除上述内容外,我认为CPSR需要在上下文切换之间保留。因为只有当CPSR中的条件代码标志满足指定的条件时,才会执行带有条件代码的ARM指令。ARM32具有存储寄存器。异常输入时,CPSR
保存到SPSR
,并通过异常返回进行恢复。我建议阅读架构参考手册以了解更多信息。“我认为它应该为上下文切换保存和恢复cpsr寄存器”-你为什么这么认为?这是切换任务的内核端上下文;谁能说它到底是不是一个用户线程呢?在内核中调用schedule()
的任何人都不会期望参数寄存器和条件标志被保留。听起来你可能把这与ret\u to\u user()
混为一谈。首先感谢你的评论。我不确定linux中是否只有用户进程。如果是这样,我认为不拯救cpsr是可以的。然后系统调用处理程序(svc处理程序)使用内核堆栈保存和恢复cpsr,如“ret_to_user”。但是,如果有多个内核进程,那么这些内核进程之间就存在上下文切换的情况。所以我认为它需要保存和恢复CPSR。您对此有何看法?除上述内容外,我认为CPSR需要在上下文切换之间保留。因为某些带有条件代码的ARM指令只有在CPSR中的条件代码标志满足指定条件时才会执行。再次感谢您的评论。我知道参数寄存器(R0~R3)和IP(R12)不需要保留。但我仍然不明白CPSR中的条件标志是否需要通过函数调用来保留,事实上,由于linux运行良好,CPSR不需要在上下文切换之间保留。我可能错了或者错过了什么。无论如何,我已经按照你的建议阅读了ABI文件。非常接近的评论是,“插入的任何单板必须保留除IP(r12)和条件代码标志外的所有寄存器的内容”,尽管参考了ABI文档,我仍然不理解。我试图拆开vmlinux。但我找不到答案。能够
add ip, r1, #TI_CPU_SAVE
ldr r3, [r2, #TI_TP_VALUE]
stmia ip!, {r4 - sl, fp, sp, lr} @ Store most regs on stack
ldr r6, [r2, #TI_CPU_DOMAIN]
strex r5, r4, [ip] @ Clear exclusive monitor
mcr p15, 0, r3, c13, c0, 3 @ set TLS register
mov r4, #0xffff0fff
str r3, [r4, #-15] @ TLS val at 0xffff0ff0
mcr p15, 0, r6, c3, c0, 0 @ Set domain register
mov r5, r0
add r4, r2, #TI_CPU_SAVE
ldr r0, =thread_notify_head
mov r1, #THREAD_NOTIFY_SWITCH
bl atomic_notifier_call_chain
mov r0, r5
ldmia r4, {r4 - sl, fp, sp, pc} @ Load all regs saved previously