首页 > 其他 > 详细

Socket与系统调用深度分析

时间:2019-12-20 01:45:17      阅读:106      评论:0      收藏:0      [点我收藏+]

一:常见的知识点回顾

  • 用户态:指非特权状态,不能执行特权指令(访问IO设备、访问特殊寄存器、置时钟... ...),所有用户程序都是运行在用户态的
  • 内核态:控制计算机的硬件资源,并提供上层应用程序运行的环境
  • 系统调用(CPU中又称为陷阱指令):为了让应用程序有能力访问系统资源,每个操作系统都提供了一套接口,以供应用程序使用,这就是系统调用。它规定了用户进程进入内核的具体位置。它本身并非内核函数,但它是由内核函数实现,进入内核后,不同的系统调用会找到各自对应的内核函数(根据系统调用号),这些内核函数被称为系统调用的“服务例程”。

系统调用的流程如下

  1. 用户态程序将一些数据值放在寄存器中, 或者使用参数创建一个堆栈(stack frame), 以此表明需要操作系统提供的服务.
  2. 用户态程序执行陷阱指令
  3. CPU切换到内核态, 并跳到位于内存指定位置的指令, 这些指令是操作系统的一部分, 他们具有内存保护, 不可被用户态程序访问
  4. 这些指令称之为陷阱(trap)或者系统调用处理器(system call handler). 他们会读取程序放入内存的数据参数, 并执行程序请求的服务
  5. 系统调用完成后, 操作系统会重置CPU为用户态并返回系统调用的结果
  • API:是一些预先定义的函数,或指软件系统不同组成部分衔接的约定。 目的是提供应用程序与开发人员基于某软件或硬件得以访问一组例程的能力
  • 系统调用和api的区别:api是函数的定义,规定了这个函数的功能,跟内核无直接关系。而系统调用是通过中断向内核发请求,实现内核提供的某些服务。

技术分享图片

二:Linux中系统调用

系统调用使得操作系统从用户态进入了内核态,从而使用了内核中的一些功能,linux x86-64系统通过int 80调用syscall中断来进入内核态。在使用socket编程中,系统先通过中断进入内核态,再调用底层功能来使得可以与网络通信协议产生连接。

技术分享图片

x86-64Linux系统启动时依次调用以下过程:start_kernel --> trap_init --> cpu_init --> syscall_init,而syscall_init函数实现了系统调用的初始化将中断向量与服务例程进行绑定。除此之外,还要进行系统调用表的初始化。

简单的验证一下:

  1. 进入menu目录,打开menuos

    make rootfs

技术分享图片

2.进入linux-5.0.1目录,打开一个新中断,执行以下命令

gdb
file vmlinux
target remote:1234          #用其和menuos连接
b start_kernel
b trap_init
b cpu_init
b syscall_init     

设置断点后,验证了其系统调用初始化的过程

技术分享图片

意外的是我执行b syscall_init告诉我该函数没有定义

CPU为不同的中断设置了不同的中断号,以Intel i386为例,它共有256种中断,每个中断都用一个0~255之间的数来表示,Intel将前32个中断号(0~31)已经固定设定好或者保留未用。中断号32~255分配给操作系统和应用程序使用,Linux将系统调用设为中断号128,即0x80。

初始化流程为:start_kernel --> trap_init --> idt_setup_traps --> 0x80绑定entry_INT80_32

在idt.c源文件我们可找到上面的的绑定的系统中断处理函数

SYSG(IA32_SYSCALL_VECTOR,entry_INT80_32);

我们用一个例子来展示一个简单的系统调用的流程:

技术分享图片

  1. 应用程序调用一个库函数xyz()
  2. 库函数内封装了一个系统调用SYSCALL,它将参数传递给内核并触发中断
  3. 触发中断后,内核进行中断处理,执行系统调用处理函数 (5.0内核中是entry_INT80_32,不再是system_call了)
  4. 系统调用处理函数会根据系统调用号,选择相应的系统调用服务例程(在这里是sys_xyz),真正开始处理该系统调用

三、Socket调用初步分析

gdb
file vmlinux
target remote:1234
b __sys_socket
b __sys_bind
b __sys_listen
b __sys_connect
b __sys_accept4
b __sys_shutdown

在实验之前,首先要修改上次的menu/Makefile文件

cd LinuxKernel/linux-5.0.1/menu
gedit Makefile
#修改内容
make rootfs

技术分享图片

Socket与系统调用深度分析

原文:https://www.cnblogs.com/kttme/p/12070741.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!