zoukankan      html  css  js  c++  java
  • 深入理解系统调用

    实验要求“

    • 找一个系统调用,系统调用号为学号最后2位相同的系统调用,学号末尾2位为10
    • 通过汇编指令触发该系统调用
    • 通过gdb跟踪该系统调用的内核处理过程
    • 重点阅读分析系统调用入口的保存现场、恢复现场和系统调用返回,以及重点关注系统调用过程中内核堆栈状态的变化

    一  环境准备

      上次实验已经下载好内核源码参考https://www.cnblogs.com/russian/p/12873826.html,接下来进行内核编译选项。

      配置内核编译选项,

      首先打开debug相关选项 ;选择进入Kernel Hacking

      接着选择 Compile-time checks and compiler options --> 

      修改下列两个选项为Y

       然后关闭KASLR,否则会导致打断点失败,首先进入Processor type and features选项

     

     保存退出。

    二 制作根文件系统

      1.下载跟文件系统  :

          axel -n 20 https://busybox.net/downloads/busybox-1.31.1.tar.bz2  

       tar -jxvf busybox-1.31.1.tar.bz2
       cd busybox-1.31.1 
    2.制作根文件系统:
       make menuconfig
       编译成静态链接,不用动态链接库:在setting中设置

         然后编译安装,默认会安装到元年吗目录下_install目录中;

        make -j$(nproc) && make install
     3.接着制作内存根文件系统镜像
        mkdir rootfs
        cd rootfs
        cp ../busybox-1.31.1/_install
    /* ./ -rf
        mkdir dev proc sys home
        
    sudo cp -a /dev/{null,console,tty,tty1,tty2,tty3,tty4} dev/
     
    4.准备添加init脚本文件放根目录下,
        touch init.sh
        vi init.sh
        i键入内容如下:
         #!/bin/sh
         mount -t proc none /proc mount -t sysfs none /sys
         echo "Wellcome MengningOS!" echo "--------------------"
         cd home
         /bin/sh
        保存退出 :wq

        接着给init脚本添加可执行权限: chmod +x init
        打包成内存根文件系统镜像:find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../rootfs.cpio.gz
        测试挂在根文件系统,看内核启动完是否执行脚本:
    qemu-system-x86_64 -kernel linux-5.4.34/arch/x86/boot/bzImage -initrd rootfs.cpio.gz
        最终挂载成功之后显示
    三 系统调用
      1.查看系统调用
        打开内核源码中中断调用号,找到与自己学号末尾相同的中断服务例程,目录为linux-5.4.34/arch/x86/entry/syscalls/syscall_64.tbl
    
    

    可知第10号调用为mprotect ,对应的处理函数为__x64_sys_mprotect。

    
    

        2.编写汇编调用代码

    
    

         由于我们搭建的系统不支持动态链接,因此这里我们在使用gcc编译时要用-static静态编译参数)。

        gcc test.c -o test -static

        3.重新执行根文件系统(重新打包,用qemu运行)

        find . -print0 | cpio --null -ov --format=newc | gzip -9 > ../rootfs.cpio.gz
        qemu-system-x86_64 -kernel linux-5.4.34/arch/x86/boot/bzImage -initrd rootfs.cpio.gz

       四  gdb调试。

        1. 启动gdb调试

        首先命令行启动qemu:    

        qemu-system-x86_64 -kernel linux-5.4.34/arch/x86/boot/bzImage -initrd rootfs.cpio.gz -S -s -nographic -append "console=ttyS0"
       然后重新开一个命令行,在源码目录下启动gdb
        gdb vmlinux
       接着在gdb中运行:
    target remote:1234
      

       然后给对应大的系统调用打上断点

       如图成功触发断点。

       2.gdb单步调试

        

         

       五 结果分析‘

        系统调用的保存现场和恢复现场;entry_SYSCALL_64是系统调用的入口点,它完成了保存现场,调用对应的内核处理函数、恢复现场、系统调用返回等工作。

        

           汇编指令syscall 触发系统调用,通过MSR寄存器找到了中断函数入口;

                       

      可以看到,它没有使用sava_all命令保存现场,而使用了特殊的swapgs,来快照式地保存现场,加快了系统调用的速度。

                   

         接着跳转获得系统调用号,执行系统调用的内容

                  

           调用结束,恢复到用户态执行syscall_return_slowpath 函数要为恢复现场做准备

        

           swapgs——恢复现场

     
     
     
     
     
     
     
  • 相关阅读:
    让DIV实现抖动效果!
    Linux下如果python2和python3同时存在使用pip3
    Eclipse 查找一个接口的具体实现
    linux下编译安装软件到指定目录
    NG机器学习-octave基本操作
    NG机器学习
    全注解方式构建SpringMVC项目
    Java多线程学习开发笔记
    RabbitMQ 学习开发笔记
    Redis 学习开发笔记
  • 原文地址:https://www.cnblogs.com/russian/p/12963046.html
Copyright © 2011-2022 走看看