系统调用(int 0x80)详解

系统调用(int 0x80)详解1、系统调用初始化在系统启动时,会在sched_init(void)函数中调用set_system_gate(0x80,&system_call),设置中断向量号0x80的中断描述符:#defineset_system_gate(n,addr) _set_gate(&idt[n],15,3,addr)其中15表示此中断号对应的是陷阱门,注意,这个中断向量不是中断门描述符

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

 1、系统调用初始化

在系统启动时,会在sched_init(void)函数中调用set_system_gate(0x80,&system_call),设置中断向量号0x80的中断描述符:

#define set_system_gate(n,addr)  _set_gate(&idt[n],15,3,addr)

其中15表示此中断号对应的是陷阱门,注意,这个中断向量不是中断门描述符。比如硬盘中断(hd_interrupt)或定时器中断(timer_interrupt)等硬件类的中断才设置为中断门描述符。陷阱门是可被中断的。关于陷阱门与中断门的区别,及陷阱门中DPL为0或3原因,请参考书本《linux 0.12》的14.19的解释,还有第四章部分内容,这些已经解释的很清楚了。

 

Int 0x80的输入输出参数说明:

输入参数:eax=功能号(比如2为fork系统调用)

用功能对应sys_call_table[]的下标,比如sys_call_table[2]表示fork系统调用函数。

fn_ptr sys_call_table[] = { sys_setup, sys_exit, sys_fork, sys_read,

         返回值:EAX=sys_fork函数的返回值

 

2、system_call的实现

当调用_system_call函数时,系统就从用户态进入了内核态。注意,特权变化了!对于x86系统,因为所有的寄存器都只有一个物理寄存器(ARM就不一要样了),因为内核态与用户态共享所有寄存器(段、通用、栈寄存器),比如SS、ESP、eflags、CS、EIP这五个寄存器。为了能够从内核态返回到调用处继续执行,当前现场,即相关寄存器的内容都需要被保存起来。

那么,这些现场信息保存到那里呢?为什么不能保存到用户态堆栈,如果保存了用户态堆栈,那么,这些栈内存区域,用户程序就可以必改定,那么,程序就很容易被攻击了,直接修改CS:EIP对应的栈内存,那么,你懂的^_^。

现场信息是保存在当前进程的内核态堆栈中,由于已经进入了内核态,在_system_call函数中执行push操作,此时被push的数据是存储也就在内核栈中。SS、ESP、eflags、CS、EIP这五个寄存器的内容是怎么进入内核栈的呢?是程序从用户态进入了内核态时,即在执行_system_call函数中的指令之前,硬件已经自动把SS、ESP、eflags、CS、EIP五个寄存器压入了内核栈,然后,根据函数的需要,再保存相关通用、段之类寄存器。当从内核返回用户态时,这五个寄存器会自动从内核栈中恢复。

         _system_call部分代码分析:

         push %ds

         push %es

         push %fs

         pushl %eax                # save the orig_eax

         pushl %edx               

         pushl %ecx                 # push %ebx,%ecx,%edx asparameters

         pushl %ebx                # to the system call

         movl $0x10,%edx              // ds、es此时指向当前进程的内核态数据段

         mov %dx,%ds

         mov %dx,%es                    

         movl $0x17,%edx              //即使没这二行也行吧,fs本来就指向当前进程的用户态数据段

         mov %dx,%fs                      //因为在fork进程时,fs已经在copy_process函数中设置了。

         call_sys_call_table(,%eax,4)  //根据EAX传入的功能号,即可调用相关系统函数

         pushl %eax                                   //系统调用函数的返回值入栈

 

关于进程状态的变化,参考书上的说明,这部分,理解的还不够,后续再分析???

当在中断处理函数(陷阱门)中执行时,是可被中断(中断门)的,因为eflags标志中的TF被设置为允许中断的。因而有可能在时钟中断函数(do_timer)中,本进程的时间片可能被修改为0。所以,当从系统调用相关功能号对应函数返回时,需要检查当前进程是否还在就绪态,或时间片是否用完,并确认是否需要重新执行调度程序。

2:      movl _current,%eax

         cmpl $0,state(%eax)                 # state

         jne reschedule

         cmpl $0,counter(%eax)             # counter

         je reschedule

//系统调用返回时,会处理当前任务的信号,进程的信号识别与信号处理,仅在系统调用或时钟中断(每10ms)返回时。就能处理信号,优先级还是蛮高的,至少在进程执行流中,到少每10m就能处理信号。

ret_from_sys_call:

         movl _current,%eax

         cmpl _task,%eax                        # task[0] cannot havesignals

         je 3f

         cmpw $0x0f,CS(%esp)               # was old code segment supervisor?

         jne 3f

         cmpw $0x17,OLDSS(%esp)                # was stack segment = 0x17 ?

         jne 3f

        

         movl signal(%eax),%ebx

         movlblocked(%eax),%ecx

         notl %ecx

         andl %ebx,%ecx

         bsfl %ecx,%ecx

         je 3f

         btrl %ecx,%ebx

         movl %ebx,signal(%eax)

         incl %ecx

         pushl %ecx

         call _do_signal                            //调用信号处理函数处理当前进程信号

         popl %ecx

         testl %eax, %eax

         jne 2b                 # see if we need toswitchtasks, or do more signals

3:      popl %eax

         popl %ebx

         popl %ecx

         popl %edx

         addl $4, %esp  # skip orig_eax

         pop %fs

         pop %es

         pop %ds

         iret            //此指令会将内核栈中的数据弹出到这5个寄存器SS、ESP、eflags、CS、EIP。

from:http://www.voidcn.com/blog/maowenl/article/p-1845345.html

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/194422.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • springboot 2.3.0 版本无法引用 javax.validation.constraints. 下的 @NotNull 注解「建议收藏」

    springboot 2.3.0 版本无法引用 javax.validation.constraints. 下的 @NotNull 注解「建议收藏」springboot2.3.0版本无法引用javax.validation.constraints.下的@NotNull注解,如果像使用@NotNull等注解,把版本降到2.2.6就可以了。

    2022年5月25日
    112
  • lineNumber: 6; columnNumber: 40; 文档根元素 “mapper” 必须匹配 DOCTYPE 根 “configuration”。

    lineNumber: 6; columnNumber: 40; 文档根元素 “mapper” 必须匹配 DOCTYPE 根 “configuration”。运行mybatis时报错:lineNumber: 6; columnNumber: 40; 文档根元素 “mapper” 必须匹配 DOCTYPE 根 “configuration”。Cause: org.apache.ibatis.builder.BuilderException: Error parsing SQL Mapper Configuration. Cause: org.a…

    2022年6月13日
    34
  • linux0.11_vim中输入linux命令

    linux0.11_vim中输入linux命令前言所有的UnixLike系统都会内建vi文书编辑器,其他的文书编辑器则不一定会存在。但是目前我们使用比较多的是vim编辑器。vim具有程序编辑的能力,可以主动的以字体颜色辨别语法的

    2022年7月30日
    4
  • byteBuffer_bytebuffer.wrap

    byteBuffer_bytebuffer.wrap引言在nio中,流的读取和写入都是依赖buffer的。jdk在nio包中提供了ByteBuffer、CharBuffer、ShortBuffer、LongBuffer、DoubleBuffer、FloatBuffer等。6中类型的buffer还分为两种实现,缓存在jvm堆中和缓存在直接内存中。Buffer主要属性//Invariants:mark<=position&lt…

    2022年10月2日
    0
  • leetcode-7整数反转「建议收藏」

    leetcode-7整数反转「建议收藏」原题链接给你一个 32 位的有符号整数 x ,返回将 x 中的数字部分反转后的结果。如果反转后整数超过 32 位的有符号整数的范围 [−231, 231 − 1] ,就返回 0。假设环境不允许存储 64 位整数(有符号或无符号)。示例 1:输入:x = 123输出:321示例 2:输入:x = -123输出:-321示例 3:输入:x = 120输出:21示例 4:输入:x = 0输出:0class Solution {public: int rever

    2022年8月8日
    2
  • 免费申请国外免费域名超详细教程「建议收藏」

    免费申请国外免费域名超详细教程「建议收藏」1.首先申请免费域名网站:https://my.freenom.com/domains.php2.填入域名,这里我们以xcflag为列(尽量选择复杂一点的或者五个字母以上的域名,因为简单的有些域名是需要收费的),点击检查可用性。3.可以看到很多免费的域名(用的谷歌翻译插件,翻译有时候不是很准确,free翻译过来应该是免费而不是自由,之后会写一些关于谷歌插件的笔记,详细讲解)4.我们选择xcflag.tk点击立即获取,稍等一会点击购物车查看绿色按钮5.默认三个月试用,这里下拉框我们选择十二个月

    2022年6月30日
    152

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号