前言

网络子系统是 Linux 内核的重中之重。今天,我们从网卡驱动入手,开始网络子系统的探索之路。

硬件环境

树莓派3B+,搭载千兆网卡 LAN7515,不过其使用的是 USB2.0 通道(最高理论速度为480Mbps),官方给出 300Mbps 的以太网传输速率。

驱动

LAN7515 的驱动为 lan78xx,源码比较简单,就两个文件 ./linux/drivers/net/usb/lan78xx.c/h,编译后产生 lan78xx.ko 驱动文件。

驱动分析

1. USB 驱动注册

static struct usb_driver lan78xx_driver = {.name            = DRIVER_NAME,.id_table        = products,.probe          = lan78xx_probe,.disconnect        = lan78xx_disconnect,.suspend      = lan78xx_suspend,.resume          = lan78xx_resume,.reset_resume     = lan78xx_reset_resume,.supports_autosuspend   = 1,.disable_hub_initiated_lpm = 1,
};module_usb_driver(lan78xx_driver);

LAN7515 是 USB 网卡,和 CPU 交互的接口为 USB,所以它是一个 USB 设备,要在内核注册它的 USB 驱动——lan78xx.ko。
insmod lan78xx.ko 即在 USB 总线上注册 LAN7515 网卡驱动,此时,会遍历 USB 总线上已注册的设备,用总线的 match 方法判断是否有匹配的设备,如果有,则调用驱动的 probe 函数。
具体看一下:

/sys/bus/usb/ 下有 devices 和 drivers 目录,这两个目录下分别是当前系统中 USB 总线上已注册的设备已注册的驱动
可以看到,在 drivers 目录中目前还没有 lan78xx 驱动,并且我们也不知道 devices 目录中的哪个 USB 设备为 LAN7515 设备。
下面我们安装 lan78xx 驱动

看到执行了 lan78xx_probe() 函数,这也印证了我们上面的说法(注册驱动,会遍历设备,寻求匹配,匹配成功,触发 probe)。
我们再次查看 /sys/bus/usb/drivers 下的目录情况

可以看到,已经产生了 lan78xx 目录,说明驱动注册成功了。

2. 驱动和设备绑定

在 lan78xx_probe() 函数中调用了 lan78xx_bind() 方法,正式地将 lan78xx 驱动和 1-1.1.1:1.1 设备绑定了起来。在 lan78xx 目录下也能体现这一点。

我们也可以手动绑定和解绑

# ifconfig -a
lo        Link encap:Local Loopback  inet addr:127.0.0.1  Mask:255.0.0.0inet6 addr: ::1/128 Scope:HostUP LOOPBACK RUNNING  MTU:65536  Metric:1RX packets:42 errors:0 dropped:0 overruns:0 frame:0TX packets:42 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000 RX bytes:4478 (4.3 KiB)  TX bytes:4478 (4.3 KiB)
# ls
bind       module     new_id     remove_id  uevent     unbind
# echo "1-1.1.1:1.0" > bind
[37493.831496] lan78xx_probe()
[37494.126379] lan78xx 1-1.1.1:1.0 (unnamed net_device) (uninitialized): No External EEPROM. Setting MAC Speed
[37494.144756] libphy: lan78xx-mdiobus: probed
[37494.264385] lan78xx 1-1.1.1:1.0 (unnamed net_device) (uninitialized): int urb period 64
[37494.276093] lan78xx_phy_init()
# ls
1-1.1.1:1.0  module       remove_id    unbind
bind         new_id       uevent
# ifconfig -a
eth0      Link encap:Ethernet  HWaddr B8:27:EB:8A:BC:F4  BROADCAST MULTICAST  MTU:1500  Metric:1RX packets:0 errors:0 dropped:0 overruns:0 frame:0TX packets:0 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000 RX bytes:0 (0.0 B)  TX bytes:0 (0.0 B)lo        Link encap:Local Loopback  inet addr:127.0.0.1  Mask:255.0.0.0inet6 addr: ::1/128 Scope:HostUP LOOPBACK RUNNING  MTU:65536  Metric:1RX packets:42 errors:0 dropped:0 overruns:0 frame:0TX packets:42 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000 RX bytes:4478 (4.3 KiB)  TX bytes:4478 (4.3 KiB)
#
#
# echo "1-1.1.1:1.0" > unbind
# ls
bind       module     new_id     remove_id  uevent     unbind
# ifconfig -a
lo        Link encap:Local Loopback  inet addr:127.0.0.1  Mask:255.0.0.0inet6 addr: ::1/128 Scope:HostUP LOOPBACK RUNNING  MTU:65536  Metric:1RX packets:42 errors:0 dropped:0 overruns:0 frame:0TX packets:42 errors:0 dropped:0 overruns:0 carrier:0collisions:0 txqueuelen:1000 RX bytes:4478 (4.3 KiB)  TX bytes:4478 (4.3 KiB)
#

3. 数据收发

以 PC1 数据链路层发送一个数据包给 PC2 数据链路层为例

rx

tasklet_schedule(&dev->bh);   // USB 收到数据时,产生中断,触发该任务
lan78xx_bh()lan78xx_rx_bh()rx_submit()usb_fill_bulk_urb()   // 从 USB 读取数据tasklet_schedule(&dev->bh);lan78xx_bh()rx_process()lan78xx_rx()lan78xx_skb_return()
-----上面为驱动-------下面为数据链路层-----------------------netif_rx()  // 送入数据链路层

tx

struct net_device_ops {.ndo_start_xmit       = lan78xx_start_xmit,
}
-----上面为数据链路层-------下面为驱动-----------------------
lan78xx_start_xmit()skb_queue_tail()    // 插入队列tasklet_schedule(&dev->bh);   // 触发任务调度 lan78xx_bhlan78xx_bh()lan78xx_tx_bh()skb_dequeue()    // 取出数据
------上面为驱动网络部分--------下面为驱动 USB 部分-----------usb_fill_bulk_urb()   // 填充数据到 USBusb_submit_urb()    // USB 发送数据

RX call tree:目前理得有点混乱,大致过程是 USB 硬件产生中断,驱动去捞数据,经过 rx_process() 处理后,最终调用 netif_rx(skb),将数据送入内核网络子系统,进一步处理 skb。
TX call tree:内核网络子系统最终调用 ndo_start_xmit() 发送数据,该接口最终由设备驱动实现,本示例为 lan78xx_start_xmit(),最终将数据通过 USB 发送给 LAN7515 网卡,网卡再经过自己的硬件加工,最终将数据发送到网线。

打印帧头

static netdev_tx_t
lan78xx_start_xmit(struct sk_buff *skb, struct net_device *net)
{printk("%s()\n", __FUNCTION__);struct ethhdr *eth = eth_hdr(skb);
printk(KERN_INFO "DEST:" MAC_FMT "\n", MAC_ARG(eth->h_dest));
printk(KERN_INFO "SOURCE:" MAC_FMT "\n", MAC_ARG(eth->h_source));struct iphdr *ip_header = ip_hdr(skb);
printk("daddr:%x is %d.%d.%d.%d\n", ip_header->daddr, inet_ntoa(ip_header->daddr));
printk("saddr:%x is %d.%d.%d.%d\n\n", ip_header->saddr, inet_ntoa(ip_header->saddr));
...
[44851.676380] lan78xx_start_xmit()
[44851.680906] DEST:08:00:27:38:fc:d0
[44851.685656] SOURCE:b8:27:eb:8a:bc:f4
[44851.690571] daddr:6401a8c0 is 192.168.1.100
[44851.696164] saddr:101a8c0 is 192.168.1.1

打印 TX 方向,驱动送给网卡的数据帧中的目的 MAC、源 MAC、目的 IP、源 IP,即上图中 ① 处的数据帧头。

总结

网卡、网卡驱动、内核网络子系统,它们干的事情核心就是传递数据包,其中 sk_buff 在整个过程中起着穿针引线的作用,这次分析网卡驱动收发的过程中,也尝试打印了 sk_buff 的部分信息,作为一个探索的开始吧。其实 sk_buff 在网络子系统中确实起着非常重要的作用,sk_buff 是 socket buffer 的意思,这又进一步体现了 socket 的重要,连其 buffer 都那么 NB,socket 不更 NB 吗?所以后面的研究路线是:driver --> sk_buff --> socket。

USB网卡收发数据分析相关推荐

  1. 水星UD6S网卡Linux驱动,水星UD6S无线usb网卡驱动程序下载-水星网络UD6S网卡驱动1.0 最新版-东坡下载...

    UD6S专业的无线usb网卡,在目前来说是很多的家庭以及办公室都是会使用到的,你可以通过官方的水星网络UD6S网卡驱动进行全方面的管理! 官方介绍 UD6S双频无线网卡适用于台式 PC 机.笔记本等设 ...

  2. linux安装comfast网卡驱动,电脑如何通过usb共享手机网络 Linux安装wifi 无线网络 811AC usb网卡驱动...

    电脑如何通过usb共享手机网络 该方法是通过USB线将手机和电脑连接的方式来共享网络,所以不管是笔记本电脑还是台式机,不管电脑有无线网卡,都可以使用该方法. 准备工作:首先用数据线把手机连接到电脑上, ...

  3. 为USB网卡(水星MW150US)编译树莓派上的驱动

    为什么80%的码农都做不了架构师?>>>    在淘宝上找了一圈,最便宜的USB网卡就是水星的这款MW150US了,二十几块钱搞定,还包邮 到手后发现树莓派压根就不识别.....网上 ...

  4. ch9200 usb网卡驱动_21包邮的PCMCIA无线网卡开箱+对比测评

    本文是我原创,经我授权发表在贵乎,原文链接:21包邮的PCMCIA无线网卡开箱+对比测评 本篇教程是之前说的18包邮的PCMCIA无线网卡的对比 关于PCMCIA无线网卡 PCMCIA无线网卡优点是兼 ...

  5. CentOS8中如何支持TL-WDN7200H无线USB网卡?

    今日在笔记本电脑ThinkBook 14 IML接入TP-LINK的TL-WDN7200H AC 1900双频高增益无线USB网卡,支持2.4GHz 600Mbps+5GHz 1300Mbps. Wi ...

  6. linux usb网卡驱动 ko,qf9700 USB网卡在x86 linux和arm linux上的驱动安装以及配置

    最近要在一块老板子上面移植openwrt,需要扩展网口,于是选择了qf9700这款USB网卡,附赠的光盘里面有提供在linux下面安装的驱动源代码,所以我们要自己编译驱动源代码生成内核加载模块,加载模 ...

  7. Debian系统源码安装usb网卡驱动

    系统为debian 9.6 64位版本,安装网卡驱动为asix的 AX88772B芯片 1. 安装系统build模块 apt-get install linux-image-$(uname -r) l ...

  8. Nanopi r4s usb网卡设置方法(MT7601U Wireless Adapter)

    解决方案: Nanopi r4s -- usb网卡设置方法(MT7601U Wireless Adapter): 写在前面! 该方案只针对 Nanopi r4s ! 之前购买USB无线网卡时就看过,官 ...

  9. 【智能无线小车系列七】在树莓派上使用USB网卡

    在这个腾"云"驾"物"(云:云计算,物:物联网)的时代,什么都可以没有,就是不能没有网络,树莓派也离不开它.本章节将详细介绍如何将树莓派接入互联网,因为有一些后 ...

  10. Linux驱动移植USB网卡r8156驱动(详细)总结

    目录 一.简介 二.驱动移植 2.1 驱动源码解压 2.2 驱动Kconfig和Makefile配置 2.2.1 驱动上层目录识别驱动文件 2.2.2 驱动目录新建驱动Kconfig和Makefile ...

最新文章

  1. 支付宝被曝光了一段视频,或许“刷脸支付”的时代就要来临了
  2. 4.Android loader详解___回调
  3. 阿里财报:云计算年度营收133亿,季度营收连续12个季度翻番
  4. web前端基础(12js基础介绍)
  5. form表单提交和重置小结
  6. 雅礼集训Day3-难题选讲
  7. 固高板卡mct2008调试轴回零_固高运动控制的Home回零过程
  8. [python][pandas]pandas数据处理+直方图绘制
  9. 网站搭建的流程是什么
  10. FFmpeg 视频处理
  11. 中国各路神仙!!!!
  12. Oracle学习3:dual详解
  13. 02 面向对象设计的七大原则
  14. 为什么说石油币是一场“国家骗局”?
  15. 825. Friends Of Appropriate Ages**
  16. 图的遍历(染色法判断奇环)
  17. 不定方程非负整数解个数
  18. 单例模式及其线程安全问题
  19. 百度地图计算两坐标点之间距离计算
  20. 微搭低代码数据源新能力详解

热门文章

  1. 数模转换器(DAC)——百度百科
  2. 《Linux内核设计与实现》读书笔记(八)- 中断下半部的处理
  3. 【BZOJ】3993: [SDOI2015]星际战争
  4. Android反编译工具合集
  5. 为女性们点赞!Google 为女性提供更多支持
  6. 工业镜头景深计算及工业镜头技术分析
  7. Mono.Cecil简介与示例
  8. 录屏软件哪个好?快来试试这几款吧!
  9. 读后感—肿瘤基因检测行业会好吗
  10. 小布机器人怎么断网_华硕“小布”智能机器人上手体验:造型呆萌可爱 全年龄段适用...