您的位置:首页 > 移动开发 > Android开发

Android系统调用流程---以open为例

2015-03-06 17:06 387 查看

Android系统调用流程---以open为例

在bionic\libc\unistd\open.c中,有用户空间的open系统调用函数,如下:
int open(const char *pathname, int flags, ...)
return__open(pathname, flags, mode);
可见调用到了 __open函数。

那我们接着去找__open函数:
在 bionic\libc\arch-arm\syscall有文件:__open.S
/*autogenerated by gensyscalls.py */
#include<machine/asm.h>
#include<sys/linux-syscalls.h>
ENTRY(__open)
.save {r4, r7}
stmfd sp!, {r4, r7}
ldr r7, =__NR_open
swi #0
ldmfd sp!, {r4, r7}
movs r0, r0
bxpl lr
b __set_syscall_errno
END(__open)

那么,貌似看到定义的地方了,到底是怎么去找到这个实现函数的呢?看看.mk文件吧。
bionic\libc的 Android.mk
里面有:
include$(LOCAL_PATH)/arch-$(TARGET_ARCH)/syscalls.mk
libc_common_src_files:= \
$(syscall_src)\
去找找syscall_src,在\bionic\libc\arch-arm里面有syscalls.mk:
syscall_src:=

syscall_src+= arch-arm/syscalls/_exit.S
......
syscall_src+= arch-arm/syscalls/__open.S
......

所以,我们看到了open函数如何找到了__open(就在__open.S里面)。

好了,我们跟踪到了__open代码,里面最重要的还是下面两句:
ldr r7, =__NR_open //把系统调用号 __NR_open
()保存到r7寄存器里。
//值为:#define __NR_open (__NR_SYSCALL_BASE+ 5)
swi #0
//触发软中断,并且由此进入内核模式

为了能够继续跟踪,必须对arm指令---swi进行了解,简述如下:
swi,软中断指令,把系统从用户模式切换到内核模式(修改CSPR寄存器状态),并执行到指定地址(0x08)---swi中断处理函数,我们在entry-common.S中,可以看到
* SWI handler

ENTRY(vector_swi)
......

一切尽在 vector_swi
中!
在新的模式EABI中(有别于老的OABI),有:
addne scno, r7, #__NR_SYSCALL_BASE@ put OS numberin
ldreq scno, [lr, #-4]
......
bic scno, scno, #0xff000000@ mask off SWI op-code//把32位里面的高8位屏蔽,取后24位
eor scno, scno, #__NR_SYSCALL_BASE@ check OSnumber //与__NR_SYSCALL_BASE异或
......
cmp scno,#NR_syscalls@ check upper syscall limit //判断获取到的scno是否越界
adr lr,BSYM(ret_fast_syscall)@ return address
ldrcc pc,[tbl, scno, lsl #2]@ call sys_* routine //若落在正常系统调用范围内,则调用对应的系统调用例程
......异常情况处理......

在entry-common.S给出了sys_call_table的位置:
ENTRY(sys_call_table)
#include"calls.S"

再去看看calls.S:
* Thisfile is included thrice in entry-common.S
*/
.......
/* 5*/CALL(sys_open)
可以看到,终于找到了open系统调用对应的处理函数。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: