⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ch17s03.html

📁 Linux设备驱动经典
💻 HTML
📖 第 1 页 / 共 2 页
字号:
<html xmlns:cf="http://docbook.sourceforge.net/xmlns/chunkfast/1.0"><head><meta http-equiv="Content-Type" content="text/html; charset=gb2312"><title>17.3.&#160;net_device 结构的详情-Linux设备驱动第三版(中文版)</title><meta name="description" content="驱动开发" /><meta name="keywords" content="Linux设备驱动,中文版,第三版,ldd,linux device driver,驱动开发,电子版,程序设计,软件开发,开发频道" /><meta name="verify-v1" content="5asbXwkS/Vv5OdJbK3Ix0X8osxBUX9hutPyUxoubhes=" /><link rel="stylesheet" href="docbook.css" type="text/css"><meta name="generator" content="DocBook XSL Stylesheets V1.69.0"><link rel="start" href="index.html" title="Linux 设备驱动 Edition 3"><link rel="up" href="ch17.html" title="第&#160;17&#160;章&#160;网络驱动"><link rel="prev" href="ch17s02.html" title="17.2.&#160;连接到内核"><link rel="next" href="ch17s04.html" title="17.4.&#160;打开与关闭"></head><body bgcolor="white" text="black" link="#0000FF" vlink="#840084" alink="#0000FF"><div class="navheader"><table width="100%" summary="Navigation header"><tr><th colspan="3" align="center">17.3.&#160;net_device 结构的详情</th></tr><tr><td width="20%" align="left"><a accesskey="p" href="ch17s02.html">上一页</a>&#160;</td><th width="60%" align="center">第&#160;17&#160;章&#160;网络驱动</th><td width="20%" align="right">&#160;<a accesskey="n" href="ch17s04.html">下一页</a></td></tr></table><hr></div><div class="sect1" lang="zh-cn"><div class="titlepage"><div><div><h2 class="title" style="clear: both"><a name="ThenetdeviceStructureinDetail"></a>17.3.&#160;net_device 结构的详情</h2></div></div></div><p>net_device 结构处于网络驱动层的非常核心的位置并且值得完全的描述. 这个列表描述了所有成员, 更多的是提供了一个参考而不是用来备忘. 本章剩下的部分简要地描述了每个成员, 一旦它用在例子代码上, 因此你不需要不停地回看这一节.</p><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="GlobalInformation"></a>17.3.1.&#160;全局信息</h3></div></div></div><p>结构 net_device 的第一部分是由下面成员组成:</p><div class="variablelist"><dl><dt><span class="term"><span> char name[IFNAMSIZ];</span></span></dt><dd><p>设备名子. 如果名子由驱动设置, 包含一个 %d 格式串, register_netdev 用一个数替换它来形成一个唯一的名子; 分配的编号从 0 开始.</p></dd><dt><span class="term"><span>unsigned long state;</span></span></dt><dd><p>设备状态. 这个成员包括几个标志. 驱动正常情况下不直接操作这些标志; 相反, 提供了一套实用函数. 这些函数在我们进入驱动操作后马上讨论这些函数.</p></dd><dt><span class="term"><span>struct net_device *next;</span></span></dt><dd><p>全局列表中指向下一个设备的指针. 这个成员驱动不能动.</p></dd><dt><span class="term"><span>int (*init)(struct net_device *dev);</span></span></dt><dd><p>一个初始化函数. 如果设置了这个指针, 这个函数被 register_netdev 调用来完成对 net_device 结构的初始化. 大部分现代的网络驱动不再使用这个函数; 相反, 初始化在注册接口前进行.</p></dd></dl></div></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="HardwareInformation"></a>17.3.2.&#160;硬件信息</h3></div></div></div><p>下面的成员包含了相对简单设备的低层硬件信息. 它们是早期 Linux 网络的延续; 大部分现代驱动确实使用它们(可能的例外是 if_port ). 我们为完整起见在这里列出.</p><div class="variablelist"><dl><dt><span class="term"><span>unsigned long rmem_end;</span></span></dt><dd></dd><dt><span class="term"><span>unsigned long rmem_start;</span></span></dt><dd></dd><dt><span class="term"><span>unsigned long mem_end;</span></span></dt><dd></dd><dt><span class="term"><span>unsigned long mem_start;</span></span></dt><dd><p>设备内存信息. 这些成员持有设备使用的共享内存的开始和结束地址. 如果设备有不同的接收和发送内存, mem 成员由发送内存使用, rmem 成员由接收内存使用. rmem 成员在驱动之外从不被引用. 惯例上, 设置 end 成员, 所以 end - start 是可用的板上内存的数量.</p></dd><dt><span class="term"><span>unsigned long base_addr;</span></span></dt><dd><p>网络接口的 I/O 基地址. 这个成员, 如同前面的, 由驱动在设备探测时赋值. ifconfig 目录可用来显示或修改当前值. base_addr 可以当系统启动时在内核命令行中显式赋值( 通过 netdev= 参数), 或者在模块加载时. 这个成员, 象上面描述过的内存成员, 内核不使用它们.</p></dd><dt><span class="term"><span>unsigned char irq;</span></span></dt><dd><p>安排的中断号. 当接口被列出时 ifconfig 打印出 dev-&gt;irq 的值. 这个值常常在启动或者加载时间设置并且在后来由 ifconfig 打印.</p></dd><dt><span class="term"><span>unsigned char if_port;</span></span></dt><dd><p>在多端口设备中使用的端口. 例如, 这个成员用在同时支持同轴线(IF_PORT_10BASE2)和双绞线(IF_PORT_100BSAET)以太网连接. 完整的已知端口类型设置定义在 &lt;linux/netdevie.h&gt;.</p></dd><dt><span class="term"><span>unsigned char dma;</span></span></dt><dd><p>设备分配的 DMA 通道. 这个成员只在某些外设总线时有意义, 例如 ISA. 它不在设备驱动自身以外使用, 只是为了信息目的( 在 ifconfig ) 中.</p></dd></dl></div></div><div class="sect2" lang="zh-cn"><div class="titlepage"><div><div><h3 class="title"><a name="InterfaceInformation"></a>17.3.3.&#160;接口信息</h3></div></div></div><p>有关接口的大部分信息由 ether_setup 函数正确设置(或者任何其他对给定硬件类型适合的设置函数). 以太网卡可以依赖这个通用的函数设置大部分这些成员, 但是 flags 和 dev_addr 成员是特定设备的, 必须在初始化时间明确指定.</p><p>一些非以太网接口可以使用类似 ether_setup 的帮助函数. deviers/net/net_init.c 输出了一些类似的函数, 包括下列:</p><div class="variablelist"><dl><dt><span class="term"><span>void ltalk_setup(struct net_device *dev);</span></span></dt><dd><p>设置一个 LocalTalk 设备的成员</p></dd><dt><span class="term"><span>void fc_setup(struct net_device *dev);</span></span></dt><dd><p>初始化光通道设备的成员</p></dd><dt><span class="term"><span>void fddi_setup(struct net_device *dev);</span></span></dt><dd><p>配置一个光纤分布数据接口 (FDDI) 网络的接口</p></dd><dt><span class="term"><span>void hippi_setup(struct net_device *dev);</span></span></dt><dd><p>预备给一个高性能并行接口 (HIPPI) 的高速互连驱动的成员</p></dd><dt><span class="term"><span>void tr_setup(struct net_device *dev);</span></span></dt><dd><p>处理令牌环网络接口的设置</p></dd></dl></div><p>大部分设备会归于这些类别中的一类. 如果你的是全新和不同的, 但是, 你需要手工赋值下面的成员:</p><div class="variablelist"><dl><dt><span class="term"><span>unsigned short hard_header_len;</span></span></dt><dd><p>硬件头部长度, 就是, 被发送报文前面在 IP 头之前的字节数, 或者别的协议信息. 对于以太网接口 hard_header_len 值是 14 (ETH_HLEN).</p></dd><dt><span class="term"><span>unsigned mtu;</span></span></dt><dd><p>最大传输单元 (MTU). 这个成员是网络层用作驱动报文传输. 以太网有一个 1500 字节的 MTU (ETH_DATA_LEN). 这个值可用 ifconfig 改变.</p></dd><dt><span class="term"><span>unsigned long tx_queue_len;</span></span></dt><dd><p>设备发送队列中可以排队的最大帧数. 这个值由 ether_setup 设置为 1000, 但是你可以改它. 例如, plip 使用 10 来避免浪费系统内存( 相比真实以太网接口, plip 有一个低些的吞吐量).</p></dd><dt><span class="term"><span>unsigned short type;</span></span></dt><dd><p>接口的硬件类型. 这个 type 成员由 ARP 用来决定接口支持什么样的硬件地址. 对以太网接口正确的值是 ARPHRD_ETHER, 这是由 ether_setup 设置的值. 可认识的类型定义于 &lt;linux/if_arp.h&gt;.</p></dd><dt><span class="term"><span>unsigned char addr_len;</span></span></dt><dd></dd><dt><span class="term"><span>unsigned char broadcast[MAX_ADDR_LEN];</span></span></dt><dd></dd><dt><span class="term"><span>unsigned char dev_addr[MAX_ADDR_LEN];</span></span></dt><dd><p>硬件 (MAC) 地址长度和设备硬件地址. 以太网地址长度是 6 个字节( 我们指的是接口板的硬件 ID ), 广播地址由 6 个 0xff 字节组成; ether_setup 安排成正确的值. 设备地址, 另外, 必须以特定于设备的方式从接口板读出, 驱动应当将它拷贝到 dev_addr. 硬件地址用来产生正确的以太网头, 在报文传递给驱动发送之前. snull 设备不使用物理接口, 它创造自己的硬件接口.</p></dd><dt><span class="term"><span>unsigned short flags;</span></span></dt><dd></dd><dt><span class="term"><span>int features;</span></span></dt><dd><p>接口标志(下面详述)</p></dd></dl></div><p>这个 flags 成员是一个位掩码, 包括下面的位值. IFF_ 前缀代表 "interface flags". 有些标志由内核管理, 有些由接口在初始化时设置来表明接口的能力和其他特性. 有效的标志, 对应于 &lt;linux/if.h&gt;, 有:</p><div class="variablelist"><dl><dt><span class="term"><span>IFF_UP</span></span></dt><dd><p>对驱动这个标志是只读的. 内核打开它当接口激活并准备号传送报文时.</p></dd><dt><span class="term"><span>IFF_BROADCAST</span></span></dt><dd><p>这个标志(由网络代码维护)说明接口允许广播. 以太网板是这样.</p></dd><dt><span class="term"><span>IFF_DEBUG</span></span></dt><dd><p>这个标识了调试模式. 这个标志用来控制你的 printk 调用的复杂性或者用于其他调试目的. 尽管当前没有 in-tree 驱动使用这个标志, 它可以通过 ioctl 来设置和重置, 你的驱动可用它. misc-progs/netifdebug 程序可以用来打开或关闭这个标志.</p></dd><dt><span class="term"><span>IFF_LOOPBACK</span></span></dt><dd><p>这个标志应当只在环回接口中设置. 内核检查 IFF_LOOPBACK , 以代替硬连线 lo 名子作为一个特殊接口.</p></dd><dt><span class="term"><span>IFF_POINTOPOINT</span></span></dt><dd><p>这个标志说明接口连接到一个点对点链路. 它由驱动设置或者, 有时, 由 ifconfig. 例如, plip 和 PPP 驱动设置它.</p></dd><dt><span class="term"><span>IFF_NOARP</span></span></dt><dd><p>这个说明接口不能进行 ARP. 例如, 点对点接口不需要运行 ARP, 它只能增加额外的流量却没有任何有用的信息. snull 在没有 ARP 能力的情况下运行, 因此它设置这个标志.</p></dd><dt><span class="term"><span>IFF_PROMISC</span></span></dt><dd><p>这个标志设置(由网络代码)来激活混杂操作. 缺省地, 以太网接口使用硬件过滤器来保证它们只接收广播报文和直接到接口硬件地址的报文. 报文嗅探器, 例如 tcpdump, 在接口上设置混杂模式来存取在接口发送介质上经过的所有报文.</p></dd><dt><span class="term"><span>IFF_MULTICAST</span></span></dt><dd><p>驱动设置这个标志来表示接口能够组播发送. ether_setup 设置 IFF_MULTICAST 缺省地, 因此如果你的驱动不支持组播, 必须在初始化时清除这个标志.</p></dd><dt><span class="term"><span>IFF_ALLMULTI</span></span></dt><dd><p>这个标志告知接口接收所有的组播报文. 内核在主机进行组播路由时设置它, 前提是 IFF_MULTICAST 置位. IFF_ALLMULTI 对驱动是只读的. 组播标志在本章后面的"组播"一节中用到.</p></dd><dt><span class="term"><span>IFF_MASTER</span></span></dt><dd></dd><dt><span class="term"><span>IFF_SLAVE</span></span></dt><dd><p>这些标志由负载均衡代码使用. 接口驱动不需要知道它们.</p></dd><dt><span class="term"><span>IFF_PORTSEL</span></span></dt>

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -