既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!
由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新
下面我们安装 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.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:42 errors:0 dropped:0 overruns:0 frame:0
TX packets:42 errors:0 dropped:0 overruns:0 carrier:0
collisions: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:1
RX packets:0 errors:0 dropped:0 overruns:0 frame:0
TX packets:0 errors:0 dropped:0 overruns:0 carrier:0
collisions: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.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:42 errors:0 dropped:0 overruns:0 frame:0
TX packets:42 errors:0 dropped:0 overruns:0 carrier:0
collisions: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.0
inet6 addr: ::1/128 Scope:Host
UP LOOPBACK RUNNING MTU:65536 Metric:1
RX packets:42 errors:0 dropped:0 overruns:0 frame:0
TX packets:42 errors:0 dropped:0 overruns:0 carrier:0
collisions: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_bh
lan78xx_bh()
lan78xx_tx_bh()
skb_dequeue() // 取出数据
------上面为驱动网络部分--------下面为驱动 USB 部分-----------
usb_fill_bulk_urb() // 填充数据到 USB
usb_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__);
![img](https://img-blog.csdnimg.cn/img_convert/1247768e2db2722a4db5e724cb4be925.png)
![img](https://img-blog.csdnimg.cn/img_convert/0d9f3d07171881dc4fbfc562fc89d7b9.png)
**网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。**
**[需要这份系统化的资料的朋友,可以添加戳这里获取](https://bbs.csdn.net/topics/618658159)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**
戳这里获取](https://bbs.csdn.net/topics/618658159)**
**一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!**