《ARM与Linux些许问题》第四章:ARM平台系统调用原理分析
注意:不是系统调用服务程序本身。
即:系统命令——>用户编程API——>系统调用(调用SWI汇编指令异常)——>系统调用处理函数(vector_SWI)——>具体的系统调用服务程序。其中蓝色部分是内核态函数。
2.所有的用户空间系统调用函数都是通过调用SWI汇编指令(x86上int $0x80)异常、进入内核态,此时、ARM默认从某一固定地址执行程序(vector_SWI()(x86上system_call())的地址)。vector_SWI()(x86上system_call())这个内核函数又怎样分发这些系统调用到各自的内核服务程序中呢?Linux为每个系统调用都进行了编号(0——_NR_syscall);同时在内核中保存一张系统调用表,该表中保存了系统调用编号和其对应的服务例程。因此,在系统调用通过门陷入内核前,需要把系统调用号一并传入内核。这个传递工作是通过把系统调用号装入相应寄存器实现的。
有了如上的分析:系统调用处理程序vector_SWI()(x86上system_call())一旦运行;就可以从相应寄存器中得到数据,然后再去系统调用表中寻找相应的服务例程了。
注意:除了系统调用号之外,有的系统调用还需要传递一些参数给内核;这是Linux在vector_SWI()(x86上system_call())调用时将参数等值传入其他寄存器。
内核系统服务例程结束时,system_call()从相应寄存器中获得系统调用返回值,并把这个返回值放在曾保存用户态相应寄存器栈单元的那个位置;然后跳转到ret_from_sys_call(),终止系统调用处理程序的执行。
====================================================================================================================================五、主要路径
1.用户空间:libc库没有研究代码,大体机制如下——
调用SWI汇编指令(x86上int $0x80))软中断进入内核,并传入中断向量号相关中断向量号arm-2010.09/arm-none-linux-gnueabi/libc/usr/include/bits/syscall.h
#define SYS_getuid __NR_getuid2.内核空间:ARM中系统调用号定义路径:kernel2.6.35.11/arch/arm/include/asm/unistd.h
#define __NR_getuid (__NR_SYSCALL_BASE+ 24)
异常进入内核空间函数路径:kernel2.6.35.11/arch/arm/kernel/entry-common.s
默认执行vector_SWI(x86上system_call())函数
ARM中系统调用表定义路径:kernel2.6.35.11/arch/arm/kernel/calls.S
CALL(sys_getuid) //第24个,要与前面unistd中对应ARM中系统调用服务程序的声明路径:kernel2.6.35.11/include/linux/syscalls.h
asmlinkage long sys_getuid(void);
====================================================================================================================================x86平台相关路径(内核):
系统调用号路径——kernel2.6.35.11/arch/x86/include/asm/unistd.h
system_call()函数路径——kernel2.6.35.11/arch/x86/kernel/entry.S
系统调用表路径——kernel2.6.35.11/arch/x86/kernel/syscall_table.S或直接在entry.S中定义ARMLinux系统调用原 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)