Linux 网络设备驱动
本文将介绍一个 Linux 下网络设备驱动的简单实现,代码基于 Linux Device Driver 的 snull 驱动,介绍该网络设备的注册、打开、写入数据、读出数据等操作,所有示例代码可以在我的 Github 中找到。
设备注册与卸载
基本流程
每个网卡,无论是物理还是虚拟的网卡,都必须有一个 net_device 结构体,这个结构体是在网卡驱动中动态分配创建的,网卡驱动会为每个新的网络接口在一个全局的网络设备列表里插入本网卡对应的 net_device。
初始化 snull 模块需要先创建 net_device 网络设备,正如在 net_device 这篇博客 中所述,设备初始化流程如下所示:
|
|
在卸载 snull 模块时,执行操作如下:
unregister_netdev从系统中删除了接口snull自己的清除函数free_netdev将net_device结构体返回给系统。如果还在什么其他地方对该设备的应用,则它将继续存在,但是驱动程序并不需要关注这一点。
|
|
初始化设备
在申请 net_devices 时使用了 snull_init 函数,其主要用于初始化设备,这里主要是对 net_device 的一些成员进行了初始化。
|
|
在这里面,通过赋值 netdev_ops 函数实现了 snull 模块自己的网络设备操作函数:
|
|
Private Data
在 snull_init 中初始化了 priv 字段,该成员的作用和字符驱动程序中的 private_data 指针的作用类似。处于性能和灵活性方面的考虑,不鼓励直接访问 priv 成员。当驱动程序需要访问私有数据指针式,应当使用 netdev_priv 函数,如上所示。
|
|
下面展示了 snull 模块中具体的私有数据的数据结构,这个结构包含了一个 net_device_stats 结构的实例,它是保存接口统计信息的标准地方。
|
|
Packet Pool
|
|
|
|
设备打开与关闭
|
|
|
|
数据包发送
基本流程
当内核想要发送一个数据包时,会调用驱动程序的 ndo_start_transmit 函数将数据放入外发队列。
|
|
控制并发传输
传输超时
Scatter/Gather I/O
数据包接收
中断处理例程
NAPI 接收
链路状态的改变
MAC 地址解析
定制 ioctl 信息
参考资料
Linked Mentions
-
No backlinks found.