KCall的实现
这个函数在内核中随处可见,它的实现是在armtrap.s中实现。
int KCall(PKFN pfn, ...);
其中
typedef int (*PKFN)();
这个函数是可变数量的参数。第一个参数是函数指针。第二个参数是不定参数。规定,对于可变参数个数的传递,参数在4个以内,分别用r0,r1,r2,r3。超过的部分就用堆栈传递。
KCall使pfn 在不可抢占的环境中运行,并在执行完之后,函数返回之前,如有需求,那么将有一次调度的机会。
KCall先将CPU切换到SVC mode,执行pfn,然后切换到system mode,检查需不需要调度。
如果需要调度,那么CPU再切回到SVC mode,并且关闭终端,跳转到SaveAndReschedule
ldr r3, =KData ; (r3) = ptr to KDataStruct
ldrb r12, [r3, #bResched] ; (r12) = reschedule flag
cmp r12, #1
其实这里就是检测struct KDataStruct 结构体的成员bResched,如果是1,那么标志需要调度。
用于准备thread的context,也就是填充struct Thread中的CPUCONTEXT ctx成员。它记录着CPU所有寄存器的内容,他们共同组成了thread context。之后进入FirstSchedule开始线程切换过程。