博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
Linux内核分析-系统中断在内核中的实现
阅读量:4660 次
发布时间:2019-06-09

本文共 2681 字,大约阅读时间需要 8 分钟。

分析system_call中断处理过程

在MenuOS中添加上周所运用到的系统调用

即在Linuxkernel/menu/test.c文件中,添加代码如下:

int Mkdir()    {        const  char *ch = "test"; //创建的文件夹名称        mode_t mode = 0700;        //创建的文件夹的权限        int flag = 0;        //是否创建成功新的文件夹的标识符        flag = mkdir(ch,mode);    //调用mkdir        if(flag==0)                //flag=0则创建成功,否则失败        {             printf("succeed");        }        else            printf("error");        return 0;    }    int MkdirAsm()    {         char *ch="test-asm"; //创建文件夹的名称        mode_t mode=S_IRWXU;  //创建新的文件夹的权限        int flag=0;            //标识符        asm volatile(                "mov $0x27,%%eax\n\t"    //系统调用号赋给eax寄存器                "mov %1,%%ebx\n\t"        //将文件夹的名称赋给ebx寄存器                "mov %2,%%ecx\n\t"        //将文件夹的权限赋给ecx寄存器                "int $0x80\n\t"            //开启中断,执行mkdir系统调用                "mov %%eax,%0\n\t"        //将返回值赋给flag                :"=m"(flag)                //输出变量flag                :"d"(ch),"D"(mode)        //输入变量ch与mode                );        if(flag==0)            //flag=0则创建成功,否则失败            printf("succeed");        else            printf("error");        return 0;    }    int main()    {        PrintMenuOS();        SetPrompt("MenuOS>>");        MenuConfig("version","XXX V1.0(Menu program v1.0 inside)",NULL);        MenuConfig("quit","Quit from XXX",Quit);    MenuConfig("mkdir","Make up a new director",Mkdir);        MenuConfig("Mkdirasm","Make up a new director by asm",MkdirAsm);        ExecuteMenu();      }
  • make rootfs即可完成功能的添加

gdb单步调试系统调用mkdir

  • 设置断点:

    设置断点

  • 在MenuOS界面输入mkdir,则发现停在了system_mkdir该函数处:

    输入mkdir出现调试界面

  • 进行单步调试,发现其步骤大约为读取pathname(所需要创建文件夹的名称),配置权限,完成创建:

    单步调试的结果

  • 同理输入命令mkdirasm,完成单步调试,与mkdir一样的结果(因为都是调用系统调用mkdir)

  • 输入c,将程序进行完,则出现最终结果:

    运行结果

system_call到iret的步骤

  • 代码如下:

    .macro INTERRUPT_RETURN ; 中断返回
    iret
    .endm
    .macro SAVE_ALL ; 保护现场
    ...
    .macro RESTORE_INT_REGS
    ...
    .endm

    ENTRY(system_call)      SAVE_ALL  syscall_call:      call *sys_call_table(,%eax,4)      movl %eax, PT_EAX(%esp)  ; store the return value  syscall exit:      testl $_TIF_ALLWORK_MASK, %ecx # current->work      jne syscall_exit_work  restore_all:      RESTORE_INT_REGS  irq_return:      INTERRUPT_RETURN      ; 到这里就算执行完了  ENDPROC(system_call)  syscall_exit_work:      testl  $_TIF_WORK_SYSCALL_EXIT, %ecx      jz work_pending  END(syscall_exit_work)  work_pending:      testb $_TIF_NEED_RESCHED, %cl      jz work_notifysig  work_resched:      call schedule      jz restore_all  work_notifysig:      ...                  ; deal with pending signals  END(work_pending)
  • 流程图如下:

    流程图

  • SAVE_ALL宏可以在栈中保存中断处理程序可能会使用的所有CPU寄存器,以此起到保护现场的作用

  • 根据sys_call_table查找所需要的中断程序的中断号,从而执行system_call

  • 系统调用完成后,则执行iret结束该操作。

转载于:https://www.cnblogs.com/Spr1ngxx/p/5325922.html

你可能感兴趣的文章
创建Docker overlay network
查看>>
运行第一个abp项目VS2015+localDB
查看>>
ubuntu之路——day8.3 RMSprop
查看>>
Jmeter接口测试自动化 (三)(数据驱动测试)
查看>>
[LeetCode] Single Number III
查看>>
哈夫曼树原理及构造
查看>>
Linux的vi和vim编辑器
查看>>
C# — LINQ查询的简单使用
查看>>
MYSQL的价格
查看>>
sublime入门文章
查看>>
Photoshop CC 智能切图功能介绍
查看>>
掌握了看计算机相关论文的方法
查看>>
软件工程综合实践专题 个人博客作业 Github
查看>>
SQL触发器+游标
查看>>
ffmpeg
查看>>
vue和angular的区别
查看>>
PowerDNS简单教程(4):优化篇
查看>>
React 介绍
查看>>
常用判断重复记录的SQL语句
查看>>
一些比较常用的在Markdown使用的数学符号
查看>>