嵌入式Linux网络体系结构设计与TCP/IP协议栈(五)

本文详细介绍了Linux内核中套接字层的实现,包括套接字的基本功能、API系统调用的实现原理以及地址族和协议交换表的管理。重点讨论了struct socket和struct sk_buff数据结构,以及系统调用如何通过系统调用表和软件中断机制在内核中执行。
摘要由CSDN通过智能技术生成

第10章 套接字层实现

Linux内环中支持的套接字结构
在这里插入图片描述
套接字的基本功能:

  • 传输数据
  • 为TCP管理连接
  • 控制或调节TCP/IP协议栈的操作

套接字层API构成

  • 网络功能 (由struct prot数据结构描述)
  • 将网络的操作映射到Linux常规I/O操作上,这样应用程序人员就可以如调用普通文件I/O操作一样使用TCP/IP来传送和接收数据 (struct proto_ops数据结构描述)

管理套接字传送数据的结构是Socket Buffer,struct sk_buff数据结构中存放了套接字接收/发送的数据。

每个程序使用套接字都有一个struct socket数据结构与struct sock数据结构的实例,这两个结构包含套接字通用属性,独立于具体协议;具体的协议族与协议实例继承通用套接字的属性,形成管理协议本身套接字的结构。

在这里插入图片描述

struct socket 是一个通用数据结构,存放的是套接字层的控制和状态信息;每个打开的套接字都有一个struct socket数据结构的实例;包含一个文件描述符可由应用程序代码引用,该文件描述符从套接字层返回给应用程序。

struct socket {
	socket_state		state;  //当前套接字状态
	short			type;   //套接字的类型
	unsigned long		flags;  //套接字等待缓冲区的状态信息
	const struct proto_ops	*ops;   //套接字层的操作函数块
	struct fasync_struct	*fasync_list;   //等待被唤醒的套接字列表,该链表用于异步文件调用
	struct file		*file;  //套接字所属的文件描述符
	struct sock		*sk;    //指向存放套接字属性的结构指针
	wait_queue_head_t	wait;   //套接字的等待队列
};

说明:

  • *ops 定义了一组套接字层的标志操作函数指针供应用程序调用,函数指针直接与socketcall系统调用存放的函数指针一一对应;
  • *file 套接字所属的文件描述符,在创建和打开套接字时,套接字层向应用程序返回该文件描述符,应用程序通过文件描述符访问套接字。

10.1 地址族的值和协议交换表

struct inet_protosw实现协议交换表,管理和描述套接字层对应系统调用套接字操作函数struct proto_ops *ops 、与内核协议相关套接字操作函数块struct proto *prot 。

struct inet_protosw {
	struct list_head list;

        /* These two fields form the lookup key.  */
    //套接字类型
	unsigned short	 type;	   /* This is the 2nd argument to socket(2). */
	unsigned short	 protocol; /* This is the L4 protocol number.  */
    //指向协议实例实现的套接字操作函数块数据结构
	struct proto	 *prot;
    //指向套接字层对应的socketcall系统调用,是套接字操作函数块数据结构的指针。
	const struct proto_ops *ops;
    //使用该套接字的权限
	int              capability; /* Which (if any) capability do
				      * we need to use this socket
				      * interface?
                                      */
    //对接收、发送数据包是否做校验和
	char             no_check;   /* checksum on rcv/xmit/none? */
    //属性的相关标志。
	unsigned char	 flags;      /* See INET_PROTOSW_* below.  */
};

在这里插入图片描述

10.2 套接字API系统调用的实现

实现系统调用的基本过程如下:

  • 内核实现了一系列的系统调用,所有系统调用函数以sys_为前缀名,对应用户程序的函数调用;内核为每个系统调用分配一个索引号,索引号与系统调用函数对应关系保存在系统调用表system call table中。
  • 用户程序调用参数在用户地址空间,内核功能函数要访问这些参数,需将其从用户地址空间映射到内核地址空间(X86 CPU体系结构,将存放用户数据地址的指针放入CPU的寄存器中,传给内核代码,然后内核代码将用户数据复制到内核地址空间,这项功能由copy_from_user函数完成)
  • 如果系统调用成功,则向用户程序返回正整数或0。如果不成功,则系统调用向用户程序返回错误代码。
    在这里插入图片描述

在应用层程序调用套接字API时,应用层的函数调用转换为内核协议实例函数需经过以下步骤:

  1. 将用户地址空间参数映射到内核地址空间
  2. 将常规套接字层的函数调用转换到某协议族的函数
  3. 将协议族的函数调用传递给协议实例的网络功能函数

10.2.1 系统调用实现原理

基本机制:
Linux下的系统调用是通过0x80实现的,每个系统调用都有相应的系统调用号作为唯一的标识,内核维护一张系统调用表, sys_call_table,表中的元素是系统调用函数的起始地址,而系统调用号就是系统调用在调用表的偏移量。在x86上,系统调用号是通过eax寄存器传递给内核的。
通知内核的机制是靠软件中断实现的。首先,用户程序为系统调用设置参数。其中一个参数是系统调用编号。参数设置完成后,程序执行“系统调用”指令。x86系统上的软中断由int产生。这个指令会导致一个异常:产生一个事件,这个事件会致使处理器切换到内核态并跳转到一个新的地址,并开始执行那里的异常处理程序。此时的异常处理程序实际上就是系统调用处理程序。它与硬件体系结构紧密相关。
新地址的指令会保存程序的状态,计算出应该调用哪个系统调用,调用内核中实现那个系统调用的函数,恢复用户程序状态,然后将控制权返还给用户程序。

https://www.cnblogs.com/alantu2018/p/8991310.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
嵌入式Linux网络体系结构设计TCP/IP协议紧密相关。嵌入式Linux操作系统是为嵌入式设备设计的一种轻量级操作系统,而TCP/IP协议是网络通信中最基础的协议。在嵌入式Linux中,网络体系结构设计的目标是实现高效稳定的网络通信功能。 嵌入式Linux网络体系结构设计通常由两部分组成:网络驱动程序和协议。网络驱动程序负责与物理网络接口进行通信,处理硬件设备的输入输出以及网络数据包的传输。而协议则负责解析网络数据包,进行协议的处理和数据包的封装转发。 TCP/IP协议是网络通信中最常用的协议,它包含了网络层的IP协议、传输层的TCP和UDP协议以及应用层的各种协议。在嵌入式Linux中,TCP/IP协议设计需考虑性能、资源占用和可靠性等因素。 嵌入式Linux网络体系结构设计需要根据具体的应用场景进行调整。对于资源有限的嵌入式设备,可以选择裁剪协议中的某些功能来降低资源占用。同时,还需要考虑网络通信的性能和延迟要求,合理分配处理器和内存资源,以确保网络通信的稳定和高效。 在实际开发中,可以选择成熟的开源TCP/IP协议,如Linux内核自带的协议或者lwIP协议等。这些协议经过长期的实践和优化,已具备较高的稳定性和可靠性,并且可以根据需要进行灵活的配置和扩展。 总之,嵌入式Linux网络体系结构设计TCP/IP协议紧密相关,需要综合考虑资源占用、性能和可靠性等因素,选择合适的协议,并根据具体应用场景进行调整,以实现高效稳定的网络通信功能。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值