作者:吴乐 山东师范大学

《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

本实验目的:通过以一个简单的menu小程序,跟踪系统调用的过程,分析与总结系统调用的机制和三层进入的过程。

一、实验步骤

1.使用gdb在sys_time处设置断点并list找到的代码

2.用s(step)跟踪断点

3.当进入system_call的时候gdb无法继续跟踪,实验结束,找到源代码进行分析

二、system_call对应的汇编代码的工作过程

1.库函数触发中断,并给出系统调用号;2.操作系统通过中断描述符表找到对应的中断处理函数:

于是我们看到了 : ENTRY(system_call)

进一步找到对应的宏定义:/linux-3.18.6/include/linux/linkage.h

#define ENTRY(name) \
                                                .globl name ASM_NL \
                                                ALIGN ASM_NL \

name:

ENTRY(system_call)

RING0_INT_FRAME			# can't unwind into user space anyway
ASM_CLAC
pushl_cfi %eax # save orig_eax
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) # 这里将真正调用对应的系统调用,调用号的意义在这里也表现出来了sys_call_table + 4 * %eax即为系统调用的地址
syscall_after_call:
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:
#ifdef CONFIG_X86_ESPFIX32
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
#endif
restore_nocheck:
RESTORE_REGS 4 # skip orig_eax/error_code
irq_return:
INTERRUPT_RETURN

  

一下在附上系统调用表/linux-3.18.6/arch/frv/kernel/entry.S ,摘录了部分

###################################################################################################
.balign L1_CACHE_BYTES
.globl system_call
system_call:
LEDS 0x6101
movsg psr,gr4 ; enable exceptions
ori gr4,#PSR_ET,gr4
movgs gr4,psr sti gr7,@(gr28,#REG_SYSCALLNO)
sti.p gr8,@(gr28,#REG_ORIG_GR8) subicc gr7,#nr_syscalls,gr0,icc0
bnc icc0,#0,__syscall_badsys ldi @(gr15,#TI_FLAGS),gr4
andicc gr4,#_TIF_SYSCALL_TRACE,gr0,icc0
bne icc0,#0,__syscall_trace_entry __syscall_call:
slli.p gr7,#2,gr7
sethi %hi(sys_call_table),gr5
setlo %lo(sys_call_table),gr5
ld @(gr5,gr7),gr4
calll @(gr4,gr0) ###############################################################################
#
# return to interrupted process
#
###############################################################################
__syscall_exit:
LEDS 0x6300 # keep current PSR in GR23
movsg psr,gr23 ldi @(gr28,#REG_PSR),gr22 sti.p gr8,@(gr28,#REG_GR(8)) ; save return value

  

三、总结:系统调用处理过程与中断处理的机制

系统调用是通过软中断指令 INT 0x80 实现的,而这条INT 0x80指令就被封装在C库的函数中。(软中断和我们常说的硬中断不同之处在于,软中断是由指令触发的,而不是由硬件外设引起的。)

INT 0x80 这条指令的执行会让系统跳转到一个预设的内核空间地址,它指向系统调用处理程序,即system_call函数。

(注意:!!!系统调用处理程序system_call 并不是系统调用服务例程,系统调用服务例程是对一个具体的系统调用的内核实现函数,而系统调用处理程序是在执行系统调用服务例程之前的一个引导过程,是针对INT 0x80这条指令,面向所有的系统调用的。简单来讲,执行任何系统调用,都是先通过调用C库中的函数,这个函数里面就会有软中断 INT 0x80 语句,然后转到执行系统调用处理程序 system_call ,system_call 再根据具体的系统调用号转到执行具体的系统调用服务例程。)

  system_call函数是怎么找到具体的系统调用服务例程的呢?通过系统调用号查找系统调用表sys_call_table!软中断指令INT 0x80执行时,系统调用号会被放入 eax 寄存器中,system_call函数可以读取eax寄存器获取,然后将其乘以4,生成偏移地址,然后以sys_call_table为基址,基址加上偏移地址,就可以得到具体的系统调用服务例程的地址了!然后就到了系统调用服务例程了。需要说明的是,系统调用服务例程只会从堆栈里获取参数,所以在system_call执行前,会先将参数存放在寄存器中,system_call执行时会首先将这些寄存器压入堆栈。system_call退出后,用户可以从寄存器中获得(被修改过的)参数。

另外:系统调用通过软中断INT 0x80陷入内核,跳转到系统调用处理程序system_call函数,然后执行相应的服务例程。但是由于是代表用户进程,所以这个执行过程并不属于中断上下文,而是进程上下文。因此,系统调用执行过程中,可以访问用户进程的许多信息,可以被其他进程抢占,可以休眠。当系统调用完成后,把控制权交回到发起调用的用户进程前,内核会有一次调度。如果发现有优先级更高的进程或当前进程的时间片用完,那么会选择优先级更高的进程或重新选择进程执行。

通过实验分析system_call中断处理过程的更多相关文章

  1. 《Linux内核分析》第五周:分析system_call中断处理过程

    实验 分析system_call中断处理过程 使用gdb跟踪分析一个系统调用内核函数(您上周选择那一个系统调用),系统调用列表参见http://codelab.shiyanlou.com/xref/l ...

  2. 20135202闫佳歆--week5 分析system_call中断处理过程--实验及总结

    week 5 实验:分析system_call中断处理过程 一.使用gdb跟踪分析一个系统调用内核函数(上周选择那一个系统调用)--getpid 复习视频: 如何实现? - 更新menu代码到最新版 ...

  3. Linux内核分析-分析system_call中断处理过程

    姓名:江军 ID:fuchen1994 分析system_call中断处理过程 使用gdb跟踪分析一个系统调用内核函数(您上周选择那一个系统调用),系统调用列表参见http://codelab.shi ...

  4. 通过分析system_call中断处理过程来深入理解系统调用

    通过分析system_call中断处理过程来深入理解系统调用 前言说明 本篇为网易云课堂Linux内核分析课程的第五周作业,上一次作业中我以2个系统调用(getpid, open)作为分析实例来分析系 ...

  5. 分析system_call中断处理过程

    分析system_call中断处理过程 上周我们使用gcc内嵌汇编调用系统调用,这次我们具体分析下过程. 将getpid嵌入menuos 代码从github下载,步骤如下: 1. 增加一个函数,get ...

  6. 作业五:分析system_call中断处理过程

    分析system_call中断处理过程 一.MesuSO增加getpid和getpid-asm 二.使用GDB跟踪系统调用内核函数sys_getpid 分析system_call中断处理过程 使用gd ...

  7. Linux内核分析第五周学习总结——分析system_call中断处理过程

    Linux内核分析第五周学习总结--分析system_call中断处理过程 zl + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/U ...

  8. 实验五:分析system_call中断处理过程

    原创作品转载请注明出处<Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 如果我写的不好或者有误的地方请留言 ...

  9. 实验五分析system_call中断处理过程

    一.实验要求: 1.使用gdb跟踪分析一个系统调用内核函数 2.根据本周所学知识分析系统调用的过程,从system_call开始到iret结束之间的整个过程,并画出简要准确的流程图 二.实验步骤: 1 ...

随机推荐

  1. lintcode :Count and Say 报数

    题目: 报数 报数指的是,按照其中的整数的顺序进行报数,然后得到下一个数.如下所示: 1, 11, 21, 1211, 111221, ... 1 读作 "one 1" -> ...

  2. lintcode:在二叉查找树中插入节点

    题目:  在二叉查找树中插入节点 给定一棵二叉查找树和一个新的树节点,将节点插入到树中. 你需要保证该树仍然是一棵二叉查找树.  样例 给出如下一棵二叉查找树,在插入节点6之后这棵二叉查找树可以是这样 ...

  3. SaaS系列介绍之十三: SaaS系统体系架构

    1 系统体系架构设计 软件开发中系统体系架构决定了一个系统稳定性.健壮性.可扩展性.兼容性和可用性,它是系统的灵魂.体系架构是架构师所关注的核心.良好的体系架构是系统成功的开端,否则,再好的代码与设计 ...

  4. 保障视频4G传输的流畅性,海康威视摄像头相关设置

    我们目前的rtsp视频解决方案如下: 摄像头<---------->NVR(通过4G上传)<---------->easydarwin<---------->自己的 ...

  5. Photoshop:制作方块背景

    1.填充背景色 2.滤镜->杂色->添加杂色 3.滤镜->像素化->马赛克 4.添加横线,明度-10 最终效果 附: 利用:查找边缘.最小值,还可以做这样的效果

  6. 8、双向一对多的关联关系(等同于双向多对一。1的一方有对n的一方的集合的引用,同时n的一方有对1的一方的引用)

    双向一对多关联关系 “双向一对多关联关系”等同于“双向多对一关联关系”:1的一方有对n的一方的集合的引用,同时n的一方有对1的一方的引用. 还是用客户Customer和订单Order来解释: “一对多 ...

  7. math模块及使用方式

    在数学之中,除了加减乘除四则运算之外——这是小学数学——还有其它更多的运算,比如乘方.开方.对数运算等等,要实现这些运算,需要用到 Python 中的一个模块:Math 模块(module)是 Pyt ...

  8. Miller-Rabin素数测试学习小计

    1.Miller-Rabin是干啥的?它是用来检测一个数字(一般是很大的数字)是不是素数: 2.Miller-Rabin算法基于的两个定理: (1)费尔马小定理:如果p是一个素数,且0<a< ...

  9. oracle portlist.ini

    Enterprise Manager Database Control URL - (orcl) :https://redhat4.7:1158/em [root@redhat4 install]# ...

  10. [UVA796]Critical Links(割边, 桥)

    题目链接:https://uva.onlinejudge.org/index.php?option=com_onlinejudge&Itemid=8&page=show_problem ...