收藏 分享(赏)

netdevice.ppt

上传人:jmydc 文档编号:8647011 上传时间:2019-07-07 格式:PPT 页数:26 大小:402.50KB
下载 相关 举报
netdevice.ppt_第1页
第1页 / 共26页
netdevice.ppt_第2页
第2页 / 共26页
netdevice.ppt_第3页
第3页 / 共26页
netdevice.ppt_第4页
第4页 / 共26页
netdevice.ppt_第5页
第5页 / 共26页
点击查看更多>>
资源描述

1、Linux操作系统分析与实践 第九讲:网络设备驱动程序,Linux操作系统分析与实践课程建设小组 北京大学 二零零八年春季*致谢:感谢Intel对本课程项目的资助,本讲主要内容,网络接口驱动程序 网络接口例子snull,9.1 网络接口驱动程序,网络接口驱动程序和字符设备、块设备驱动程序都不同 本次课介绍一个不和真实硬件相关的“虚拟”网络接口,设备注册, struct net_device 这个结构中包括了网络设备接口需要的很多信息 必须动态分配,例如 struct net_device *snull_devs2; struct net_device *alloc_netdev(int siz

2、eof_priv, const char *name, void (*setup)(struct net_device *); struct net_device *alloc_netdev(int sizeof_priv, /*私有数据区长度 ,驱动程序设计者设计*/ const char *name,/*接口名 */ void (*setup)(struct net_device *)/* 网络接口初始化函数 */);,例子,snull_devs0 = alloc_netdev(sizeof(struct snull_priv), “sn%d“, snull_init);snull_dev

3、s1 = alloc_netdev(sizeof(struct snull_priv), “sn%d“, snull_init); if (snull_devs0 = = NULL | snull_devs1 = = NULL) goto out;,alloc_etherdev,除了alloc_netdev,也有一些简化工作的函数,比如: struct net_device *alloc_etherdev(int sizeof_priv); 这个函数不用驱动程序提供接口初始化函数,网络接口名是 eth%d 这样的形式 在中定义,register_netdev,for (i = 0; i nam

4、e);,初始化设备,ether_setup(dev); /* 对dev的某些域先进行初始化*/ dev-open = snull_open; dev-stop = snull_release; dev-set_config = snull_config; dev-hard_start_xmit = snull_tx; dev-do_ioctl = snull_ioctl; dev-get_stats = snull_stats; dev-rebuild_header = snull_rebuild_header; dev-hard_header = snull_header; dev-tx_t

5、imeout = snull_tx_timeout; dev-watchdog_timeo = timeout; /* keep the default flags, just add NOARP */ dev-flags |= IFF_NOARP; dev-features |= NETIF_F_NO_CSUM; dev-hard_header_cache = NULL; /* Disable caching */,网络设备的一系列操作和 状态标志,程序员定义的结构snull_priv,struct snull_priv struct net_device_stats stats; /统计信

6、息int status;/状态struct snull_packet *ppool;struct snull_packet *rx_queue; /* List of incoming packets */int rx_int_enabled;int tx_packetlen;u8 *tx_packetdata;struct sk_buff *skb;spinlock_t lock; ;,通过netdev_priv()来获得设备 的私有数据区,清理工作,void snull_cleanup(void)int i;for (i = 0; i 2; i+) if (snull_devsi) unr

7、egister_netdev(snull_devsi);snull_teardown_pool(snull_devsi);free_netdev(snull_devsi);return; ,net_device 结构中重要数据介绍,char nameIFNAMSIZ; 网络接口名,如果名字中包括 %d,那么 register_netdev 替换它为唯一名字,从0开始分配数字unsigned long state; 驱动状态struct net_device *next; 在全局接口链表中指向下一个接口结构int (*init)(struct net_device *dev); 初始化函数。被r

8、egister_netdev调用完成初始化。现在一般不使用这个函数,而是在调用register_netdev前就对结构进行初始化,Cont.,unsigned long rmem_end; unsigned long rmem_start; unsigned long mem_end; unsigned long mem_start; Device memory information. These fields hold the beginning and ending addresses of the shared memory used by the device. Rmem 代表接收内

9、存;mem_代表发送内存 unsigned long base_addr; The I/O base address of the network interface. unsigned char irq; The assigned interrupt number. unsigned char if_port; The port in use on multiport devices. unsigned char dma; The DMA channel allocated by the device.,比较重要的网络设备驱动方法,int (*open)(struct net_device

10、*dev); Opens the interface. The interface is opened whenever ifconfig activates it. The open method should register any system resource it needs (I/O ports, IRQ, DMA, etc.), turn on the hardware, and perform any other setup your device requires. int (*stop)(struct net_device *dev); Stops the interfa

11、ce. The interface is stopped when it is brought down. This function should reverse operations performed at open time,Cont.,int (*hard_start_xmit) (struct sk_buff *skb, struct net_device *dev); Method that initiates the transmission of a packet. The full packet (protocol headers and all) is contained

12、 in a socket buffer (sk_buff) structure. Socket buffers are introduced later in this chapter. int (*hard_header) (struct sk_buff *skb, struct net_device *dev, unsigned short type, void *daddr, void *saddr, unsigned len); Function (called before hard_start_xmit) that builds the hardware header from t

13、he source and destination hardware addresses that were previously retrieved; its job is to organize the information passed to it as arguments into an appropriate, device-specific hardware header. eth_header is the default function for Ethernet-like interfaces, and ether_setup assigns this field acco

14、rdingly.,Cont.,void (*tx_timeout)(struct net_device *dev); Method called by the networking code when a packet transmission fails to complete within a reasonable period, on the assumption that an interrupt has been missed or the interface has locked up. It should handle the problem and resume packet

15、transmission.struct net_device_stats *(*get_stats)(struct net_device *dev); Whenever an application needs to get statistics for the interface, this method is called. This happens, for example, when ifconfig or netstat -i is run.int (*set_mac_address)(struct net_device *dev, void *addr); int (*change

16、_mtu)(struct net_device *dev, int new_mtu); maximum transfer unit (MTU),9.2 网络接口例子 snull,打开设备int snull_open(struct net_device *dev) /* request_region( ), request_irq( ), (like fops-open) * Assign the hardware address of the board: use “0SNULx“, where* x is 0 or 1. The first byte is 0 to avoid being

17、a multicast* address (the first byte of multicast addrs is odd). */memcpy(dev-dev_addr, “0SNUL0“, ETH_ALEN);if (dev = = snull_devs1)dev-dev_addrETH_ALEN-1+; /* 0SNUL1 */netif_start_queue(dev);return 0; ,netif_start_queue()使能处理数据; netif_stop_queue()停止处理数据,关闭设备int snull_release(struct net_device *dev)

18、/* release ports, irq and such- like fops-close */netif_stop_queue(dev); /* cant transmit any more */return 0;,Cont.,发送数据,int snull_tx(struct sk_buff *skb, struct net_device *dev)int len;char *data, shortpktETH_ZLEN;struct snull_priv *priv = netdev_priv(dev);data = skb-data;len = skb-len;if (len dat

19、a, skb-len);len = ETH_ZLEN;data = shortpkt;,要发送的数据保存在 Skb-data 指向的位置,从skb-data拷贝数据到要保存 发送数据的缓冲区shortpkt,Cont.,dev-trans_start = jiffies; /* save the timestamp */* Remember the skb, so we can free it at interrupt time */priv-skb = skb;/* actual deliver of data is device-specific, and not shown here *

20、/snull_hw_tx(data, len, dev); return 0; /* Our simple device can not fail */ ,在snull_hw_tx中,实际上我们可以 编写程序实现具体硬件的发送数据 的控制,这里的snull_hw_tx并 没有对哪个具体的硬件进行操作。,snull_hw_tx,/* Transmit a packet (low level interface)*/ static void snull_hw_tx(char *buf, int len, struct net_device *dev) /* This function deals

21、with hw details. This interface loops* back the packet to the other snull interface (if any).* In other words, this function implements the snull behaviour,* while all other procedures are rather device-independent*/struct iphdr *ih;struct net_device *dest;struct snull_priv *priv;u32 *saddr, *daddr;

22、struct snull_packet *tx_buffer;,/* I am paranoid. Aint I? */if (len saddr;daddr = ,if (dev = snull_devs0)PDEBUGG(“%08x:%05i %08x:%05in“,ntohl(ih-saddr),ntohs(struct tcphdr *)(ih+1)-source),ntohl(ih-daddr),ntohs(struct tcphdr *)(ih+1)-dest);elsePDEBUGG(“%08x:%05i daddr),ntohs(struct tcphdr *)(ih+1)-d

23、est),ntohl(ih-saddr),ntohs(struct tcphdr *)(ih+1)-source);/* Ok, now the packet is ready for transmission: first simulate a* receive interrupt on the twin device, then a* transmission-done on the transmitting device*/dest = snull_devsdev = snull_devs0 ? 1 : 0;priv = netdev_priv(dest);tx_buffer = snu

24、ll_get_tx_buffer(dev);tx_buffer-datalen = len;memcpy(tx_buffer-data, buf, len);snull_enqueue_buf(dest, tx_buffer);,if (priv-rx_int_enabled) priv-status |= SNULL_RX_INTR;snull_interrupt(0, dest, NULL);priv = netdev_priv(dev);priv-tx_packetlen = len;priv-tx_packetdata = buf;priv-status |= SNULL_TX_INT

25、R;if (lockup ,Cont.,模拟真实中断的中断处理程序,static void snull_napi_interrupt(int irq, void *dev_id, struct pt_regs *regs) int statusword;struct snull_priv *priv;/* As usual, check the “device“ pointer for shared handlers.* Then assign “struct device *dev“*/struct net_device *dev = (struct net_device *)dev_id;/* . and check with hw if its really ours */* paranoid */if (!dev)return;,Cont.,/* Lock the device */priv = netdev_priv(dev);spin_lock( ,Q&A,本讲结束 !,

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 企业管理 > 管理学资料

本站链接:文库   一言   我酷   合作


客服QQ:2549714901微博号:道客多多官方知乎号:道客多多

经营许可证编号: 粤ICP备2021046453号世界地图

道客多多©版权所有2020-2025营业执照举报