深入理解系统调用

Posted sa19225475

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了深入理解系统调用相关的知识,希望对你有一定的参考价值。

深入理解系统调用

一.实验要求

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

二.实验过程

  1. 实验准备
  • 配置内核选项

    ?make defcon?g # Default con?guration is based on ‘x86_64_defcon?g‘
    ?make menucon?g
    ?#打开debug相关选项
    ?Kernel hacking --->
    ?Compile-time checks and compiler options --->
    ?[*] Compile the kernel with debug info
    ?[*] Provide GDB scripts for kernel debugging
    ?[*] Kernel debugging
    ?#关闭KASLR,否则会导致打断点失败
    ?Processor type and features ---->
    ?[] Randomize the address of the kernel image (KASLR)

技术图片

技术图片

技术图片

配置完成后, 将源码重新编译, 然后运行qemu:

qemu-system-x86_64 -kernel arch/x86/boot/bzImage
  • 制作根文件系统

    • 下载busybox源码

      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
      
    • 配置

      配置编译成静态链接库

      ?Settings --->
      ?[*] Build static binary (no shared libs)
      ?然后编译安装,默认会安装到源码?录下的_install?录中。
      ?make -j$(nproc) && make install

    • 制作内存根文件系统

      ?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/

    • 准备测试脚本

      ?准备init脚本?件放在根?件系统跟?录下(rootfs/init),添加如下内容到init?件。

      #!/bin/sh
      mount -t proc none /proc
      mount -t sysfs none /sys
      echo "Wellcome MengningOS!"
      echo "--------------------"
      cd home
      /bin/sh
      

      ?给init脚本添加可执?权限
      chmod +x init

    • 打包根文件系统 , 测试

      ?nd . -print0 | cpio --null -ov --format=newc | gzip -9 > ../rootfs.cpio.gz
      

      测试挂载根?件系统,看内核启动完成后是否执?init脚本

      qemu-system-x86_64 -kernel linux-5.4.34/arch/x86/boot/bzImage-initrd rootfs.cpio.gz
      

    可以看到我们的脚本 已经顺利的被打包到根文件系统中运行了

    技术图片

  1. 调试75号系统调用

    我的学号后两位是75, 查看系统调用表

    arch/x86/syscalls/syscall_64.tbl

    技术图片

该系统调用的功能 是将数据刷新到磁盘上面

fdatasync:

Linux的文件存储的是将数据文件信息inode 分别存储的,在inode中保存了如:名称、文件大小size、修改时间、访问时间等信息我们称作metadata元数据。数据和文件信息inode在物理上是分开存储的,innode修改时需要一次磁盘IO的

  • 编写一个简单的代码来触发fdatasync系统调用

    int main()
    {
        asm volatile(
            "movl $0x4B,%eax
    	" //使用EAX传递系统调号75
            "syscall
    	" //触发系统调用;
            );
        return 0;
    }
    
    

    编译这个代码生成可执行文件fdatasync_test(一定要加上-static参数使用静态编译, 因为我们设置了在内核中设置了静态编译选项)

  • 重新打包根文件系统

    ?nd . -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 -S -s -nographic -append "console=ttyS0"
    
  • 调试

    • 启动系统后会暂时停止, 这时我们新开一个终端, 输入命令:
    gdb vmlinux
    target remote:1234
    
    • 接着我们输入c, 虚拟机会继续运行, 完成初始化并进入初始界面

      技术图片

    ? 因为fdatasync对应的函数入口是_x64_sys_fadatasync, 所以我们在这个打下断点:

    • qemu运行后, 我们在qemu的终端的home目录下, 运行我们之前编译好的fdatasync_test可执行文件, 此时虚拟机会卡主, 我们在调试终端查看调试信息
      //TODO



















以上是关于深入理解系统调用的主要内容,如果未能解决你的问题,请参考以下文章

深入理解系统调用

深入理解系统调用

深入理解计算机操作系统(笔记)

深入理解系统调用

深入理解系统调用

深入理解系统调用