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

    一、实验环境准备

    按照课程PPT的步骤进行:

    1. 编译linux内核

    2. 安装开发工具qemu

    3. 制作根文件系统

    4. 准备gdb调试工具

    由于本人环境为ubuntu16.04,在使用gdb调试的过程中出现了下面的错误:

     经过查阅资料得知这是由于ubuntu16.04的gdb版本问题,且不能通过apt升级,故下载gdb7.5版本源码进行编译安装。

    在编译之前需修改remote.c文件中的部分代码,将下面代码:

    if (buf_len > 2 * rsa->sizeof_g_packet)
        error (_(“Remote ‘g’ packet reply is too long: %s”), rs->buf);

    修改为:

    if (buf_len > 2 * rsa->sizeof_g_packet) {
       rsa->sizeof_g_packet = buf_len ;
       for (i = 0; i < gdbarch_num_regs (gdbarch); i++) {
           if (rsa->regs->pnum == -1)
              continue;
           if (rsa->regs->offset >= rsa->sizeof_g_packet)
              rsa->regs->in_g_packet = 0;
           else  
              rsa->regs->in_g_packet = 1;
       }    
    }

    二、系统调用实现

    本人学号尾号为49,通过vscode查阅arch/x86/ entry/syscalls/syscall_64.tbl文件,可以得到系统调用号为49的系统调用为bind,通过查阅资料,Bind一般是在server端调用,通过bind,会把本端的地址和端口号与socket描述符进行绑定,而目的地址和端口在connect的时候才能确定。

     

    由于本次实验旨在理解系统调用如何执行,故没有深入研究如何在程序中使用bind系统调用,而使用嵌入的汇编代码进行了bind系统调用。

     新建/rootfs/home/systemcall文件夹,创建bind.c文件。

    #include <stdio.h>
    int main(){
        asm volatile(
        "movl $0x31,%eax
    	"
        "syscall
    	");
        printf("end!
    ");
        return 0;
    }

    然后编译:gcc -o bind bind.c -static

    返回roofs目录,打包系统镜像:find . -print0 | cpio --null -ov --format=newc | gzip -9 > ~/linux_code/linux-5.4.34/rootfs.cpio.gz

    执行  qemu-system-x86_64 -kernel arch/x86/boot/bzImage -initrd rootfs.cpio.gz -S -s -nographic -append "console=ttyS0"  启动内核

    打开新终端源代码目录下执行  gdb vmlinux  打开gdb调试工具,运行bind文件,进行如下调试过程

     分析:

    1. linux内核定义了大量的系统调用,内核通过EAX寄存器传递的系统调用号即可得知用户态程序希望哪个系统调用。

    2. 除了系统调用号以外,系统调用还可能要传递参数,由于32为的x86体系结构下是将参数压栈的方式传递,这样效率较低,而64位的x86体系结构使用寄存器来传递参数,效率较高。

    3. 使用syscall汇编指令来触发系统调用。

    4. 保存现场:如调试过程所示,系统自动将rip保存到rcx,然后将系统调用入口加载到rip,syscall借助CPU内部的MSR寄存器来存放,查找系统调用入口地址会更快。

    4.恢复现场:使用swapgs指令,将保存现场和恢复现场时的CPU寄存器也通过CPU内部的存储器快速保存和恢复,更加加快了系统调用。

  • 相关阅读:
    特效优化
    Jsp
    JRebel 热部署
    mysql
    行为树
    Medium | LeetCode 139. 单词拆分 | 动态规划
    Medium | LeetCode 31. 下一个排列
    Easy | LeetCode 27. 移除元素 | 快慢指针
    Medium | LeetCode 437. 路径总和 III | 树 + 回溯 + 前缀和
    Medium | LeetCode 337. 打家劫舍 III | 树后序遍历 + 动态规划
  • 原文地址:https://www.cnblogs.com/happyyouli/p/12971721.html
Copyright © 2011-2022 走看看