• 深入理解系统调用


    一、实验环境准备

    按照课程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内部的存储器快速保存和恢复,更加加快了系统调用。

  • 相关阅读:
    环境配置 | 安装Jupyter Notebook及jupyter_contrib_nbextensions库实现代码自动补全
    环境配置 | mac环境变量文件.bash_profile相关
    Django | 解决“(1146, "Table 'mydb.django_session' doesn't exist")”报错的方法
    Django | pycharm 提示 unresolved attribute referene 'objects' for class 'xxxx'
    站点中添加企业qq的几种方式
    div自适应高度
    SVN服务器搭建和使用(三)
    SVN服务器搭建和使用(二)
    SVN服务器搭建和使用(一)
    宽度为100%,缩小窗口,右侧的区域背景图片变成空白
  • 原文地址:https://www.cnblogs.com/happyyouli/p/12971721.html
Copyright © 2020-2023  润新知