zoukankan      html  css  js  c++  java
  • Linux内核分析-系统中断在内核中的实现

    分析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
    	"    //系统调用号赋给eax寄存器
                    "mov %1,%%ebx
    	"        //将文件夹的名称赋给ebx寄存器
                    "mov %2,%%ecx
    	"        //将文件夹的权限赋给ecx寄存器
                    "int $0x80
    	"            //开启中断,执行mkdir系统调用
                    "mov %%eax,%0
    	"        //将返回值赋给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结束该操作。

  • 相关阅读:
    刚刚找到的IP地址对应地区数据库
    SQL2000中像SQL2005中的Row_Number一样获取行号
    KindEditor3.4.4版的ASP.NET版本
    使用程序代码输出论坛回复第X层楼
    IIS上启用Gzip压缩(HTTP压缩)详解(PDF)
    ASP.NET中过滤HTML字符串的两个方法
    七个受用一生的心理寓言
    Android获取其他包的Context实例然后XX(转载)
    android junit基础教程
    java获取web容器地址
  • 原文地址:https://www.cnblogs.com/Spr1ngxx/p/5325922.html
Copyright © 2011-2022 走看看