r8, #PSR_T_BIT ?38? ? movne? ? r10, #0? ? ? ? ? ? ? ? @ no thumb OABI emulation ?39? USER(? ? ldreq? ? r10, [lr, #-4]? ? ? ? )? ? @ get SWI instruction ?40 #else ?41? USER(? ? ldr? ? r10, [lr, #-4]? ? ? ? )? ? @ get SWI instruction ?42 #endif ?43? ARM_BE8(rev? ? r10, r10)? ? ? ? ? ? @ little endian instruction ?44 ?45 #elif defined(CONFIG_AEABI) ?46 ?47? ? /* ?48? ? ? * 我们主要看这里,EABI将系统调用号保存在r7中 ?49? ? ? */ ?50 #elif defined(CONFIG_ARM_THUMB) ?51? ? /* 先判断是否为THUMB模式 */ ?52? ? tst? ? r8, #PSR_T_BIT? ? ? ? ? ? ?53? ? addne? ? scno, r7, #__NR_SYSCALL_BASE? ? ?54? USER(? ? ldreq? ? scno, [lr, #-4]? ? ? ? ) ?55 ?56 #else ?57? ? /* EABI模式 */ ?58? USER(? ? ldr? ? scno, [lr, #-4]? ? ? ? )? ? @ 获取系统调用号 ?59 #endif ?60 ?61? ? adr? ? tbl, sys_call_table? ? ? ? @ tbl为r8,这里是将sys_call_table的地址(相对于此指令的偏移量)存入r8 ?62 ?63 #if defined(CONFIG_OABI_COMPAT) ?64? ? /* ?65? ? ? * 在EABI体系中,如果swi跟着的立即数为0,这段代码不做处理,而如果是old abi体系,则根据系统调用号调用old abi体系的系统调用表(sys_oabi_call_table) ?66? ? ? * 其实说白了,在EABI体系中,系统调用时使用swi 0x0进行软中断,r7寄存器保存系统调用号 ?67? ? ? * 而old abi体系中,是通过swi (系统调用号|magic)进行调用的 ?68? ? ? */ ?69? ? bics? ? r10, r10, #0xff000000 ?70? ? eorne? ? scno, r10, #__NR_OABI_SYSCALL_BASE ?71? ? ldrne? ? tbl, =sys_oabi_call_table ?72 #elif !defined(CONFIG_AEABI) ?73? ? bic? ? scno, scno, #0xff000000? ? ? ? ?74? ? eor? ? scno, scno, #__NR_SYSCALL_BASE? ? ?75 #endif ?76 ?77 local_restart: ?78? ? ldr? ? r10, [tsk, #TI_FLAGS]? ? ? ? @ 检查系统调用跟踪 ?79? ? stmdb? ? {r4, r5}? ? ? ? ? ? @ 将第5和第6个参数压入栈 ?80 ?81? ? tst? ? r10, #_TIF_SYSCALL_WORK? ? ? ? @ 判断是否在跟踪系统调用 ?82? ? bne? ? __sys_trace ?83 ?84? ? cmp? ? scno, #NR_syscalls? ? ? ? @ 检测系统调用号是否在范围内,NR_syscalls保存系统调用总数 ?85? ? adr? ? lr, BSYM(ret_fast_syscall)? ? @ 将返回地址保存到lr寄存器中,lr寄存器是用于函数返回的。 ?86? ? ldrcc? ? pc, [tbl, scno, lsl #2]? ? ? ? @ 调用相应系统调用例程,tbl(r8)保存着系统调用表(sys_call_table)地址,scno(r7)保存着系统调用号120,这里就转到相应的处理例程上了。 ?87 ?88? ? add? ? r1, sp, #S_OFF ?89 2:? ? cmp? ? scno, #(__ARM_NR_BASE - __NR_SYSCALL_BASE) ?90? ? eor? ? r0, scno, #__NR_SYSCALL_BASE? ? @ put OS number back ?91? ? bcs? ? arm_syscall ?92? ? mov? ? why, #0? ? ? ? ? ? ? ? @ no longer a real syscall ?93? ? b? ? sys_ni_syscall? ? ? ? ? ? @ not private func ?94 ?95 #if defined(CONFIG_OABI_COMPAT) || !defined(CONFIG_AEABI) ?96? ? /* ?97? ? ? * We failed to handle a fault trying to access the page ?98? ? ? * containing the swi instruction, but we're not really in a ?99? ? ? * position to return -EFAULT. Instead, return back to the 100? ? ? * instruction and re-enter the user fault handling path trying 101? ? ? * to page it in. This will likely result in sending SEGV to the 102? ? ? * current task. 103? ? ? */ 104 9001: 105? ? sub? ? lr, lr, #4 106? ? str? ? lr, [sp, #S_PC] 107? ? b? ? ret_fast_syscall 108 #endif 109 ENDPROC(vector_swi)? ? ? ? ? ? @ 返回
?
?
? ? 好的,终于跳转到了系统调用表,现在我们看看系统调用表是怎么样的一个形式
?
?1 /* 文件地址: linux内核目录/arch/arm/kernel/calls.S */ ?2 ?3 /* 0 */? ? ? ? CALL(sys_restart_syscall) ?4? ? ? ? CALL(sys_exit) ?5? ? ? ? CALL(sys_fork) ?6? ? ? ? CALL(sys_read) ?7? ? ? ? CALL(sys_write) ?8 /* 5 */? ? ? ? CALL(sys_open) ?9? ? ? ? CALL(sys_close) 10? ? ? ? CALL(sys_ni_syscall)? ? ? ? /* was sys_waitpid */ 11? ? ? ? CALL(sys_creat) 12? ? ? ? CALL(sys_link) 13 /* 10 */? ? CALL(sys_unlink) 14? ? ? ? CALL(sys_execve) 15? ? ? ? CALL(sys_chdir) 16? ? ? ? CALL(OBSOLETE(sys_time))? ? /* used by libc4 */ 17? ? ? ? CALL(sys_mknod) 18 /* 15 */? ? CALL(sys_chmod) 19? ? ? ? CALL(sys_lchown16) 20? ? ? ? CALL(sys_ni_syscall)? ? ? ? /* was sys_break */ 21? ? ? ? CALL(sys_ni_syscall)? ? ? ? /* was sys_stat */ 22? ? ? ? CALL(sys_lseek) 23 /* 20 */? ? CALL(sys_getpid) 24? ? ? ? CALL(sys_mount) 25? ? ? ? CALL(OBSOLETE(sys_oldumount))? ? /* used by libc4 */ 26? ? ? ? CALL(sys_ |