我面临一些Linux内核代码的问题。我正在尝试使用linux下一个内核的CPU挂起功能(位于arch / arm / kernel / sleep.s中)
代码如下:
/ *\n\n *保存CPU状态以挂起。这节省了CPU通用\n\n *注册并在内核堆栈上分配空间以节省CPU\n\n *特定的寄存器和一些其他数据以供恢复。\n\n * r0 =暂停功能arg0\n\n * r1 =暂停功能\n\n * r2 =恢复CPU将使用的MPIDR值\n\n * /\n\nENTRY(__ cpu_suspend)\n\n stmfd sp !, {r4-r11,lr}\n\n#ifdef MULTI_CPU\n\n ldr r10,=处理器\n\n ldr r4,[r10,#CPU_SLEEP_SIZE] @ CPU睡眠状态的大小\n\n#其他\n\n ldr r4,= cpu_suspend_size\n\n#万一\n\n mov r5,sp @当前虚拟SP\n\n 添加r4,r4,#12 @ pgd,virt sp,phys简历的空间fn\n\n sub sp,sp,r4 @在堆栈上分配CPU状态\n\n ldr r3,= sleep_save_sp\n\n stmfd sp !, {r0,r1} @保存暂停函数arg和指针\n\n ldr r3,[r3,#SLEEP_SAVE_SP_VIRT]\n\n ALT_SMP(ldr r0,= mpidr_hash)\n\n ALT_UP_B(1f)\n\n / *此ldmia依赖于mpidr_hash结构的内存布局* /\n\n ldmia r0,{r1,r6-r8} @ r1 = Mpidr掩码(r6,r7,r8)= l [0,1,2]个移位\n\n compute_mpidr_hash r0,r6,r7,r8,r2,r1\n\n 加r3,r3,r0,lsl#2\n\n1:mov r2,r5 @虚拟SP\n\n mov r1,r4 @保存块的大小\n\n 添加r0,sp,#8 @指针以保存块\n\n bl __cpu_suspend_save\n\n adr lr,BSYM(cpu_suspend_abort)\n\n ldmfd sp !, {r0,pc} @调用暂停fn\n\nENDPROC(__ cpu_suspend)\n\n .ltorg\n\ncpu_suspend_abort:\n\n ldmia sp !, {r1-r3} @ pop phys pgd,virt SP,phys resume fn\n\n teq r0,#0\n\n moveq r0,#1 @强制非零值\n\n mov sp,r2\n\n ldmfd sp !, {r4-r11,pc}\n\nENDPROC(cpu_suspend_abort)\n该代码似乎遵循以下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缓存可能是原因? |