Linux网络设备驱动架構學習(二)

接下來會從以下幾個方面介紹網絡設備驅動的編寫流程:

1、網絡設備的註冊與註銷

2、網絡設備的初始化

3、網絡設備的打開與釋放

4、網絡數據發送流程

5、網絡數據接收流程

6、網絡連接狀態

7、網絡參數設置和統計數據

瞭解了這幾部份內容,網絡設備驅動的編寫方法也就基本明白了

網絡設備的註冊與註銷

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

int register_netdev(struct net_device *dev);

void unregister_netdev(struct net_device *dev);

这两个函数都接收一个 net_device 结构体指针为参数,可见 net_device 数据结构在网络设备驱动中的核心地位。

net_device 的生成和成员的赋值并非一定要由工程师逐个亲自动手完成,可以利用下面的函数帮助我们填充:
struct net_device *alloc_netdev(int sizeof_priv, const char *name, void(*setup) (struct net_device*));

struct net_device *alloc_etherdev(int sizeof_priv);

alloc_netdev()函数生成一个 net_device 结构体,对其成员赋值并返回该结构体的指针。第一个参数为设备私有成员的大小,第二个参数为设备名,第三个参数为net_device 的 setup()函数指针。setup()函数接收的参数也为 struct net_device 指针,用
于预置 net_device 成员的值。

alloc_etherdev()是 alloc_netdev()针对以太网的“快捷”函数。

完成与 alloc_enetdev()和 alloc_etherdev()函数相反功能,即释放 net_device 结构体的函数为:

void free_netdev(struct net_device *dev);

net_device 结构体的分配和网络设备驱动注册需在网络设备驱动程序的模块加载函数中进行,而 net_device 结构体的释放和网络设备驱动的注销则需在模块卸载函数中完成,如代码清单所示。

1   int xxx_init_module(void)
2 {
3 ...
4 /* 分配 net_device 结构体并对其成员赋值 */
5 xxx_dev = alloc_netdev(sizeof(struct xxx_priv), "sn%d", xxx_init);
6 if (xxx_dev == NULL)
7 ... /* 分配 net_device 失败 */
8
9 /* 注册 net_device 结构体 */
10 if ((result = register_netdev(xxx_dev)))
11 ...
12 }
13
14 void xxx_cleanup(void)
15 {
16 ...
17 /* 注销 net_device 结构体 */
18 unregister_netdev(xxx_dev);
19 /* 释放 net_device 结构体 */
20 free_netdev(xxx_dev);
21 }

網絡設備的初始化

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

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

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

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

对 net_device 结构体成员及私有数据的赋值都可能需要与硬件初始化工作协同进行,即硬件检测出了相应的资源,需要根据检测结果填充 net_device 结构体成员和私有数据。 一个网络设备驱动初始化函数的模板如代码清单所示,具体的设备驱动初始化函数并不一定完全和本模板一样,但是其本质过程是一致的。

1   void xxx_init(struct net_device *dev)
2 {
3 /*设备的私有信息结构体*/
4 struct xxx_priv *priv;
5
6 /* 检查设备是否存在和设备所使用的硬件资源 */
7 xxx_hw_init();
8
9 /* 初始化以太网设备的公用成员 */
10 ether_setup(dev);
11
12 /*设置设备的成员函数指针*/
13 dev->open = xxx_open;
14 dev->stop = xxx_release;
15 dev->set_config = xxx_config;
16 dev->hard_start_xmit = xxx_tx;
17 dev->do_ioctl = xxx_ioctl;
18 dev->get_stats = xxx_stats;
19 dev->change_mtu = xxx_change_mtu;
20 dev->rebuild_header = xxx_rebuild_header;
21 dev->hard_header = xxx_header;
22 dev->tx_timeout = xxx_tx_timeout;
23 dev->watchdog_timeo = timeout;
24
25 /*如果使用 NAPI,设置 pool 函数*/
26 if (use_napi)
27 {
28 dev->poll = xxx_poll;
29 }
30
31 /* 取得私有信息,并初始化它*/
32 priv = netdev_priv(dev);
33 ... /* 初始化设备私有数据区 */
34 }

上述代码第 7 行的 xxx_hw_init()函数完成硬件相关的初始化操作,如下所示。

1、探测 xxx 网络设备是否存在。探测的方法类似于数学上的“反证法”,即先假设存在设备 xxx,访问该设备,如果设备的表现与预期的一致,就确定设备存在;否则,假设错误,设备 xxx 不存在。

2、探测设备的具体硬件配置。一些设备驱动编写得非常通用,对于同类的设备使用统一的驱动,我们需要在初始化时探测设备的具体型号。另外,即便是同一设备,在硬件上的配置也可能不一样,我们也可以探测设备所使用的硬件资源。

3、申请设备所需要的硬件资源,如用 request_region()函数进行 I/O 端口的申请等,但是这个过程可以放在设备的打开函数 xxx_open()中完成。

針對Mini2440 DM9000 驱动probe方法做一個分析就可以對上面兩個過程有一個更清晰的認識

請移步:Mini2440 DM9000 驱动分析(三)

網絡設備的打開與釋放

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

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

2、调用 Linux 内核提供的 netif_start_queue()函数,激活设备发送队列。

网络设备的关闭函数需要完成如下工作。

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

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

Linux 内核提供的 netif_start_queue()和 netif_stop_queue()两个函数的原型为:

void netif_start_queue(struct net_device *dev);

void netif_stop_queue (struct net_device *dev);

根据以上分析,可得出如代码清单所示的网络设备打开和释放函数的模板。

1   int xxx_open(struct net_device *dev)
2 {
3 /* 申请端口、IRQ 等,类似于 fops->open */
4 ret = request_irq(dev->irq, &xxx_interrupt, 0, dev->name, dev);
5 ...
6 netif_start_queue(dev);
7 ...
8 }
9
10 int xxx_release(struct net_device *dev)
11 {
12 /* 释放端口、IRQ 等,类似于 fops->close */
13 free_irq(dev->irq, dev);
14 ...
15 netif_stop_queue(dev); /* can't transmit any more */
16 ...
17 }

針對Mini2440 DM9000 驱动open,stop方法做一個分析就可以對上面兩個過程有一個更清晰的認識

請移步:Mini2440 DM9000 驱动分析(四)

Linux网络设备驱动架構學習(二)的更多相关文章

  1. Linux网络设备驱动架構學習(三)

    Linux网络设备驱动架構學習(三) 接下來會從以下幾個方面介紹網絡設備驅動的編寫流程: 1.網絡設備的註冊與註銷 2.網絡設備的初始化 3.網絡設備的打開與釋放 4.網絡數據發送流程 5.網絡數據接 ...

  2. linux设备驱动归纳总结(十二):简单的数码相框【转】

    本文转载自:http://blog.chinaunix.net/uid-25014876-id-116926.html linux设备驱动归纳总结(十二):简单的数码相框 xxxxxxxxxxxxxx ...

  3. linux网络设备驱动

    Linux网络设备驱动 Linux网络驱动程序的体系结构可划分为4个层次.Linux内核源代码中提供了网络设备接口及以网络子系统的上层的代码,移植特定网络硬件的驱动程序的主要工作就是完成设备驱动功能层 ...

  4. 【Linux开发】linux设备驱动归纳总结(十二):简单的数码相框

    linux设备驱动归纳总结(十二):简单的数码相框 xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx ...

  5. linux 网络设备驱动

    linux 网络驱动 谨以此文纪念过往的岁月 一.前言在linux中网络驱动也是一个大头,如何去理解网络驱动是作为一个linux驱动工程师必备的技能.不过同样的设备,在不同人的手中会有不同的效果,其原 ...

  6. Linux网络设备驱动(一) _驱动模型

    Linux素来以其强大的网络功能著名,同时, 网络设备也作为三大设备之一, 成为Linux驱动学习中必不可少的设备类型, 此外, 由于历史原因, Linux并没有强制对网络设备贯彻其"一切皆 ...

  7. Linux网络设备驱动架构

    Linux网络设备驱动程序体系结构分为四层:网络协议接口层.网络设备接口层.提供实际功能的设备驱动层以及网络设备与媒介层. (1)网络协议接口层向网络层协议提供统一的数据包收发接口,不论上层协议是AR ...

  8. Linux网络设备驱动 _驱动模型

    Linux素来以其强大的网络功能著名,同时, 网络设备也作为三大设备之一, 成为Linux驱动学习中必不可少的设备类型, 此外, 由于历史原因, Linux并没有强制对网络设备贯彻其"一切皆 ...

  9. Linux 网络设备驱动开发(一) —— linux内核网络分层结构

    Preface Linux内核对网络驱动程序使用统一的接口,并且对于网络设备采用面向对象的思想设计. Linux内核采用分层结构处理网络数据包.分层结构与网络协议的结构匹配,既能简化数据包处理流程,又 ...

随机推荐

  1. 使用phpstorm+wamp实现php代码实时调试审计

    转载自:https://www.bugbank.cn/q/article/5853afaffc0bf4f010ee6ac3.html php调试有N多好用的工具,最近研究到phpstorm配合wamp ...

  2. 常用 Git 命令清单【转】

    转自:http://www.ruanyifeng.com/blog/2015/12/git-cheat-sheet.html 作者: 阮一峰 日期: 2015年12月 9日 我每天使用 Git ,但是 ...

  3. 基于 Apache 在本地配置多个虚拟主机

    如何使用 Apache 在本地配置出多个虚拟主机呢?而且使用不同的“域名”来访问本地不同的站点呢? 一般情况下,咱们都使用 localhost 来访问本机上的服务器,在我们的 C:/WINDOWS/s ...

  4. 使用crontab命令添加计划任务

    Ubuntu 16.04, 计划任务 就是 有(时间)计划地执行(做)任务,有计划 包括 定时执行(在哪些时间点执行任务).按照周期执行(每隔多少时间执行任务). 那么,什么是任务呢?就是 自己想要干 ...

  5. HTTP2.0新特性

    参考:http://www.tuicool.com/articles/mq2qm26

  6. Android 7.0 行为变更

    Android 7.0 除了提供诸多新特性和功能外,还对系统和 API 行为做出了各种变更.本文重点介绍您应该了解并在开发应用时加以考虑的一些主要变更. 如果您之前发布过 Android 应用,请注意 ...

  7. Coursera台大机器学习技法课程笔记13-Deep Learning

    深度学习面临的问题和现在解决的办法: 简要来说,分两步使用DL:初始化时一层一层的选择权重,而后再进行训练: 那么怎么做pre-training,即怎么选择权重呢?好的权重能够不改变原有资料的信息,即 ...

  8. javaweb笔记七

    过滤器:是一个web中间组件,用于拦截从客户端发送给服务器的请求和响应.当客户端向服务器发出请求时,服务器会查看是否有过滤器和该请求匹配,如果有,则交给过滤器执行,业务操作后,可以将请求继续向目标资源 ...

  9. ElastAlert告警

    ElastAlert告警 https://blog.csdn.net/qq_38369069/article/details/80842432

  10. maven 配置阿里云仓库

    <mirror>     <id>nexus-aliyun</id>     <mirrorOf>*</mirrorOf>     < ...