来定义的,
虽然cpsr的cpu模式根据低5位来定,但是可以根据低4位区分开,所以只用了低4位.
只算低4位,usr是0,svc是3.
stubs_offset被定义为:
.equ stubs_offset, __vectors_start + 0x200 - __stubs_start
调用early_trap_init之后,0xffff0000的内容为:
b vector_irq + stubs_offset
b vector_irq + __vectors_start + 0x200 - __stubs_start
该语句的意思是b到vector_irq加上偏移量stubs_offset.
该语句的作用就是跳到vector_irq这个标号.
在entry-armv.S中,__stubs_start和__stubs_end定义在__vectors_start的前面,
__stubs_start:
vector_irq:
......
__stubs_end:
__vectors_start:
......
b vector_irq + stubs_offset
__vectors_end:
以vector_irq为基点去算,先看成
b vector_irq
跳到了vector_irq标号处,再加上__vectors_start - __stubs_start,等于跳到了
__vectors_start处,再加上0x200,0x200开始的地方就是early_trap_init copy过去的
__stubs_start
...
__stubs_end
之间的内容.
b vector_dabt + stubs_offset
先跳到vector_dabt,加上__vectors_start - __stubs_start,如果__vectors_start处
也放有
__stubs_start
...
__stubs_end
那这时就跳到了__vectors_start处的vector_dabt,再加上0x200,0x200开始也是
__stubs_start
...
__stubs_end
所以跳到了正确的地址.
所有的系统调用接口都可以在arch\arm\kernel\call.S文件里边找到,
/* 0 */ CALL(sys_restart_syscall)
CALL(sys_exit)
CALL(sys_fork_wrapper)
CALL是宏,在arch\arm\kernel\entry-common.S文件里边定义,CALL被定义为两种情况.
第一次:
.equ NR_syscalls,0
#define CALL(x) .equ NR_syscalls,NR_syscalls+1
#include "calls.S"
#undef CALL
#define CALL(x) .long x
这里是为了计算有多少个NR_syscalls,后面重新定义CALL 为.long x
所有的系统调用号在arch\arm\include\asm\unistd.h中定义.
这里定义了系统调用表,所有的系统调用函数都在这表里边:
.type sys_call_table, #object
ENTRY(sys_call_table)
#include "calls.S"
#undef ABI
#undef OBSOLETE
这里取得系统调用号码:
#elif defined(CONFIG_ARM_THUMB)
/* Legacy ABI only, possibly thumb mode. */
tst r8, #PSR_T_BIT @ this is SPSR from save_user_regs
addne scno, r7, #__NR_SYSCALL_BASE @ put OS number in
ldreq scno, [lr, #-4]
#else
ne就是结果不为0,eq就是结果为0.
在arm模式下,第2条语句不执行,第三条语句从swi指令中取得系统调用号.
swi指令的低24位是系统调用号:
#elif !defined(CONFIG_AEABI)
bic scno, scno, #0xff000000 @ mask off SWI op-code
eor scno, scno, #__NR_SYSCALL_BASE @ check OS number
#endif
__NR_SYSCALL_BASE在 arch\arm\include\asm\unistd.h里边定义为0.
cmp scno, #NR_syscalls @ check upper syscall limit
adr lr, ret_fast_syscall @ return address
ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine
在这里跳到系统调用函数.