操作系统为在用户态运行的进程与硬件设备进行交互,提供操作系统的系统服务,提供了一组接口。在应用程序和硬件之间,提供内核的系统-服务设置一个额外层具有很多最优点。
首先,这使得编程更加容易,把用户从学习硬件设备的低级编程特性中解放出来。
其次,这极大地提高了系统的安全性,因为内核在试图满足某个请求之前在接口级就可以检查这种请求的正确性。
最后,更重要的是这些接口使得程序具有可移植性,因为只要内核所提供的一组接口相同,那么在任一内核之上就可以正确地编译和执行程序。
1.libc库调用swi指令后,首先汇编指令执行如下:
swi #val发生了什么呢?
ENTRY(vector_swi)
/*1.保存现场。r0-r12,cpsr*/
sub sp, sp, #S_FRAME_SIZE
stmia sp, {r0 - r12} @ Calling r0 - r12
add r8, sp, #S_PC
stmdb r8, {sp, lr}^ @ Calling sp, lr
mrs r8, spsr @ called from non-FIQ mode, so ok.
str lr, [sp, #S_PC] @ Save calling PC
str r8, [sp, #S_PSR] @ Save CPSR
str r0, [sp, #S_OLD_R0] @ Save OLD_R0
zero_fp
/*2.检测swi指令是否符合规范(见下图)scno为sw指令机器码*/
ldr scno, [lr, #-4] @ get SWI instruction
A710( and ip, scno, #0x0f000000 @ check for SWI )
A710( teq ip, #0x0f000000 )
A710( bne .Larm710bug
/*3.找到存放swi 函数指针数组*/
enable_irq
get_thread_info tsk
adr tbl, sys_call_table @ load syscall table pointer
ldr ip, [tsk, #TI_FLAGS] @ check for syscall tracing
/*4.获取数组#val(清除高8位)*/
bic scno, scno, #0xff000000 @ mask off SWI op-code
eor scno, scno, #__NR_SYSCALL_BASE @ check OS number
/*5.根据scno和table找到table[scno]对应的函数指针*/
cmp scno, #NR_syscalls @ check upper syscall limit
adr lr, ret_fast_syscall @ return address
ldrcc pc, [tbl, scno, lsl #2] @ call sys_* routine
swi指令规范:
2.数组列表
call.S中:
.type sys_call_table, #object
ENTRY(sys_call_table)
#include "calls.S"
#undef ABI
#undef OBSOLETE
/**********************************************************/
/* 0 */ CALL(sys_restart_syscall)
CALL(sys_exit)
CALL(sys_fork_wrapper)
CALL(sys_read)
CALL(sys_write)
/* 5 */ CALL(sys_open)
3.找到对应函数指针:
asmlinkage ssize_t sys_write(unsigned int fd, const char __user * buf, size_t count)
进行调用
参考