WinCE5读核笔记(五) KCall的实现

 

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,那么标志需要调度。

SaveAndReschedule

用于准备thread的context,也就是填充struct Thread中的CPUCONTEXT ctx成员。它记录着CPU所有寄存器的内容,他们共同组成了thread context。之后进入FirstSchedule开始线程切换过程。

你可能感兴趣的:(WinCE5读核笔记(五) KCall的实现)