一、Socket接口在用户态通过系统调用机制进入内核;
- 内核态:控制计算机的硬件资源,并提供上层应用程序运行的环境。此时处理器处于特权级最高的(0级)内核代码中执行。
- 用户态:上层应用程序的活动空间,应用程序的执行必须依托于内核提供的资源。此时处理器在特权级最低的(3级)用户代码中运行。
- 系统调用:为了使上层应用能够访问到这些资源,内核为上层应用提供访问的接口。
三者之间的关系:用户态下的应用程序,通过系统调用的方式,访问内核态中的资源。
Socket API :socket可以看成是用户进程与内核网络协议栈的编程接口。TCP/IP协议的底层部分已经被内核实现了,而应用层是用户需要实现的,这部分程序工作在用户空间。用户空间的程序需要通过套接字来访问内核网络协议栈。
Socket接口在用户态通过系统调用机制进入内核的过程为:
用户态下的应用程序通过Socket API 请求系统调用,从而进入内核态访问内核中的TCP/IP的底层协议栈。
二、内核中将系统调用作为一个特殊的中断来处理
系统调用被称为软中断,是应用程序主动进入内核的方式,是借助于中断异常机制实现的。有一条特殊指令,使得用户态和内核态得以切换(在linux中为 int 0x80)。
![](https://img2018.cnblogs.com/common/1805739/201912/1805739-20191219110928977-1839474152.png)
系统调用过程:
- 中断异常机制:硬件保护现场,查询中断向量表,cpu控制权转移至系统调用总入口程序。
- 系统调用总入口程序:保存现场,把参数保存到内核的堆栈中,查询系统调用表,将cpu控制权转交给相应内核函数
- 执行系统调用例程
- 恢复现场,返回用户进程
以socket相关系统调用为例进行分析
反汇编menu目录下的init文件,共有5处int $0x80的汇编指令,其中一处如图所示:
验证了内核中将系统调用作为一个特殊的中断来处理。
![](https://img2018.cnblogs.com/common/1805739/201912/1805739-20191219111021243-1373189506.png)
验证 x86-64位系统下的系统调用初始化过程:start_kernel --> trap_init --> cpu_init --> syscall_init
进入menu目录,修改Makefile文件,并执行 make rootfs #打开menuos 。
![](https://img2018.cnblogs.com/common/1805739/201912/1805739-20191219190629450-21996327.png)
在linux-5.0.1目录下,打开一个新的终端,执行命令如下:
设置断点成功,验证了x86-64位系统下的系统调用初始化过程。
gdb file vmlinux target remote:1234 b start_kernel b trap_init b cpu_init b syscall_init
![](https://img2018.cnblogs.com/common/1805739/201912/1805739-20191219190832117-863153593.png)
三、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 但获取不到断点。。。。
![](https://img2018.cnblogs.com/common/1805739/201912/1805739-20191219191310610-54636495.png)
发现是Makefile设置错误,修正后,运行结果如下:
![](https://img2018.cnblogs.com/common/1805739/201912/1805739-20191219191501136-2092172413.png)
可见在replyhi 执行过程中,调用了socket()、bind()、listen()等api 。