Linux Network device driver (i) _ Drive model

Source: Internet
Author: User

Linux has always been known for its strong network capabilities, while equipment ' > network equipment is also one of the three major devices that are essential for Linux-driven learning, and because of historical reasons, Linux does not enforce its "all documents" concept for Devices ' > network devices. , the device ' > network device does not use the device file in/dev as the interface, and the user program uses the socket as the interface to access the hardware. Taking Linux3.14.0 kernel As an example, this paper discusses the network driving model in Linux.
Linux devices ' > network devices do not use files as user programs to access devices ' > Network device interfaces, so there is no corresponding device ' > Network device files under/sys/dev and/dev, in Linux, the user program eventually uses sockets to access the device ' > Network equipment.

Framework

is the classic OSI 7 layer model, the Linux network card driver is in the OSI model data link layer, his duty is to send the upper layer of the protocol stack sent over the network card, \
The Linux network-driven model uses a 4-tier structure:

    • The protocol interface layer provides a unified packet sending interface to the network protocol, the upper layer any form of protocol is sent through Dev_queue_xmit (), received through NETIF_RX (), all use Sk_buff as the carrier of the data
    • The Device Interface layer provides a unified framework for describing specific devices ' > Network device properties and operations, and the structure of the device-driven functional layer of the specific operating hardware, which is a container for the functions of the device-driven function layer, is provided to the Protocol interface layer, Net_device The main task of developing a network driver is to write the functions that drive the function layer to populate the contents of the Net_device data structure and register the Net_device with the kernel
    • Each function of the driving function layer is the specific member of the device ' > Network Device Interface layer Net_device data structure, is the program that drives the device ' > Network device Hardware to complete the corresponding action, it initiates the sending action through the Ndo_start_xmit () function, and receiving operations via interrupts on the device ' > network devices, through interrupts or poll mechanisms
    • The device and media layer is the physical entity that completes the data sending and receiving, the network card is physically driven by the function in the device driver layer, and for the Linux system, the device ' > network equipment and media can be virtual

2nd and 3rd layer is the main concern of driving development level

Brief introduction to Core classes and methods

When analyzing the core object and the core method, find out where to provide the interface and where to operate the hardware.????

Core class
    • Sk_buff is the carrier of information in network-driven framework, and it is the carrier of layer-by-layer packaging and layer unpacking of data in network hierarchical model.
    • The net_device object describes a device ' > Network device, * * the struct net_device_ops *netdev_ops is a set of operating methods that provides an interface upward while also operating the hardware
    • netdev_ops a device ' > Network device operation Method set
    • As with other model frameworks, the Net_device object also provides a domain that hosts private data, but does not use void *, see below Alloc_ethdev
Core approach
    • Dev_queue_xmit () is a network protocol interface layer to send data down the interface, the kernel has been implemented, do not need device ' > Network device driver implementation
    • Ndo_start_xmit () is the device ' > Network device interface layer to send data down the interface, located in Net_device->net_device_ops, will be Dev_queue_xmit () callback, Requires network-driven implementation
    • Netif_rx () is the interface of the device ' > Network device interface layer to send data upwards, without network-driven implementation
    • The interrupt handler function is the entry of the device ' > Network device's media layer to send data upwards after receiving the data, need the network drive implementation, and finally call NETIF_RX ()
Core classes and methods detailed Sk_buff

Socket buffer is the carrier of data transmission in multi-layer model, the end result of which is the network packet, and Linux skillfully uses the mobile head/tail pointer to realize the processing of each layer of data packet in the network model. The Sk_buff section is defined as follows

 427 struct Sk_buff {428/* these. must be first. */429 struct Sk_buff *next; 430 struct Sk_buff *prev; 432 ktime_t Tstamp; 434 struct sock *sk; 435 struct Net_device *dev; 443 char cb[48] __aligned (8); 445 unsigned long _skb_refdst; 449 unsigned int len, Data_len; 451 __u16 Mac_len, 452 Hdr_len;    473 __BE16 Protocol; 534 __u16 Inner_transport_header; 535 __u16 Inner_network_header; 536 __u16 Inner_mac_header; 537 __u16 Transport_header; 538 __u16 Network_header; 539 __u16 Mac_header; 540/* These elements must be at the end, see ALLOC_SKB () for details. */541 sk_buff_data_t tail; 542 sk_buff_data_t End; 543 unsigned char *head, 544 *data; 545 unsigned int truesize; 546 atomic_t users; 547};

struct Sk_buff
–435–> corresponding to the Net_device
–449–>len Valid data length
–451–>mac_len indicates the length of the Mac head
–473–>protocol Agreement Number
–537–>transport_header pointing to the Transport layer Protocol header
–538–>network_header pointing to the IP header
–539–>mac_header point to Ethernet header
–541–>tail points to the end address of the current packet, which varies with the processing of each network layer
–542–>end point to the data buffer's kernel end address, unchanged
–543–>head points to the core header of the data buffer (Packertdata), unchanged
–544–>data points to the first address of the current packet, which varies with the processing of each network layer

Net_device

Net_device is the core of the device interface layer and the object that writes the network drive core.

1160 struct Net_device {1167 char name[ifnamsiz];1179 unsigned long mem_end;      /* Shared mem end */1180 unsigned long mem_start;      /* Shared mem start */1181 unsigned long base_addr;            /* device I/O address */1182 int IRQ; /* Device IRQ number */1189 unsigned long state;1190 1191 struct List_head dev_list;11         list_head struct napi_list;1193 struct list_head unreg_list;1194 struct list_head         close_list;1210 netdev_features_t features;1212 netdev_features_t hw_features;1214 netdev_features_t wanted_features;1243 const struct NET_DEVICE_OPS *netdev_ops;1244 const STRUC T ethtool_ops *ethtool_ops;1245 const struct forwarding_accel_ops *fwd_ops;1248 const struct Header_ops *h eader_ops;1250 unsigned int flags; /* Interface flags (a la BSD) */1251 unsigned int priv_flags; /* like ' flags ' but invisible to userspace.1252 * see if.h for definitions.                   */1253 unsigned short gflags; 1254 unsigned short padded; /* How much padding added by Alloc_netdev () */1256 unsigned char operstate; /* RFC2863 operstate */1257 unsigned char link_mode;        /* Mapping policy to operstate */1259 unsigned char if_port; /* selectable AUI, TP,..            */1260 unsigned char DMA;    /* DMA channel */1262 unsigned int MTU;   /* Interface MTU value */1263 unsigned short type;        /* Interface hardware type */1264 unsigned short hard_header_len; /* Hardware HDR length */1270 unsigned short needed_headroom;1271 unsigned short needed_tailroom;1274 unsigned char perm_addr[max_addr_len]; /* Permanent HW address */1275 unsigned char addr_assign_type;       /* HW address Assignment Type */1276 unsigned char addr_len; /* Hardware address length */1289 struct kset *queues_kset;1386 int W Atchdog_timeo; /* Used by Dev_watchdog () */1480};

struct Net_device
–1170–>name is the device ' > Network device name, device ' > Network device is loaded and will appear in ifconfig, such as the default eth0 is this
–1179–>mem_start and Mem_end Store the shared memory start and end addresses used by the device
–1180–>base_addr means ' IO base address for equipment ' > Network devices
–1182–>IRQ the interrupt number used for the device
–1210–> features that can be modified by the user layer
–1212–> features that the user layer cannot modify
–1230–> Network card statistics
–1243–>netdev_ops ' > Network device operation Method set
Set of methods for –1244–>ethtool
–1248–>header_ops represents the protocol header action set
–1250–> standard that can be modified by the user layer
–1251–> standards that cannot be modified by the user layer
–1254–>alloc_netdev () the size of the pad when added
–1259–>if_port specify which port to use for a multi-port device
–1260–>DMA is the DMA channel assigned to the device
–1264–>hard_header_len indicates the hardware head length of the device ' > Network device, and during the initialization of the Ethernet device, the member is assigned a value of Eth_hlen, which is 14
–1263–>type is a hardware type
–1262–>MTU is the max TRANSFER UNIT
–1270–>needed_headroom represents the required head_room size in the packet buffer
–1271–> the size of the tailroom required in the data buffer
–1274–>mac Address
–1275–> Hardware Address Type
–1276–> Hardware Address length
–1289–> device belongs to Kset
–1386–> Count Value

Here are some of the kernel APIs related to Net_device

Allocation/Release
//linux/etherdevice.h/** * 分配及初始化net_device对象() * @sizeof_priv - 私有数据大小(单位:字节数) * 返回值:失败:NULL, 成功:net_device对象的首地址 */struct net_device *alloc_etherdev(int sizeof_priv);//linux/netdevice.h/** * 分配及初始化net_device对象 * @int sizeof_priv - 私有数据大小(单位:字节数) * @const char *name - 物理接口名("名称%d") * @unsigned char name_assign_type - NET_NAME_UNKNOWN * @void (*setup)(struct net_device *) - 初始化函数 * 返回值:失败:NULL成功:net_device对象的首地址 */struct net_device *alloc_netdev(int sizeof_priv, const char *name,unsigned char name_assign_type,void (*setup)(struct net_device *));//释放void free_netdev(struct net_device *dev);

As you can see through the name of the formal parameter, this function does not only allocate space for a Net_device object, because Net_device does not have a domain where private data is stored (except Dev->platform_data), about net_ The way in which device's private data is stored, as we can see through the definition of this function, is the reason why the kernel API is used to allocate a NET_DEVICE structure

//include/linux/netdevice.h2897 #define alloc_netdev(sizeof_priv, name, setup) 2898         alloc_netdev_mqs(sizeof_priv, name, setup, 1, 1)  
 //net/core/dev.c6308 struct net_device *alloc_netdev_mqs (int sizeof_priv, const char *name,6309  void (*setup) (struct Net_device *), 6310 unsigned int txqs, unsigned int rxqs) 6311{6330 alloc_size = sizeof (struct net_device); 6331 if (sizeof_priv) {6332 */ensure 32-byte alignment of private AR          EA */6333 alloc_size = ALIGN (alloc_size, netdev_align); 6334 alloc_size + = sizeof_priv;6335    }6336/* Ensure 32-byte alignment of whole construct */6337 alloc_size + = netdev_align-1; 6339 p = kzalloc (alloc_size, Gfp_kernel | __gfp_nowarn | __gfp_repeat); 6340 if (!p) 6341 p = Vzalloc (alloc_size); 6342 if (!p) 6343 return null;6344 6345 dev = ptr_align (p, Netdev_ali GN); 6346 dev->padded = (char *) Dev-(char *) p;6406}  

Alloc_net_dev_wqs
–6330–> Save the size of a net_device with alloc_size
–6333–> If there is a requirement for private data, re-assigning the value to Alloc_size, the new size is Net_device 32-byte alignment size + The requested private data size
–6337–> ensure that the allocated space is 32-byte aligned and used in conjunction with –6345–
–6339–> allocates space, size of space =net_device size + requested private data space size + (netdev_align-1) size Net_device private data is pre-allocated, just below the Net_device object.
The role of the –6345–>6337 line is reflected in this line, ptr_align is aligned upward, so long to ensure that dev points to the space is 32-byte alignment, the previously allocated redundant part as padded is added to the Net_device domain, so, Considering that the net_device itself happens to be 32-byte aligned, the last resulting memory layout is "net_device+priv_data+padded" a piece of physical contiguous space

Initialization
//以太网的初始化void ether_setup(struct net_device *dev);

This function is also a starting point, should be called when initializing an Ethernet device, its main function is to initialize the Net_device object for the Ethernet standard.

//net/ethernet/eth.c359 void ether_setup(struct net_device *dev)360 {361         dev->header_ops         = &eth_header_ops;362         dev->type               = ARPHRD_ETHER;363         dev->hard_header_len    = ETH_HLEN;364         dev->mtu                = ETH_DATA_LEN;365         dev->addr_len           = ETH_ALEN;366         dev->tx_queue_len       = 1000; /* Ethernet wants good queues */367         dev->flags              = IFF_BROADCAST|IFF_MULTICAST;368         dev->priv_flags         |= IFF_TX_SKB_SHARING;369 370         memset(dev->broadcast, 0xFF, ETH_ALEN);371 372 }
Registration/Logout
//注册int register_netdev(struct net_device *dev);//注销void unregister_netdev(struct net_device *dev);
Netdevice_ops
1002 struct Net_device_ops {1003 int (*ndo_init) (struct net_device *dev); 1004 void (*ndo_uninit)                     (struct net_device *dev); 1005 int (*ndo_open) (struct net_device *dev); 1006 int (*ndo_stop)                                                    (struct net_device *dev); 1007 netdev_tx_t (*ndo_start_xmit) (struct Sk_buff *skb,1008 struct Net_device *dev); 1013 void (*ndo_change_rx_flags) (str                    UCT net_device *dev,1014 int flags); 1015 void (*ndo_set_rx_mode)                                                        (struct net_device *dev); 1016 Int (*ndo_set_mac_address) (struct Net_device *dev,1017  void *addr); 1018 int (*ndo_validate_addr) (struct Net_device *dev); 1019 Int (*ndo_do_ioctl) (struct net_device *dev,1020 struct ifreq *ifr, int cmd); 1021 int (*ndo_set_config)                     (struct net_device *dev,1022 struct ifmap *map); 1023 int (*NDO_CHANGE_MTU)                     (struct net_device *dev,1024 int new_mtu); 1025 int (*ndo_neigh_setup)                    (struct net_device *dev,1026 struct neigh_parms *); 1027 void (*ndo_tx_timeout) (struct net_device *dev); 1028 1148};

struct NET_DEVICE_OPS
–1003–>ndo_init is the initialization function pointer, and if the pointer is set, it will be called when the device is registered to initialize the Net_device object, which is equivalent to the constructor in C + + , which can be null
–1004–> Destructors, recycling cleanup
–1005–> open device, ifconfig xxx up will callback
–1006–> shutdown device, ifconfig xxx down will callback
–1007–> send data, will be Dev_queue_xmit () callback
–1016–> setting up your Mac
–1018–> Check if your Mac is valid
–1019–> the IOCTL operation of equipment ' > network equipment
–1021–> configuration interface for configuring read-write parameters, read status, control network card, etc.
–1023–> Setting the MTU value
–1027 timeout, will be callback after timeout

Ndo_init () template

Here is a reference to the implementation of the Ndo_init ()

void xxx_init(struct net_device *dev){        /* 设备的私有信息结构体 */        struct xxx_priv *priv;        /* 检查设备是否存在, 以及设备需要的硬件资源 */        xxx_hw_init();        /* 初始化以太网设备的公用成员 */        ether_setup(dev);             /* 设置设备的成员函数指针 */        dev->netdev_ops->ndo_open = xxx_open;        dev->netdev_ops->ndo_stop = xxx_stop;        dev->netdev_ops->ndo_set_config = xxx_set_config;        dev->netdev_ops->ndo_start_xmit = xxx_tx;        dev->netdev_ops->ndo_do_ioctl = xxx_ioctl;        dev->netdev_ops->ndo_get_stats = xxx_stats;        dev->netdev_ops->ndo_change_mtu = xxx_change_mtu;        dev->netdev_ops->ndo_tx_timeout = xxx_tx_timeout;        dev->netdev_ops->ndo_watchdog_timeo = xxx_timeout;        dev->rebuild_header = xxx_rebuild_header;        dev->hard_header = xxx_header;        /* 获得私有数据并将其初始化 */        priv = netdev_priv(dev);        /* 初始化priv代码 */}
Ndo_open ()/ndo_release () template
int xxx_open(struct net_device *dev){        /* 申请资源 */        ret = request_irq(dev->irq, &xxx_interrupt, 0, dev->name, dev);        /* 激活设备的发送队列 */        netif_start_queue(dev);}init xxx_release(struct net_device *dev){        /* 释放资源 */        free_irq(dev->irq,dev);        /* 关闭设备的发送队列 */        netif_stop_queue(dev);}
Ndo_start_xmit () template
int xxx_tx(struct sk_buff *skb, struct net_device *dev){        int len;        char *data, shortpkt[ETH_ZLEN];        if(xxx_send_available(...)){    //发送队列未满, 可以发送                /* 获得有效数据指针和长度 */                data = skb->data;                len = skb->len;                if(len < ETH_ZLEN){                        /* 如果帧长小于以太网帧最小长度,补0 */                        memset(shortpkt,0,ETH_ZLEN);                        memcpy(shortpkt,skb->data,skb->len);                        len = ETH_ZLEN;                data = shortpkt;                }                dev->trans_start = jiffies;     //记录发送时间戳                /* 设置硬件寄存器让硬件将数据发出去 */                xxx_hw_tx(data,len,dev);        }else{                netif_stop_queue(dev);                ...        }}
Timeout () template

This function is called when it is timed out, and is often used to implement a re-send.

void xxx_tx_timeout(struct net_device *dev){        ...        netif_wake_queue(dev);  //重新启动设备发送队列}
Interrupt handler function

is the device ' > Network device media layer device drive function layer to send data interface, network card received data is reported by interruption, so the network drive interrupt processing function is the first time the team received data processing place, This function finally must call NETIF_RX () The data will be received on the Reporting protocol interface layer. The following is a simple receive data interrupt handler function template

static void xxx_rx(struct xxx_device * dev){        ...        length = get_rev_len(...);        /* 分配新的套接字缓冲区 */        skb = dev_alloc_skb(length +2);        skb_researve(skb, 2);   //对齐        skb->dev = dev;        /* 读取硬件上接收到的数据 */        insw(ioaddr +RX_FRAME_PORT, skb_put(skb, length), length >>1);        if(length &1){                skb ->data[length - 1] = inw(ioaddr + RX_FRAME_PORT);        }        /* 获取上层协议类型 */        skb->protocol = eth_type_trans(skb,dev);        /* 把数据包交给上层 */        netif_rx(skb);        /* 记录接收时间戳 */        dev->last_rx = jiffies;        ...}static void xxx_interrupt(int irq, void *dev_id){        ...        switch(status & ISQ_EVENT_MASK){        case ISQ_RECEIVER_EVENT:                                                                         /* 获取数据包 */            xxx_rx(dev);            break;        /* 其他类型中断 */        }}
Other APIs

These APIs are declared in "Include/linux/netdevice.h"

得到私有数据指针void *netdev_priv(const struct net_device *dev);设置MACint eth_mac_addr(struct net_device *dev, void *p);检查MAC地址是否有效int eth_validate_addr(struct net_device *dev);修改MTU值int eth_change_mtu(struct net_device *dev, int new_mtu);//随机生成mac地址void eth_hw_addr_random(struct net_device *dev)void eth_random_addr(u8 *addr);//开启发送队列void netif_start_queue(struct net_device *dev)//停止发送队列void netif_stop_queue(struct net_device *dev)//runingvoid netif_carrier_on(struct net_device *dev)//not runingvoid netif_carrier_off(struct net_device *dev)
The above is the Linux network device driver (a) _ Drive model of the entire content, more information, please pay attention to: CPP Learning Network _cpp University
This article fixed link: CPP Learning Network _cpp University-linux Network device driver (a) _ Drive model

Linux Network device driver (i) _ Drive model

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.