我正在写一个操作系统...我正在研究上下文切换..我可以将内核切换到用户程序,然后再返回。但是SVC调用似乎不能很好地工作。
syscall:
svc SYSCALL_SVC_NUMBER
bx lr当调用svc触发中断时,我可以看到控制流返回到内核。当它返回到用户程序时,硬故障出现了。
在这里--> bx lr
我已经检查了所有寄存器是否正确加载,除了xPSR缺少拇指位。这就是硬故障出现的原因。
但我不知道为什么xPSR是清楚的为零..。
.global activate
activate:
/* save kernel state in ip register */
mrs ip, psr
push {r4, r5, r6, r7, r8, r9, r10, r11, ip, lr}
/* switch to process stack */
msr psp, r0
mov ip, #2
msr control, ip
ldr ip, [sp, #0x38]
msr psr_nzcvq, ip
/* load user state */
pop {r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, lr}
add sp, #0x8
ldr ip, [sp, #-0x8]
/* this line can branch correctly */
bx ip发布于 2017-05-12 09:36:05
啊,是的,你是对的,但是你不需要同时修改任何东西。
以下面的代码为例
mov r1,#0x22
mov r2,#0x33
mov r3,#0x44
mov r0,#0x55
mov r12,r0
mov r0,#0x66
mov r14,r0
mov r0,#0x11
svc #1当堆栈命中svc处理程序时,它看起来像这样。
可以肯定的是,这是有文档记录的
20000FD4 FFFFFFF9 return address
20000FD8 00000011 r0
20000FDC 00000022 r1
20000FE0 00000033 r2
20000FE4 00000044 r3
20000FE8 00000055 r12
20000FEC 00000066 r14
20000FF0 0100009E r15
20000FF4 21000000 xPSR在cortex-m上的例外情况下,它们在硬件中的行为方式可以根据它们的调用约定直接调用C函数。了解程序计数器本身的lsbit为0,1的lsbit用于BX,BLX和POP,它被这些指令用来确定ARM或THUMB模式,该位被剥离,然后用作PC。
从SVC返回的结果可以/应该类似于上面的内容。如果您想使用svc或任何其他中断来执行上下文切换,则需要构建与之匹配的堆栈。
当然,对于每个线程,都存在一些先有鸡还是先有蛋的问题,您可以构建一个类似上面的堆栈映像
20000FD4 FFFFFFF9
20000FD8 00000011
20000FDC 00000022
20000FE0 00000033
20000FE4 00000044
20000FE8 00000055
20000FEC 00000066
20000FF0 01001234
20000FF4 21000000 但是你可以把“不关心”放在寄存器中,除了你设置为线程入口点的pc。未设置lsbit的情况下。此外,您还需要一些结构来保存其他寄存器的状态。
然后,当您进行上下文切换时,您将上述以外的寄存器保存在某个结构中,该结构包括sp,然后从下一个线程填充这些寄存器,包括它的sp。然后你bx lr返回。
除此之外,还有更多信息,请参阅atomthreads或chibios或其他开放源码的功能操作系统。
被中断的地址是正确的,或者在这种情况下,svc之后的地址,程序计数器,在没有设置lsbit的情况下位于堆栈上,但同时也是正确的。用于从异常(svc或计时器中断等)返回的实际lr是特殊的0xFFFxxxx,它设置了lsbit。
https://stackoverflow.com/questions/43916933
复制相似问题