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

📄 (ldd) ch14-网络驱动程序(上)(转载).txt

📁 献给ARM初学者
💻 TXT
📖 第 1 页 / 共 3 页
字号:
      plip和ppp一类点到点协议使用这个域记录连接另一侧的IP号码。和前面的域一样,它也
      是只读的。

      是只读的。
       
      unsigned short flags;
       
      接口标志。这个域含有下列位值。前缀IFF意为接口标志(InterFace Flags)。有些标
      志由核心管理,有些则是在初始化时由接口设置,以确认接口的能力。有效的标志是:
       
      IFF_UP
       
      当接口是活跃的时,核心置上该标志。这个标志对驱动程序是只读的。
       
      IFF_BROADCAST
       
      这个标志表明接口的播送地址是有效的。以太网卡支持播送。
       
      IFF_DEBUG
       
      查错模式。这标志控制printk调用的唠叨,还用在其它一些查错目的。尽管目前没有官
      方驱动程序使用它,用户程序可以通过ioctl来对其置位或者清除,你的驱动程序可以使
      用它。misc-progs/netifdebug程序可以用来将这个标志打开或关闭。
       
      IFF_LOOPBACK
       

       
      这个标志在环回接口中要被置位。核心检测这个标志而不是将名字lo作为特殊接口硬写
      入程序。
       
      IFF_POINTOPOINT
       
      点到点的初始化函数应置位这个标志。例如,plip对它置位。ifconfig工具也可以对其
      置位和清除。当它被置位时,dev->pa_dstaddr应该指向连接的另一端。
       
      IFF_NOARP
       
      常规网络接口可以传送ARP包。如果接口不能进行ARP,它必须置这个标志。例如,点到
      点接口并不需要运行ARP,它只能增加额外的通信,却不能获取任何有用的信息。snull
      不具有ARP能力,因此它要对其置位。
       
      IFF_PROMISC
       
      这个标志被置位以获得杂类操作。在缺省情况下,以太网接口使用硬件过滤器以保证它
      只收到播送包和指向其硬件地址的包。而象tcpdump一类包监视器则在接口上设置杂类模
      式,以获取经过接口传输介质的所有包。
       
      IFF_MULTICAST
       

       
      能进行选播传送的接口要置这个标志。ether_setup在缺省情况下对其置位。所以如果你
      的驱动程序不支持选播,它必须在初始化时清除这个标志。
       
      IFF_ALLMULTI
       
      这个标志告诉接口接收所有的选播包。只有当IFF_MULTICAST被置位,而主机由进行选播
      路由时,核心对其置位。它对接口时只读的。IFF_MULTICAST和IFF_ALLMULTI早在1.2版
      就已经定义了,但那时并未使用。在后面“选播”一节我们将看到它是如何使用的。
       
      IFF_MASTER
       
      IFF_SLAVE
       
      这些标志被加载均衡代码使用。接口驱动程序不需要知道它们。
       
      IFF_NOTRAILERS
       
      IFF_RUNNING
       
      这些标志在Linux中不使用,只是为了和BSD兼容而存在。
       
      当一个程序改变IFF_UP,open和close方法会被调用。当IFF_UP或其它标志被修改时,se

      当一个程序改变IFF_UP,open和close方法会被调用。当IFF_UP或其它标志被修改时,se
      t_multicast_list方法被调用。如果驱动程序因为标志的修改而要执行一些动作,那么
      必须在set_multicast_list中进行。例如,当IFF_PROMIS被置位或清除时,板上硬件过
      滤器必须被通知。这个设备方法的责任将在后面的“选播”一节简单介绍。
       
       
       
      设备方法
       
      与字符设备和块设备的情况一样,每个网络设备要声明在其上操作的函数。可以在网络
      接口上进行的操作列在下面。一些操作可以留为NULL,还有一些通常不去动它们,因为e
      ther_setup给它们分配合适的方法。
       
      一个网络接口的设备方法可以分为两类:基本的和可选的。基本的包括那些为访问接口
      所需要的;可选的方法实现一些并不严格要求的高级功能。下面是基本方法:
       
      int (*open)(struct device *dev);
       
      打开接口。只要ifconfig激活一个接口,它就被打开了。open方法要注册它需要的所有
      资源(I/O端口,IRQ,DMA,等),打开硬件,增加模块的使用计数。
       
      int (*stop)(struct device *dev);
       

       
      终止接口。接口在关闭时就终止了;在打开时进行的操作应被保留。
       
      int (*hard_start_xmit)(struct sk_buff *skb, struct device *dev);
       
      硬件开始传送。这个方法请求一个包的传送。这个包含在一个套接字缓冲区结构(sk_bu
      ff)中。套接字缓冲区在下面介绍。
       
      int (*rebuild_header)(void *buf, struct device *dev, unsigned long raddr,
      struct sk_buffer *skb);
       
      这个函数用来在一个包传送之前重构硬件包头。这个以太网设备使用的缺省包头用ARP向
      包中填入缺少的信息。snull驱动程序实现了它自己的这个方法,因为ARP并不在sn接口
      上运行。(在本章的后面会介绍ARP。)这个方法的参数是一些指针,分别指向硬件包头
      ,设备,“路由器地址”(包的初始目的地),以及被传送的缓冲区。
       
      int (*hard_header)(struct sk_buffer *skb, struct device *dev, unsigned
      short type,
       
                                     void *daddr, void *saddr, unsigned len);
       
      硬件包头。这个函数用以前获取的源和目的地址构造包头;它的任务是组织那些以参数
      的形式传给它的信息。eth_header是以太网类接口的缺省函数, ether_setup相应地对

      的形式传给它的信息。eth_header是以太网类接口的缺省函数, ether_setup相应地对
      这个域赋值。给出的参数顺序适用于核心2.0或更高版本,但与1.2有所不同。这个改变
      对以太网驱动程序是透明的,因为它继承了 eth_header的实现;其它驱动程序可能要处
      理一下这个不同,如果它们想保持向后兼容的话。
       
      struct enet_statistics * (*get_stats)(struct device *dev);
       
      当应用希望获得接口的统计信息时需要调用这个方法,例如,当运行ifconfig或netstat
       –i时。在snull中的一个示例实现将在后面“统计信息”中介绍。
       
      int (*set_config)(struct device *dev, struct ifmap *map);
       
      改变接口的配置。这个方法是配置驱动程序的入口点。设备的I/O地址和中断号可以在运
      行时用set_config改变。在接口不能探测到时,系统管理员可以适用这个能力。这个方
      法在后面的“运行时配置”中介绍。
       
       
       
      其余的设备方法是被我称为可选的那些。传递给其中一些的参数在Linux1.2到Linux2.0
      的转变中改了好几次。如果你想写一个可以在两个版本核心都工作的驱动程序,你可以
      只为从2.0开始的版本实现这些操作。
       
      int (*do_ioctl)(struct devices *dev, struct ifreg *ifr, int cmd);

      int (*do_ioctl)(struct devices *dev, struct ifreg *ifr, int cmd);
       
      执行接口特定的ioctl命令。这些命令的实现在后面的“自定义ioctl命令”中描述。这
      里给出的原形在1.2以上的核心都能工作。如果接口不需要任何接口特定的命令,那么结
      构device中相应的域可以留为NULL。
       
      void (*set_multicast_list)(struct device *dev);
       
      当设备的选播列表改变和标志改变时,将调用这个方法。这里的参数传递与1.2版本不同
      。更多的细节和一个示例实现见“选播”一节。
       
      int (*set_mac_address)(struct device *dev, void *addr);
       
      如果接口支持改变硬件地址的能力,可实现这个函数。多数接口要么不支持这个能力,
      要么使用缺省的eth_mac_addr实现。这个原形与1.2版也不同。
       
      #define HAVE_HEADER_CACHE
       
      void (*header_cache_bind)(struct hh_cache **hhp, struct device *dev,
      unsigned short htype, __u32 daddr);
       
      void (*header_cache_update)(struct hh_cache *hh, struct device *dev,
      unsigned char *haddr);

      unsigned char *haddr);
       
      这些函数和宏在Linux1.2中没有。以太网驱动程序不必关心header_cache的问题,因为e
      th_setup会安排使用缺省的方法。
       
      #define HAVE_CACHE_MTU
       
      int (*change_mtu)(struct device *dev, int new_mtu);
       
      如果接口的MTU(最大传送单元)发生了改变,这个函数负责采取动作。这个函数和宏在
      Linux1.2中都没有。当MTU改变时,如果驱动程序要做一些特殊的事情,它应该声明它自
      己的函数,不然将由缺省函数来完成。如果你感兴趣,snull有一个这个函数的模版。
       
       
       
      工具域
       
      其余的结构device中的域被接口用来保存一些有用的状态信息。其中一些被ifconfig和n
      etstat用来向用户提供当前配置的信息。因此,接口应该对这些域赋值。
       
      unsigned long trans_start;
       
      unsigned long last_rx;

      unsigned long last_rx;
       
      这两个域用来保存一些瞬间值。它们目前不用,但核心有可能将来使用这些计时提示。
      驱动程序负责在传送开始时和收到包时更新这些值。trans_start域还可以被驱动程序用
      来检测锁定。驱动程序可以在等待一个“传送完成”的中断时用trans_start来检查超时
       
      void *priv
       
      等价于filp->private_data。驱动程序拥有这个指针,可以随意使用。通常这个私有数
      据结构含有一个enet_statistics结构项。这个域在以前的“初始化每个设备”中用过。
       
       
      unsigned char if_prot;
       
      这个域用来记录哪个硬件端口被接口使用(例如,BNC,AUI,TP)。任何数值都可以按
      需要赋给它。
       
      unsigned char dma;
       
      被接口使用的DMA通道。这个域被ioctl的SIOCGIFMAP命令使用。
       
      struct dev_mc_list *mc_list;

       
      unsigned char dma;
       
      被接口使用的DMA通道。这个域被ioctl的SIOCGIFMAP命令使用。
       
      struct dev_mc_list *mc_list;
       
      int mc_count
       
      这两个域被用来处理选播传送。Mc_count是mc_list中项的个数。更多的细节见“选播”
      结构device中还有一些别的域,但驱动程序没有使用它们
      --
      

⌨️ 快捷键说明

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