我面临一些Linux内核代码的问题。我正在尝试使用linux下一个内核的CPU挂起功能(位于arch / arm / kernel / sleep.s中)
代码如下:
/ *
*保存CPU状态以挂起。这节省了CPU通用
*注册并在内核堆栈上分配空间以节省CPU
*特定的寄存器和一些其他数据以供恢复。
* r0 =暂停功能arg0
* r1 =暂停功能
* r2 =恢复CPU将使用的MPIDR值
* /
ENTRY(__ cpu_suspend)
stmfd sp !, {r4-r11,lr}
#ifdef MULTI_CPU
ldr r10,=处理器
ldr r4,[r10,#CPU_SLEEP_SIZE] @ CPU睡眠状态的大小
#其他
ldr r4,= cpu_suspend_size
#万一
mov r5,sp @当前虚拟SP
添加r4,r4,#12 @ pgd,virt sp,phys简历的空间fn
sub sp,sp,r4 @在堆栈上分配CPU状态
ldr r3,= sleep_save_sp
stmfd sp !, {r0,r1} @保存暂停函数arg和指针
ldr r3,[r3,#SLEEP_SAVE_SP_VIRT]
ALT_SMP(ldr r0,= mpidr_hash)
ALT_UP_B(1f)
/ *此ldmia依赖于mpidr_hash结构的内存布局* /
ldmia r0,{r1,r6-r8} @ r1 = Mpidr掩码(r6,r7,r8)= l [0,1,2]个移位
compute_mpidr_hash r0,r6,r7,r8,r2,r1
加r3,r3,r0,lsl#2
1:mov r2,r5 @虚拟SP
mov r1,r4 @保存块的大小
添加r0,sp,#8 @指针以保存块
bl __cpu_suspend_save
adr lr,BSYM(cpu_suspend_abort)
ldmfd sp !, {r0,pc} @调用暂停fn
ENDPROC(__ cpu_suspend)
.ltorg
cpu_suspend_abort:
ldmia sp !, {r1-r3} @ pop phys pgd,virt SP,phys resume fn
teq r0,#0
moveq r0,#1 @强制非零值
mov sp,r2
ldmfd sp !, {r4-r11,pc}
ENDPROC(cpu_suspend_abort)
该代码似乎遵循以下ARM文档中描述的标准过程:
http://www.google.fr/url?sa=t... AFQjCNEVnPO_e_2aYi2Q_4BMthr1Bp-AtA&sig2 = NGAYgxTY_MIB1qA3_zeBcA&bvm = bv.72185853,d.d2k
我对ARM汇编不是很熟悉,但是我知道代码将寄存器状态保存在堆栈中,然后进入子例程cpu_suspend_save刷新L1和L2高速缓存。
当程序进入__cpu_suspend保存函数时,CPU迷失在其中,这会导致内核崩溃。您看到这种事情的原因了吗?刷新L1和L2缓存可能是原因?