Android 系统调用
来源:互联网 发布:算法设计与分析李春葆 编辑:程序博客网 时间:2024/06/05 22:32
为什么需要系统调用:
系统调用是用户态访问进入到内核态从而可以访问内核资源的一个桥梁。比如说在用户态可以调用getpid()这个系统调用来获取当前进程号,当前进程号是存在内核的task_struct结构体中的,只有内核态才能访问到。如果用户态试图访问内核地址空间将会产生一个段错误。
Android的系统调用:
首先内核需要实现好相应的系统调用号的处理函数。
在linux-syscall.h定义系统调用号
#define __NR_getpid (__NR_SYSCALL_BASE + 20)
在syscalls.txt生命要生成代码的系统调用汇编文件
# each non comment line has the following format:
# return_type func_name[:syscall_name[:call_id]]([parameter_list]) (#syscall_number|stub)
pid_t getpid () 20
通过gensyscalls.py产生汇编文件getpid.S,内容如下:
/* autogenerated by gensyscalls.py */
#include <sys/linux-syscalls.h>
.text
.type getpid, @function
.globl getpid
.align 4
getpid:
movl $__NR_getpid, %eax //将系统调用好保存到eax寄存器
int $0x80 //编程异常。陷入到内核态
cmpl $-129, %eax
jb 1f
negl %eax
pushl %eax
call __set_errno
addl $4, %esp
orl $-1, %eax
1:
ret
Linux内核处理流程:
在用户态执行了int $0x80之后,cpu产生了一个编程异常。Cpu的控制单元做了一系列的硬件处理之后,比如保存eflags,cs,eip,ss,esp寄存器,并载入新的值切换到内核态。然后cpu跳转到0x80相应的中断处理函数处执行。(硬件处理流程具体见深入理解linux内核的中断和异常的硬件处理)
内核的中断处理函数是:system_call
ENTRY(system_call)
RING0_INT_FRAME # can't unwind into user space anyway
pushl %eax # save orig_eax
CFI_ADJUST_CFA_OFFSET 4
SAVE_ALL #保存大多数寄存器的内容
GET_THREAD_INFO(%ebp)
# system call tracing in operation / emulation
testl $_TIF_WORK_SYSCALL_ENTRY,TI_flags(%ebp)
jnz syscall_trace_entry
cmpl $(nr_syscalls), %eax
jae syscall_badsys
syscall_call:
call *sys_call_table(,%eax,4) #调用相应系统调用号的处理函数
movl %eax,PT_EAX(%esp) # store the return value
syscall_exit: #退出系统调用
LOCKDEP_SYS_EXIT
DISABLE_INTERRUPTS(CLBR_ANY) # make sure we don't miss an interrupt
# setting need_resched or sigpending
# between sampling and the iret
TRACE_IRQS_OFF
movl TI_flags(%ebp), %ecx
testl $_TIF_ALLWORK_MASK, %ecx # current->work
jne syscall_exit_work
restore_all:
TRACE_IRQS_IRET
restore_all_notrace:
movl PT_EFLAGS(%esp), %eax # mix EFLAGS, SS and CS
# Warning: PT_OLDSS(%esp) contains the wrong/random values if we
# are returning to the kernel.
# See comments in process.c:copy_thread() for details.
movb PT_OLDSS(%esp), %ah
movb PT_CS(%esp), %al
andl $(X86_EFLAGS_VM | (SEGMENT_TI_MASK << 8) | SEGMENT_RPL_MASK), %eax
cmpl $((SEGMENT_LDT << 8) | USER_RPL), %eax
CFI_REMEMBER_STATE
je ldt_ss # returning to user-space with LDT SS
restore_nocheck:
RESTORE_REGS 4 # skip orig_eax/error_code
CFI_ADJUST_CFA_OFFSET -4
irq_return:
INTERRUPT_RETURN
- android 调用系统应用
- android 系统调用例子
- android调用系统应用
- Android调用系统照相机
- Android 系统调用
- Android调用系统程序
- android 调用系统应用
- android 调用系统应用
- Android 调用系统摄像头
- android调用系统应用
- Android调用系统程序
- android 调用系统设置
- Android系统调用
- android调用系统程序
- android调用系统程序
- 常用Android系统调用
- Android 调用系统应用
- android调用系统功能
- sysklogd
- IOS中输入框被软键盘遮挡的解决办法
- 使用JDK发布一个简单WebService
- 线性规划与网络流24题索引
- ubuntu10.10 配置swap交换分区大小
- Android 系统调用
- 动态解析xml
- Dalvik opcodes
- WebBrowser.Document.ExecCommand 指令集
- 多个Acitivty跳转与传值
- ProgressDialog的用法示例
- 线性规划与网络流24题 1飞行员配对方案问题
- 从淘宝数据结构来看电子商务中商品属性设计
- 如何向开源社区提问题