system_call中断处理过程分析

原创作品转载请注明出处  《Linux内核分析》MOOC课程http://mooc.study.163.com/course/USTC-1000029000

系统调用是上层软件最终与操作系统沟通的唯一途径,于是我们需要分析操作系统调用的整个流程以便于更清楚地知道操作系统如何运作。

int TimeAsm(int argc, char *argv[])
{
    time_t tt;
    struct tm *t;
    asm volatile(
        "mov $0,%%ebx\n\t"
        "mov $0xd,%%eax\n\t" 
        "int $0x80\n\t" 
        "mov %%eax,%0\n\t"  
        : "=m" (tt) 
    );
    t = localtime(&tt);
    printf("time:%d:%d:%d:%d:%d:%d\n",t->tm_year+1900, t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
    return 0;
}

int main()
{
    PrintMenuOS();
    SetPrompt("MenuOS>>");
    MenuConfig("version","MenuOS V1.0(Based on Linux 3.18.6)",NULL);
    MenuConfig("quit","Quit from MenuOS",Quit);
    MenuConfig("time","Show System Time",Time);
    MenuConfig("time-asm","Show System Time(asm)",TimeAsm);	// 将实现的函数加入到命令列表中
    ExecuteMenu();                				// 最终执行体,等待用户交互
}

以下面是注册和执行流程:


int TimeAsm(int argc, char *argv[])
{
    time_t tt;
    struct tm *t;
    asm volatile(
        "mov $0,%%ebx\n\t"
        "mov $0xd,%%eax\n\t" 
        "int $0x80\n\t" 
        "mov %%eax,%0\n\t"  
        : "=m" (tt) 
    );
    t = localtime(&tt);
    printf("time:%d:%d:%d:%d:%d:%d\n",t->tm_year+1900, t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
    return 0;
}

int main()
{
    PrintMenuOS();
    SetPrompt("MenuOS>>");
    MenuConfig("version","MenuOS V1.0(Based on Linux 3.18.6)",NULL);
    MenuConfig("quit","Quit from MenuOS",Quit);
    MenuConfig("time","Show System Time",Time);
    MenuConfig("time-asm","Show System Time(asm)",TimeAsm);	// 将实现的函数加入到命令列表中
    ExecuteMenu();                				// 最终执行体,等待用户交互
}

这个流程还是比较简单明了的。

        接着,步入正轨,具体了解调用流程:

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

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

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

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

                                                name:

        这里有些不太理解,按照宏中显示此处便定义了标号system_call,但在后面却又看到system_call,希望理解的小伙伴可以告知,觉得这段主要起链接用途,还有个ENDPROC(system_call)与之对应。

int TimeAsm(int argc, char *argv[])
{
    time_t tt;
    struct tm *t;
    asm volatile(
        "mov $0,%%ebx\n\t"
        "mov $0xd,%%eax\n\t" 
        "int $0x80\n\t" 
        "mov %%eax,%0\n\t"  
        : "=m" (tt) 
    );
    t = localtime(&tt);
    printf("time:%d:%d:%d:%d:%d:%d\n",t->tm_year+1900, t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
    return 0;
}

int main()
{
    PrintMenuOS();
    SetPrompt("MenuOS>>");
    MenuConfig("version","MenuOS V1.0(Based on Linux 3.18.6)",NULL);
    MenuConfig("quit","Quit from MenuOS",Quit);
    MenuConfig("time","Show System Time",Time);
    MenuConfig("time-asm","Show System Time(asm)",TimeAsm);	// 将实现的函数加入到命令列表中
    ExecuteMenu();                				// 最终执行体,等待用户交互
}

下面是系统调用表/linux-3.18.6/arch/frv/kernel/entry.S ,的一部分呢

int TimeAsm(int argc, char *argv[])
{
    time_t tt;
    struct tm *t;
    asm volatile(
        "mov $0,%%ebx\n\t"
        "mov $0xd,%%eax\n\t" 
        "int $0x80\n\t" 
        "mov %%eax,%0\n\t"  
        : "=m" (tt) 
    );
    t = localtime(&tt);
    printf("time:%d:%d:%d:%d:%d:%d\n",t->tm_year+1900, t->tm_mon, t->tm_mday, t->tm_hour, t->tm_min, t->tm_sec);
    return 0;
}

int main()
{
    PrintMenuOS();
    SetPrompt("MenuOS>>");
    MenuConfig("version","MenuOS V1.0(Based on Linux 3.18.6)",NULL);
    MenuConfig("quit","Quit from MenuOS",Quit);
    MenuConfig("time","Show System Time",Time);
    MenuConfig("time-asm","Show System Time(asm)",TimeAsm);	// 将实现的函数加入到命令列表中
    ExecuteMenu();                				// 最终执行体,等待用户交互
}

总结

1、用户态到内核态需要int 0x80进行中断,只有生成了中断向量后才可以切换状态;

2、中断处理让CPU停止当前工作转为执行系统内核中预设的一些任务,因此必须要对当前CPU执行的任务进行执行现场的保护工作,并对一些其他杂七杂八的工作进行检查,完成调用后,再进行检查,才能执行iret返回。

3、系统内部调用涉及CPU架构等内容,不同的CPU对于系统调用的汇编具体代码是不一样的。









  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值