码迷,mamicode.com
首页 > 其他好文 > 详细

深入理解系统调用

时间:2020-05-24 21:09:33      阅读:78      评论:0      收藏:0      [点我收藏+]

标签:table   init   生成   call   代码   汇编指令   mic   idt   用户   

1.系统调用的概念

用户态与内核态:

技术图片

 

32 位 Linux 进程地址空间:

技术图片

 

系统调?概述:

技术图片

 

 Linux的系统调?:

技术图片

 

 2.环境准备

编译选项:

技术图片

 

 技术图片

 

 编译内核并运行:由于还未挂载根文件系统,因此出现kernel panic。

技术图片

 

 制作根文件系统:

配置编译选项:

技术图片

 

 编写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

  技术图片

 

 3.系统调用分析

本人学号末2位为95,查看95号系统调用:

技术图片

 

 umask用于设置文件和目录的默认访问权限。

 

编写代码调用这一系统调用:

int main()
{
  asm volatile(
  "movl $0x5f,%eax\n\t" 
  "syscall\n\t" );
  return 0;
}

静态编译后将可执行文件拷贝到rootfs/home目录下,重新生成根文件系统。

再次运行虚拟机,可以发现已经成功拷贝该文件。

技术图片

 

进行跟踪调试:

由于umask对应的内核处理函数为 __x64_sys_umask,因此在__x64_sys_umask处断点。

技术图片

 

 查看函数调用堆栈:

技术图片

 

不难发现,entry_SYSCALL_64是系统调用的入口,完成 保存现场的功能。进入该函数:

技术图片

 

 swapgs指令用于保存现场。这是在x86-64中引入的指令,类似快照的?式将保存现场和恢复现场时的CPU寄存器也通过CPU内部的存储器快速保存和恢复,近?步加快了系统调?。

继续运行,回到do_syscall函数,这个

技术图片

 

 可以发现,rax存储了系统调用号。通过系统调用表调用相应的系统调用函数,然后将返回值存入rcx寄存器中。

继续执行,回到entry_SYSCALL_64函数中,这一部分的代码用于恢复现场。

 技术图片

 

 4.总结

系统调用的流程大致如下:

首先,通过汇编指令中的系统调用号找到系统调用入口ENTRY(entry_SYSCALL_64),然后在ENTRY(entry_SYSCALL_64)中,执行swapgs保存现场。随后执行do_syscall_64方法,该方法中,执行x32_sys_call_table方法,根据rax中存储的系统调用号跳转至具体的系统调用函数,在本例中,为__x64_sys_umask。系统调用函数执行完毕后,返回ENTRY(entry_SYSCALL_64)方法,执行恢复现场操作。

 

深入理解系统调用

标签:table   init   生成   call   代码   汇编指令   mic   idt   用户   

原文地址:https://www.cnblogs.com/daiyan1/p/12952508.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!