Socket与系统调用深度分析

摘要:
系统调用由操作系统核心提供,运行于内核态。在这里调用中断指令int0x80实现由用户态转向内核态,,当运行到int0x80这条中断指令时,跳转到entry_INT80_32,这是liunx系统中所有系统调用的入口点。利用GDB跟踪系统调用过程,我们来用上次创建的MenuOS,运行hello/hi程序,跟踪系统调用的过程。首先在sys_socketcall处打上断点,接下来按c继续运行,看看都调用了哪些函数。socket()调用sys_socketcall()系统调用。bind,connect等等函数都需要sys_socketcall()作为入口。sys_socketcall()里面都有些什么呢?

一、系统调用

什么是系统调用呢?

来了解这个问题之前我们先来分析一下什么是用户态,什么是内核态。用户态是非特权状态,简单来说,就是不允许执行某些可能存在危险的操作的状态,在这种状态下,进程只能在各自的用户空间当中运行。内核态也就是特权状态,也就是具有可以具有权限来执行某些可能存在危险的操作。当一个进程执行系统调用,由于这个进程在用户态下没有足够的权限,那么它就会陷入到内核态,在调用内核代码来执行这些系统调用。系统调用由操作系统核心提供,运行于内核态。

系统调用的过程是怎样的呢?

step1:应用程序代码调用系统调用x(),而这个函数是包装成系统调用的库函数

step2:库函数负责向内核传递参数,触发软中断切换到内核

step3:CPU被中断后,按照中断向量找到中断处理函数并执行中断处理函数,也就是系统调用处理函数

step4:系统调用处理函数调用系统调用服务程序,真正开始处理该系统调用

Socket与系统调用深度分析第1张

Socket与系统调用

Socket API编程接口之上可以编写基于不同网络协议的应用程序,Socket接口在用户态通过系统调用机制进入内核。start_kernel-->trap_init-->idt_setup_traps-->0x80-->entry_INT80。

在这里调用中断指令 int 0x80实现由用户态转向内核态,,当运行到int 0x80这条中断指令时,跳转到entry_INT80_32,这是liunx系统中所有系统调用的入口点。entry_INT80_32不是一段普通的函数,它是一段汇编代码,同时,我们将系统调用号用eax寄存器进行传递,entry_INT80_32通过系统调用号来查询对应的内核处理函数并跳转到相应的内核处理函数执行,完毕后再按顺序逐步返回到用户态。

利用GDB跟踪系统调用过程,我们来用上次创建的MenuOS,运行hello/hi程序,跟踪系统调用的过程。首先在sys_socketcall处打上断点,接下来按c继续运行,看看都调用了哪些函数。

Socket与系统调用深度分析第2张

socket()调用sys_socketcall()系统调用。bind,connect等等函数都需要sys_socketcall()作为入口。

sys_socketcall()里面都有些什么呢?

SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
{
    unsigned longa[AUDITSC_ARGS];
    unsigned longa0, a1;
    interr;
    unsigned intlen;

    if (call < 1 || call >SYS_SENDMMSG)
        return -EINVAL;
    call = array_index_nospec(call, SYS_SENDMMSG + 1);

    len =nargs[call];
    if (len > sizeof(a))
        return -EINVAL;

    /*copy_from_user should be SMP safe. */
    if(copy_from_user(a, args, len))
        return -EFAULT;

    err = audit_socketcall(nargs[call] / sizeof(unsigned long), a);
    if(err)
        returnerr;

    a0 = a[0];
    a1 = a[1];

    switch(call) {
    caseSYS_SOCKET:
        err = __sys_socket(a0, a1, a[2]);
        break;
    caseSYS_BIND:
        err = __sys_bind(a0, (struct sockaddr __user *)a1, a[2]);
        break;
    caseSYS_CONNECT:
        err = __sys_connect(a0, (struct sockaddr __user *)a1, a[2]);
        break;
    caseSYS_LISTEN:
        err =__sys_listen(a0, a1);
        break;
    caseSYS_ACCEPT:
        err = __sys_accept4(a0, (struct sockaddr __user *)a1,
                    (int __user *)a[2], 0);
        break;
    ...
    ...
    default:
        err = -EINVAL;
        break;
    }
    returnerr;
}

免责声明:文章转载自《Socket与系统调用深度分析》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇多级代理 haproxy 传递X-Forwarded-Protoasp中将文本框内的日期转换成datetime类型的数据下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

python-gevent模块实现socket大并发

服务器端:gevent_server.py 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 import sys import socket import time import gev...

文件随机或顺序读写原理深入浅出

一、文件读写的用户程序、操作系统、磁盘交互原理  最近为了彻底搞懂文件读写原理,我特意查询了很多资料,包括Java读写文件的API代码、操作系统处理文件以及磁盘硬件知识等。由于网上现存技术文章,几乎没有找到一篇能够彻底综合讲明白这个原理的文章。心中还是有很多疑问。且有不少文章包括书籍所阐述的随机/顺序读写原理讲述的都是错误或误导性的。所以我综合了一下我能查...

Live555 分析(一):类介绍

从程序的结构来看,live项目包括了四个基本库、程序入口类(在mediaServer中)和一些测试代码(在testProgs中)。 四个基本静态库是UsageEnvironment、BasicUsageEnvironment、groupsock和liveMedia。 UsageEnvironment: 包括抽象类UsageEnvironment和抽象类Ta...

Linux基础知识(一)

    本篇主要介绍Linux操作系统相关知识以及其常用命令等。 一、操作系统的基本知识   一般而言,现代计算机计算机系统是一个复杂的系统,故若程序员需要掌握该系统的每一个细节例如如何通过代码去调用音响等这些事情,那可能不再编写代码了,这种情况会严重影响程序员的开发效率。 并且管理这些部件并加以优化使用,是一件极富挑战性的工作,于是,计算安装了一层软件(...

零拷贝

零拷贝(Zero-copy)技术指在计算机执行操作时,CPU 不需要先将数据从一个内存区域复制到另一个内存区域,从而可以减少上下文切换以及 CPU 的拷贝时间。它的作用是在数据报从网络设备到用户程序空间传递的过程中,减少数据拷贝次数,减少系统调用,实现 CPU 的零参与,彻底消除 CPU 在这方面的负载。实现零拷贝用到的最主要技术是 DMA 数据传输技术...

调用互联网API接口(腾讯、阿里)等出现"未知名称或服务(Name or service not known)"

一、问题 开发反馈程序调用api.mch.weixin.qq.com时,时不时出现"[Errno -2] Name or service not known"错误。 二、排查 1、DNS地址配置为114.114.114.114,偶发出现解析慢的现象 2、可能原因 CentOS 6/7的DNS解析器在解析地址时会同时发出解析ipv4和ipv6的请求,且使用同...