Socket 与系统调用深度分析

一、实验环境准备

uname -a

在本机编译linux 5.0.1 X86-64内核,重新按照64位方式编译,步骤同上一篇博客。

make x86_64_defconfig
make menuconfig
make  #编译内核

二、Socket与系统调用

1.socket

  1. Socket API编程接口之上可以编写基于不同网络协议的应用程序;
  2. Socket接口在用户态通过系统调用机制进入内核;
  3. 内核中将系统调用作为一个特殊的中断来处理,以socket相关系统调用为例进行分析;
  4. socket相关系统调用的内核处理函数内部通过“多态机制”对不同的网络协议进行的封装方法。

2.系统调用

  1. 系统调用就是为了让应用程序可以访问系统资源,每个操作系统都会提供一套接口供应用程序使用。这些接口通常通过中断来实现,linux使用0x80号中断作为系统的调用的入口。
  2. 系统调用的弊端:各个操作系统的系统调用不兼容,使用不方便,系统调用比较原始。运行库解决这两个问题,它的使用统一不会随着操作系统或编译器的变化而变化。
  3. 系统调用的原理:系统调用是运行在内核态的,而用户程序一般是运行在用户态的,操作系统一般通过中断从用户态切换到内核态。中断具有两个属性一个是中断号,一个是中断向量表,是一个数组,包含中断处理程序。一个中断号对应一个中断处理程序。中断分为硬件中断和软件中断,软件中断通常是一条指令,带有一个参数代表中断号。在linux中使用0x80来触发所有的系统调用。和中断一样系统调用都有一个系统调用号,系统调用号代表在系统调用表中的位置。

3.系统调用表

vi linux-5.0.1/arch/sh/include/uapi/asm/unistd_64.h

从中可以看到与socket相关的调用号。

三、GDB调试

1.启用gdb调试系统启动

vi LinuxKernel/menu/Makefile
cd menu
make rootfs

在图形化界面启动menu后,用终端打开gdb:

查找资料得知,我本机是32位linux,gdb为32位,无法调试64位程序。因此,下面为基于32位linux内核的调试。

  在系统启动后,可以看到,内核的初始化完成了以下的函数调用过程:start_kernel > trap_init > idt_setup_traps, 其中start_kernal是内核启动的入口函数。

2.gdb调试socket

这一次我们在__sys_listen加入断点

可以看到,当我在Qemu中输入replyhi后,进入断点

在sys_socketcall加入断点,输入了replyhi后,可以看到该方法被调用了4次

Socket本质上是一个glibc中的函数,执行实际上是是调用sys_socketcall()系统调用。sys_socketcall()是几乎所有socket相关函数的入口,即是说,bind,connect等等函数都需要sys_socketcall()作为入口。省略号省略掉的是各种网络编程用得到的函数,全部都在这个系统调用中,socketcall是系统所有socket相关函数打大门。

SYSCALL_DEFINE2(socketcall, int, call, unsigned long __user *, args)
{
     unsigned long a[6];
     unsigned long a0, a1;
     int err;
     unsigned int len;
     if (call < 1 || call > SYS_SENDMMSG)
             return -EINVAL;
     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;
     audit_socketcall(nargs[call] / sizeof(unsigned long), a);
     a0 = a[0];
     a1 = a[1];
     switch (call) {
     case SYS_SOCKET:
             err = sys_socket(a0, a1, a[2]);
             break;
     case SYS_BIND:
             err = sys_bind(a0, (struct sockaddr __user *)a1, a[2]);
             break;
    //...
     default:
             err = -EINVAL;
             break;
     }
     return err;
 }

原文地址:https://www.cnblogs.com/tanhao1410/p/12066356.html

时间: 2024-10-05 04:04:40

Socket 与系统调用深度分析的相关文章

Socket与系统调用深度分析

Socket与系统调用深度分析 可以想象的是,当应用程序调用socket()接口,请求操作系统提供服务时,必然会系统调用,内核根据发起系统调用时传递的系统调用号,判断要执行的程序,若为socket对应的编号,则执行socket对应的中断服务程序.服务程序内部,又根据你要请求的不同服务,来执行不同服务对应的处理程序.当处理结束,执行返回,从中断服务程序到发起中断的int 0x80,再到用户态我们执行的用户程序,层层返回,socket()也就执行完毕了. 本次,我们关心三个问题: 1.应用程序如何如

【Socket系统调用】Socket与系统调用深度分析

Socket与系统调用深度分析 系统调用 在一开始,应用程序是可以直接控制硬件的,这就需要程序员有很高的编程能力,否则一旦程序出了问题,会将整个系统Crash. 在现在的操作系统中,用户程序运行在用户态,而要进行诸如Socket.磁盘I/O这样的一些操作,这需要切换到内核态,再进行进行相应的操作,而这一过程则是系统调用system call.有了操作系统分离了内核和用户态,应用程序就无法直接进行硬件资源的访问,需要经过系统调用来进行. 每次的系统调用,都会从用户态转换到内核态,运行完任务后,回到

Socket与系统调用深度分析 ——X86 64环境下Linux5.0以上的内核中

1.Socket与系统调用——概述 Socket API编程接口之上可以编写基于不同网络协议的应用程序: Socket接口在用户态通过系统调用机制进入内核: 内核中将系统调用作为一个特殊的中断来处理,以socket相关系统调用为例进行分析: socket相关系统调用的内核处理函数内部通过“多态机制”对不同的网络协议进行的封装方法: 下面会将Socket API编程接口.系统调用机制及内核中系统调用相关源代码. socket相关系统调用的内核处理函数结合起来分析,并在X86 64环境下Linux5

基于x86-64 Linux-5.0.1的Socket与系统调用深度分析

一.Socket API编程接口 Libc库中定义的一些应用编程接口(Application Program Interface, API)引用了封装例程(Wrapper Routine),一般一个封装例程对应一个系统调用,大部分封装例程返回一个整数,其值含义依赖于相应的系统调用,-1在多数情况下表示内核不能满足进程的请求,Libc中定义的errno变量包含特定的出错码.C语言中的Socket API就是一种涉及系统调用的API,常用的函数如下: int socket(int domain, i

socket系统调用深度分析

1.系统调用过程 1.1用户态和内核态以及系统调用机制 1.进程的地址空间 linux进程有4GB地址空间,如图所示: 3G-4G大部分是共享的,是内核态的地址空间.这里存放整个内核的代码和所有的内核模块以及内核所维护的数据. 2.特权级别 对于任何操作系统来说,创建一个进程是核心功能.创建进程要做很多工作,会消耗很多物理资源.比如分配物理内存,父子进程拷贝信息,拷贝设置页目录页表等等,这些工作得由特定的进程去做,所以就有了特权级别的概念.最关键的工作必须交给特权级最高的进程去执行,这样可以做到

Pin截获socket系统调用初步分析

Pin截获socket系统调用初步分析 根据为知笔记中上传的Pin tool for tracing system calls,修改代码过滤出socket相关的系统调用,并进行初步的分析.主要有2点: - 过滤socket相关的系统调用 - 分析得到的系统调用参数 过滤socket相关的系统调用 socket编程中与访问网络相关的主要关注socket().accept().然后在PinTool中过滤出这两个系统调用,对他们的参数进行初步的分析.下面先看一下这两个函数: int socket(in

Socket与内核调用深度分析

------------恢复内容开始------------ 1 概念 Linux的设计哲学之一就是:对不同的操作赋予不同的执行等级,就是所谓特权的概念,即与系统相关的一些特别关键的操作必须由最高特权的程序来完成.Intel的X86架构的CPU提供了0到3四个特权级,数字越小,特权越高,Linux操作系统中主要采用了0和3两个特权级,分别对应的就是内核态(Kernel Mode)与用户态(User Mode). 内核态:CPU可以访问内存所有数据,包括外围设备(硬盘.网卡),CPU也可以将自己从

深度分析:Android中Mms设置页面更改短信中心号码流程

相关控件初始化方法:showSmscPref private void showSmscPref() { int count = MSimTelephonyManager.getDefault().getPhoneCount(); boolean airplaneModeOn = Settings.System.getInt(getContentResolver(), Settings.System.AIRPLANE_MODE_ON, 0) != 0; for (int i = 0; i < c

read系统调用深度剖析

本文转自:http://blog.csdn.net/unbutun/article/details/6101354#ibm-pcon Read 系统调用在用户空间中的处理过程 Linux 系统调用(SCI,system call interface)的实现机制实际上是一个多路汇聚以及分解的过程,该汇聚点就是 0x80 中断这个入口点(X86 系统结构).也就是说,所有系统调用都从用户空间中汇聚到 0x80 中断点,同时保存具体的系统调用号.当 0x80 中断处理程序运行时,将根据系统调用号对不同