当前位置:早雪网网络学院编程文档C/C++ → linux系统调用实现代码分析

linux系统调用实现代码分析

减小字体 增大字体 作者:不详  来源:supcode.com收集整理  发布时间:2005-7-22 19:38:17
call的其他部分跳转过来。
ALIGN
.globl ret_from_sys_call
.globl ret_from_intr
ret_from_sys_call:
movl SYMBOL_NAME(bh_mask),%eax
andl SYMBOL_NAME(bh_active),%eax
jne handle_bottom_half
/*检测bottom half是否激活,如果激活,程序就跳转到handle_bottom_half执行,bottom half是中断进程的一部
分,以后再提及,中断进程我的概念也很模糊。*/
ret_with_reschedule:
cmpl $0,need_resched(%ebx)/*检查进程是否为再次调度做了标记*/
jne reschedule/*如果是,就跳转到reschedule*/
cmpl $0,sigpending(%ebx)/*检查是否还有挂起信号*/
jne signal_return/*如果有,则程序跳转到signal_return*/
restore_all:
RESTORE_ALL/*system_call的退出点,参看前面SAVE_ALL的用法*/

ALIGN
signal_return:/*当system_call从系统调用返回前,如果它检测到需要将信号传送给当前的进程时,才会执行到
signal_return。它通过使中断再次可用开始执行。*/
sti # we can get here from an interrupt handler
testl $(VM_MASK),EFLAGS(%esp)/*检测是否返回虚拟8086模式*/
movl %esp,%eax
jne v86_signal_return/*如果是,就跳转到v86_signal_return(由于虚拟8086我也不太理解,所以就跳过了,:(*/
xorl %edx,%edx /*system_call需要调用c函数do_signal来释放信号。do_signal需要两个参数,这两个参数都是
通过寄存器来传递的;第一个是EAX寄存器,另一个是edx寄存器。system_call已经把第一个参数的值赋给了eax;
现在,把edx寄存器和寄存器本身进行xor操作,从而将其清0,这样do_signal就认为这是一个空指针。*/
call SYMBOL_NAME(do_signal) /*好,现在就可以调用do_signal来传递信号了*/
jmp restore_all /*然后跳转到restore_all结束*/

ALIGN
v86_signal_return:
call SYMBOL_NAME(save_v86_state)
movl %eax,%esp
xorl %edx,%edx
call SYMBOL_NAME(do_signal)
jmp restore_all

ALIGN
tracesys: /*前面说过,当有当前进程的系统调用被其祖先跟踪,如strace或truss程序,程序就跳转到此。*/
movl $-ENOSYS,EAX(%esp) /*system_call把存储在堆栈中的EAX拷贝赋予-ENOSYS。*/
call SYMBOL_NAME(syscall_trace) /*调用syscall_trace*/
movl ORIG_EAX(%esp),%eax /*在172行再从所作的拷贝中恢复EAX的值*/
call *SYMBOL_NAME(sys_call_table)(,%eax,4) /*调用实际的系统调用。*/
movl %eax,EAX(%esp) /*把系统调用的返回值置入堆栈中EAX的位置。*/
call SYMBOL_NAME(syscall_trace) /*再次调用syscall_trace*/
jmp ret_from_sys_call /*被跟踪的系统调用已经返回,控制流程跳转到ret_from_sys_call*/
badsys: /*前面说过,当系统调用数超过边界值时程序就跳转到这里。*/
movl $-ENOSYS,EAX(%esp) /*这时system_call必须返回-ENOSYS,82行把ENOSYS赋值为38。调用者会识别这个错误*/
jmp ret_from_sys_call  /*跳转到ret_from_sys_call*/

ALIGN
ret_from_exception:/*在诸如除0之类的cpu异常中断情况下将执行到这里;system_call内部代码不会执行到这个标号*/
movl SYMBOL_NAME(bh_mask),%eax
andl SYMBOL_NAME(bh_active),%eax
jne handle_bottom_half
ALIGN
ret_from_intr:
GET_CURRENT(%ebx)
movl EFLAGS(%esp),%eax # mix EFLAGS and CS
movb CS(%esp),%al
testl $(VM_MASK | 3),%eax # return to VM86 mode or non-supervisor?
jne ret_with_reschedule
jmp restore_all

ALIGN
handle_bottom_half:
call SYMBOL_NAME(do_bottom_half)
jmp ret_from_intr

ALIGN
reschedule:
call SYMBOL_NAME(schedule)  # test
jmp ret_from_sys_call
这以上的代码,我都还不太怎么明白,等我弄明白了就补齐,但基本的system_call的内部核心代码都介绍完了。后几
天我会分析几个系统调用的样例来帮助理

上一页  [1] [2] [3] 

[数据载入中...] [返回上一页] [打 印]