Socket与系统调用深度分析

一、Socket接口在用户态通过系统调用机制进入内核;

  • 内核态:控制计算机的硬件资源,并提供上层应用程序运行的环境。此时处理器处于特权级最高的(0级)内核代码中执行。
  • 用户态:上层应用程序的活动空间,应用程序的执行必须依托于内核提供的资源。此时处理器在特权级最低的(3级)用户代码中运行。
  • 系统调用:为了使上层应用能够访问到这些资源,内核为上层应用提供访问的接口。
  三者之间的关系:用户态下的应用程序,通过系统调用的方式,访问内核态中的资源。
  Socket API :socket可以看成是用户进程与内核网络协议栈的编程接口。TCP/IP协议的底层部分已经被内核实现了,而应用层是用户需要实现的,这部分程序工作在用户空间。用户空间的程序需要通过套接字来访问内核网络协议栈。
  Socket接口在用户态通过系统调用机制进入内核的过程为:
  用户态下的应用程序通过Socket API 请求系统调用,从而进入内核态访问内核中的TCP/IP的底层协议栈。

二、内核中将系统调用作为一个特殊的中断来处理

  系统调用被称为软中断,是应用程序主动进入内核的方式,是借助于中断异常机制实现的。有一条特殊指令,使得用户态和内核态得以切换(在linux中为 int 0x80)。
  Socket与系统调用深度分析
  系统调用过程:
  • 中断异常机制:硬件保护现场,查询中断向量表,cpu控制权转移至系统调用总入口程序。
  • 系统调用总入口程序:保存现场,把参数保存到内核的堆栈中,查询系统调用表,将cpu控制权转交给相应内核函数
  • 执行系统调用例程
  • 恢复现场,返回用户进程
  以socket相关系统调用为例进行分析
  反汇编menu目录下的init文件,共有5处int $0x80的汇编指令,其中一处如图所示:
  验证了内核中将系统调用作为一个特殊的中断来处理。
  Socket与系统调用深度分析
   验证 x86-64位系统下的系统调用初始化过程:start_kernel --> trap_init --> cpu_init --> syscall_init
  进入menu目录,修改Makefile文件,并执行 make rootfs #打开menuos 。
    Socket与系统调用深度分析
   在linux-5.0.1目录下,打开一个新的终端,执行命令如下:
gdb
file vmlinux
target remote:1234
b start_kernel
b trap_init
b cpu_init
b syscall_init
  设置断点成功,验证了x86-64位系统下的系统调用初始化过程。
  Socket与系统调用深度分析
 

  三、Socket 调用初步分析

  使用gdb跟踪replyhi的执行过程。
  在menu目录下执行 make rootfs 启动 memuos。
  在linux-5.0.1目录下打开新的终端,执行命令,如下:
gdb
file vmlinux
target remote:1234
b __sys_socket
b __sys_bind
b __sys_listen
b __sys_shutdown
   即:进入gdb模式,加载vmlinux,用target remote:1234和menuos连接,在__sys_listen处设置断点,按c执行下去,在menuos中输入replyhi 但获取不到断点。。。。
  Socket与系统调用深度分析
  发现是Makefile设置错误,修正后,运行结果如下:
  Socket与系统调用深度分析
  可见在replyhi 执行过程中,调用了socket()、bind()、listen()等api 。