文章目录

  • 前言​
    • 网络协议层接口
    • 网络设备接口层
    • 设备驱动功能层
    • 网络设备驱动的注册与注销
    • 网络设备的初始化
    • 网络设备的打开与释放
    • 数据的发送
    • 数据的接受流程
    • 总结

前言​

与字符设备和块设备不同(通过应用层和驱动层指向同一个文件,通过file_operation作为两者之间的桥梁),网络设备并不对应于/dev目录下的文件,应用程序最终使用套接字完成与 网络设备的接口。因而在网络设备身上并不能体现出“一切都是文件”的思想。

Linux系统对网络设备驱动定义了4个层次,这4个层次为网络协议接口层、网络设备接口层、提供实际功能的设备驱动功能层和网络设备与媒介层。

1)网络协议接口层向网络层协议提供统一的数据包收发接口,不论上层协议是ARP,还是IP,都通 过dev_queue_xmit()函数发送数据,并通过netif_rx()函数接收数据。这一层的存在使得上层协议独立于具体的设备。

2)网络设备接口层向协议接口层提供统一的用于描述具体网络设备属性和操作的结构体net_device, 该结构体是设备驱动功能层中各函数的容器。实际上,网络设备接口层从宏观上规划了具体操作硬件的设 备驱动功能层的结构。

3)设备驱动功能层的各函数是网络设备接口层net_device数据结构的具体成员,是驱使网络设备硬件完成相应动作的程序,它通过hard_start_xmit()函数启动发送操作,并通过网络设备上的中断触发接收操作。

4)网络设备与媒介层是完成数据包发送和接收的物理实体,包括网络适配器和具体的传输媒介,网络适配器被设备驱动功能层中的函数在物理上驱动。对于Linux系统而言,网络设备和媒介都可以是虚拟的。

网络协议层接口

传输层:1、通过dev_queue_xmit()函数发送该数据包/接受通过netif_rx()函数

重要的数据结构sk_buff,又被称为套接字缓冲区。当发送数据包时,Linux内核的网络处理模块必须建立一个包含要传输的数据包的sk_buff,然后将 sk_buff递交给下层,各层在sk_buff中添加不同的协议头直至交给网络设备发送。同样地,当网络设备从网 络媒介上接收到数据包后,它必须将接收到的数据转换为sk_buff数据结构并传递给上层,各层剥去相应的 协议头直至交给用户

网络设备接口层

对不同的网络设备进行统一定义,用结构体net_device来描述

net_device结构体在内核中指代一个网络设备,它定义于include/linux/netdevice.h文件中,网络设备驱动程序只需通过填充net_device的具体成员并注册net_device即可实现硬件操作函数与内核的挂接。

struct net_device{char name[IFNAMESIZ] ; //全局信息unsigned long mem_end ;unsigned long mem_start; //mem_start和mem_end分别定义了设备所使用的共享内存的起始和结束地址unsigned long base_addr; //网络设备I/O基地址unsigned char irq ; // 设备使用的中断号unsigned char if_port; // 指定多端口设备使用哪一个端口,该字段仅针对多端口设备unsigned char dma ;// dma指定分配给设备的DMA通道static int moxart_set_mac_address(struct net_device *ndev, void *addr);//用于存放设备的硬件地址,驱动可能提供了设置MAC地址的接口,这会导致用户设置的MAC地址等const struct net_device_ops *netdev_ops; //设备操作函数}

设备驱动功能层

net_device结构体的成员(属性和net_device_ops结构体中的函数指针)需要被设备驱动功能层赋予具 体的数值和函数。对于具体的设备xxx,工程师应该编写相应的设备驱动功能层的函数,这些函数形如xxx_open()、xxx_stop()、xxx_tx()、xxx_hard_header()、xxx_get_stats()和xxx_tx_timeout()等。

由于网络数据包的接收可由中断引发,设备驱动功能层中的另一个主体部分将是中断处理函数,它负责读取硬件上接收到的数据包并传送给上层协议,因此可能包含xxx_interrupt()和xxx_rx()函数,前者完成中断类型判断等基本工作,后者则需完成数据包的生成及将其递交给上层等复杂工作。

网络设备驱动的注册与注销

网络设备驱动的注册与注销由register_netdev() 和 unregister_netdev()函数完成,这两个函数的原型为:

int register_netdev(struct net_device *dev) ;
void unregister_netdev(struct net_device *dev) ;
1static int xxx_register(void)
{... /* 分配net_device结构体并对其成员赋值 */ xxx_dev = alloc_netdev(sizeof(struct xxx_priv), "sn%d", xxx_init);if (xxx_dev == NULL) ... /* 分配net_device失败 */ /* 注册net_device结构体 */ if ((result = register_netdev(xxx_dev)))... }static void xxx_unregister(void) { ... /* 注销net_device结构体 */ unregister_netdev(xxx_dev); /* 释放net_device结构体 */ free_netdev(xxx_dev); }

网络设备的初始化

网络设备的初始化主要需要完成如下几个方面的工作。

1、进行硬件上的准备工作,检查网络设备是否存在,如果存在,则检测设备所使用的硬件资源。

2、进行软件接口上的准备工作,分配net_device结构体并对其数据和函数指针成员赋值。

3、获得设备的私有信息指针并初始化各成员的值。如果私有信息中包括自旋锁或信号量等并发或同步

机制,则需对其进行初始化。

4、对net_device结构体成员及私有数据的赋值都可能需要与硬件初始化工作协同进行,即硬件检测出了相应的资源,需要根据检测结果填充net_device结构体成员和私有数据。

void xxx_init(struct net_device *dev)
{/* 设备的私有信息结构体 */ struct xxx_priv *priv; /* 检查设备是否存在和设备所使用的硬件资源 */xxx_hw_init();/* 初始化以太网设备的公用成员 */ ether_setup(dev); /* 设置设备的成员函数指针 */ ndev->netdev_ops = &xxx_netdev_ops; ndev->ethtool_ops = &xxx_ethtool_ops; dev->watchdog_timeo = timeout; /* 取得私有信息,并初始化它 */ priv = netdev_priv(dev); ... /* 初始化设备私有数据区 */
}

网络设备的打开与释放

网络设备的打开函数需要完成如下工作:

2、使能设备使用的硬件资源,申请I/O区域、中断和DMA通道等。

1、调用Linux内核提供的netif_start_queue()函数,激活设备发送队列。网络设备的关闭函数需要完成如下工作。

3、调用Linux内核提供的netif_stop_queue()函数,停止设备传输包。

4、释放设备所使用的I/O区域、中断和DMA资源。

static int xxx_open(struct net_device *dev) {/* 申请端口、IRQ等,类似于fops->open */ret = request_irq(dev->irq, &xxx_interrupt, 0, dev->name, dev); ... netif_start_queue(dev);...}static int xxx_release(struct net_device *dev) { /* 释放端口、IRQ等,类似于fops->close */ free_irq(dev->irq, dev); ... netif_stop_queue(dev); /* can't transmit any more */ ... }

数据的发送

Linux网络子系统在发送数据包时,会调用驱动程序提 供的hard_start_transmit()函数,该函数用于启动数据包的发送。在设备初始化的时候,这个函数指针需 被初始化以指向设备的xxx_tx()函数

网络设备驱动完成数据包发送的流程如下。

1)网络设备驱动程序从上层协议传递过来的sk_buff参数获得数据包的有效数据和长度,将有效数据放入临时缓冲区。

2)对于以太网,如果有效数据的长度小于以太网冲突检测所要求数据帧的最小长度ETH_ZLEN,则 给临时缓冲区的末尾填充0。

3)设置硬件的寄存器,驱使网络设备进行数据发送操作。

数据的接受流程

网络设备接收数据的主要方法是由中断引发设备的中断处理函数,中断处理函数判断中断类型,如果 为接收中断,则读取接收到的数据,分配sk_buffer数据结构和数据缓冲区,将接收到的数据复制到数据缓 冲区,并调用netif_rx()函数将sk_buffer传递给上层协议

总结

我们说的Linux的网络设备驱动,可以分为四个部分,网络协议接口层,网络设备接口层,设备驱动功能层,硬件结构层。而贯穿这个四个层,我们在网络设备驱动编写的过程,首先申请的也是这么一个net_device结构体,在这个结构体中就包括DMA通道,中断号,设备的MAC地址以及操作函数,而这个操作函数就是整个网络设备驱动功能层的集合,像这个open,stop等函数,在open中就去实现这个硬件初始化,申请中断号,IO区域,DMA通道等。还有一个比较重要的结构就是缓存区,我们用结构体shr_buff 表示,在Linux中网络数据包就是以这种结构进行传输的,且相关的协议头的添加以及去除,也是通过操作这个结构体来完成的

Linux下的网络设备驱动相关推荐

  1. Linux下的硬件驱动——USB设备配置以及开发

    Linux下的硬件驱动--USB设备(上)(驱动配置部分) USB设备越来越多,而Linux在硬件配置上仍然没有做到完全即插即用,对于Linux怎样配置和使用他们,也越来越成为困扰我们的一大问题.本文 ...

  2. Linux下的硬件驱动——USB设备

    想起当初对于破安卓手机,挂在系统上可是费了好些劲,今偶遇USB驱动开发,收集备用,哪天一生气,说不定也写一个linux下的手机驱动,类似于91手机助手的,也不用配置了. Linux下的硬件驱动--US ...

  3. 嵌入式Linux下彩色LCD驱动的设计与实现

    嵌入式Linux下彩色LCD驱动的设计与实现 转载 摘要:本文介绍了如何在嵌入在开发彩色LCD显示驱动的方法,并对Linux中的显示驱动程序结构和框架作一介绍. 长期以来,在常见的掌上电脑(PDA)等 ...

  4. linux下测试RTC驱动相关的命令date和hwclock常见用法简介

    之前对Linux下面时间相关的内容,一无所知,第一次见到hwclock,不知为何物,也没找到解释清楚的帖子.故此整理一下,简单介绍Linux下验证rtc驱动是否工作正常,相关的的命令:date和hwc ...

  5. linux查看网卡的驱动命令行,Linux下查看网卡驱动和版本信息

    Linux下查看网卡驱动和版本信息 查看网卡生产厂商和信号 查看基本信息:lspci 查看详细信息:lspci -vvv # 3个小写的v 查看网卡信息:lspci | grep Ethernet 查 ...

  6. linux查看当前igb的版本信息,Linux下查看网卡驱动和版本信息

    Linux下查看网卡驱动和版本信息 查看网卡生产厂商和信号 查看基本信息:lspci 查看详细信息:lspci -vvv  # 3个小写的v 查看网卡信息:lspci | grep Ethernet ...

  7. linux显卡驱动卸载和安装,Linux下Nvidia显卡驱动卸载和卸载后的问题

    Linux下Nvidia显卡驱动卸载和卸载后的问题 由于在Ubuntu下安装了Nvidia显卡驱动后开机一直处于循环登录界面,密码输入正确也是进不去,然后就决定卸载Nvidia显卡驱动. 首先是在能使 ...

  8. Linux下的硬件驱动——USB设备(下)

    Linux下的硬件驱动--USB设备(下)(驱动开发部分) 文档选项 打印本页 将此页作为电子邮件发送 未显示需要 JavaScript 的文档选项 级别: 初级 赵明, 联想软件设计中心嵌入式研发处 ...

  9. linux获取网卡协议地址,读取linux下的网络设备的mac地址与发送原始数据包 (2011-11-23 20:11)...

    一:linux下的网络设备 linux的网络设备信息都在/proc/net/dev,从这里我们可以得到所有网卡的名字,如eth0, eth1等等 root@dlrc-desktop:/home/dlr ...

最新文章

  1. CF331A1,331A2
  2. Cisco网院成立10周年-未来三年在蓉增50所
  3. SDNU 1209.磊磊的随机数
  4. Linux预备知识(三):系统调用-用户态/内核态
  5. 微信js-sdk使用
  6. 深圳店匠笔试题-4.01
  7. pytorch1.7教程实验——对抗示例生成FGSM
  8. 通过iLO进行Zabbix监控——针对HP服务器集成
  9. 《Linux杂记》Window读取 Ext3/Ext4文件系统数据
  10. 安装java程序出错
  11. multisim 1.4破解汉化
  12. 计算机考研数据结构代码题总结--Day01
  13. 芬美意2020财年集团收入38.78亿瑞士法郎,增长2.8%
  14. 路由器的级联(LAN-WAN)
  15. 过宝塔php大马,分享宝塔网站防火墙使用帮助
  16. 计算机指令集的相关概念
  17. 任我发财663311conm_任我发财663311-王中王期期公开平特肖_特时代
  18. 记录yolov5更改backbone为ShuffleBlock网络迁移训练出错问题以及解决方法
  19. 高效的六面体变换算法实现(一) —— 等圆柱映射 与 六面体映射(MarkDown编辑器版)
  20. ProMax v2.0.7047 1CD流程模拟软件

热门文章

  1. 移动护理、护士工作站 UI界面及业务
  2. 人工ai智能电话机器人应用市场分析
  3. 滑膜观测器物理意义_PMSM扩展状态滑模观测器和转子位置和速度估算.PDF
  4. 宝藏又小众的球形物体Flash动画素材网站分享
  5. 计算机学家名言 英语,科学家英语名言
  6. 考研政治大题 记忆方法 顺口溜
  7. 开源 串口调试助手 BaoYuanSerial 使用教程
  8. 【计算机毕业设计】医院挂号系统
  9. 视频重播转换器:Replay Converter for Mac
  10. c语言 点运算符,C语言点运算符和箭头运算符