Work needs to write a Linux driver of our company's network card. Experience a process from an incompetence,
Deep sense of technical exchange
want. As a strong weapon challenged Microsoft monopoly, Linux is increasingly popular.
Love. I really hope she can grow rapidly in China. Paste the program document, hope to discuss Linux technology with you
And applications to promote Linux in China.
This article can be reproduced freely, but please do not publish it on the profit publication.
-------------------------------------------------
------------ Contact The Author by mailto: bordi@bordi.dhs.org ------
Linux job system network driver programming
One. LINUX system equipment driver program outline
1.1 Linux device driver program classification
1.2 Some basic concepts written in the driver
Two .linux system network equipment driver
2.1 Structure of Network Drive
2.2 Basic methods of network drivers
2.3 Data structure used in network drivers
2.4 Common system support
III. Writing problems that may encounter in Linux network drivers
3.1 Interrupt
3.2 Treatment of hardware transmission
3.3 Flow Control (Flow Control)
3.4 debugging
Fourth. Further reading
V. Miscellaneous
One. LINUX system equipment driver program outline
1.1 Linux device driver program classification
Linux device driver has a large proportion in Linux's kernel source code, the length of the source code
The increase is mainly, mainly the increase in the driver. During the continuous upgrade of the Linux kernel, the structure of the drive program
Still relatively stable. In the change of 2.0.xx to 2.2.xx, the driver's writing has made some changes, but
Driven from 2.0.xx to 2.2.xx, transplantation is only a small amount of work.
The equipment of the Linux system is divided into a char device, block device (Block device) and a network.
NetWork Device). The character device is a device that does not have a cached when the access is accessed. Block device reading
There are caching to support, and block equipment must be able to access (Random Access), the character device is not
This requirement. Typical character devices include a mouse, a keyboard, a serial number, and the like. Block equipment mainly includes hard disk soft disc
Equipment, CD-ROM, etc. A gear system must install enter the job system must be on the block device.
Network equipment do special processes in Linux. Linux's network system is mainly based on BSD UNIX
Socket
mechanism. Defining a special data structure (SK_BUFF) is defined between the system and the driver. system
During the trust, the cache for sending materials and reception materials, providing traffic control mechanisms, providing support for multi-protocols.
1.2 Some basic concepts written in the driver
No matter what the operating system drivers, there are some universal concepts. Homework system is provided to drive
The support of the program is also substantially the same. The following is a brief introduction to some basic requirements of the network equipment driver.
1.2.1 Send and receive
This is the most basic function of a network device. The network card is nothing more than the transmission and reception work. So drive
You want to tell the system where your send function is to be sent, and the system will call your hair when you have information.
Delivery. There is also a drive program because it is directly operating hard, so the network hard body has information to receive the first one.
It is also the driving program, which is responsible for the necessary processing of these original information and then gives the system.
System. Here, the operating system must provide two mechanisms, one is to find the send function of the driver, one
It is the driver to give the received data to the system.
1.2.2 interrupt
Interrupt is an important role in modern computer structure. The operating system must provide a driver response interrupt
Ability. Generally, an interrupt process is registered in the system. After the working system is broken in the hardware interruption
Call the process of the driver. The common use of Linux support interruption, that is, multiple devices share an interrupt.
1.2.3 clock
Many places will be used in many places when implementing the drive. For timeout processing in some protocols, there is no polling of the hardware of the interrupt mechanism. The operating system should provide a timing mechanism for the driver. Generally in the scheduled time
After passing the clock function registered later. In the network driver, if the hard body has no interrupt function, set
The timer can provide a polling (POLL) to access the hardware. Or doing timeout required when implementing certain agreements
Revitalization, etc.
Two .linux system network equipment driver
2.1 Structure of Network Drive
All Linux network drivers follow the general interface. The method of facing the object is designed.
A device is an object (Device structure), which has its own information and methods. Every device
The first parameter when the method is called is the device itself. This way can you access itself.
Data (THIS references to object-oriented design).
The most basic method of a network device has initialization, sending, and receiving.
---------------------------------------
| DELIVER PACKETS | | Receive Packets Queue |
| (dev_queue_xmit ()) | | Them (Netif_Rx ()) |
---------------------------------------
| | / /
/ / | |
-------------------------------------------------- -----
| Methods and Variables (Initialize, Open, Close, Hard_Xmit, |
Interrupt Handler, Config, Resources, Status ...) |
-------------------------------------------------- -----
| | / /
/ / | |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| send to hardware | | receivce from hardware |
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
| | / /
/ / | |
-------------------------------------------------- ---
Hardware Media |
-------------------------------------------------- ---
The initialization process completes the initialization of the hardware, the initialization of variables in Device, and the application of system resources. send
The program is automatically called when there is information to be sent when the upper layer agreement layer of the drive program is sent. Unorganized in general drivers
Send data to cache, but directly use the hardware sending function to send the information out. Receive information is generally pass
Differ interrupts are notified. In the interrupt processing, hardware frame information is filled in a SKBUFF structure,
-------------------------------------------------
------------ Contact The Author by mailto: bordi@bordi.dhs.org ------
The rear call is transmitted to the upper layer.
2.2 Basic methods of network drivers
Network equipment is an object that provides some approach to system access. It is these unified interfaces
law,
Show the specific details of the hardware, allowing the system to use a unified form of access to various network equipment, do hardware
Unrelated.
The most basic method is explained below.
2.2.1 Initialize
The driver must have an initialization method. This first is called when loading the driver into the system.
Pending process. It does the following work. Testing Equipment. In the initialization, you can use the hardware
Features Check if the hardware exists and then decides whether to start this driver. Configure and initialize the hardware. in
In the initialization program you can complete the configuration of hardware resources, such as plug-and-play hardware can be configured at this time (Linux kernel does not support PNP function, you can do this in the driver)
can). After configuring or negotiates the resources occupied by the hardware, you can apply for these resources to the system. Some resources are
Can be shared with other devices, such as interrupts. Some are unable to be shared, such as IO, DMA. Next you want to initially
The variables in the DEVICE structure. Finally, you can let the hardware begin to work.
2.2.2 Open (Open)
Open This method is called when the network device is started (ie equipment
State by DOWN -> UP). So actually a lot of work in Initialize can be made here. For example
The application, the start of the hardware. If DEV-> Open returns non-0 (error), the state of the hard body is still Down.
Another role of the OPEN method is that if the driver is loaded as a module, it should be prevented from uninstalling the module.
The device is open. In the OPEN method, you want to call the MOD_INC_USE_COUNT macro.
2.2.3 Close (STOP)
The Close method does the opposite of Open. Certain resources can be released to reduce system burden. CLOSE is
The device status is called by the UP to DOWN. In addition, if it is a drive program that is loaded as a module, close in Close
You should call MOD_DEC_USE_COUNT to reduce the number of times the device is referenced, so that the driver can be unloaded.
In addition, the Close method must return success (0 == Success).
2.2.4 Send (HARD_START_XMIT)
All online device drivers must have this sending method. In the system call the driver XMIT
When the sending information is placed in a SK_BUFF structure. The general drive program transmits the data to the hard body.
There are also some special devices such as loopback to form a receive information to the system, or
Dummy devices discard data directly.
If the send is successful, SK_BUFF is released in the hard_start_xmit method, and 0 (successful transmission). in case
The device is temporarily unable to handle, such as hardware, return 1. If DEV-> TBUSY is set to 0, the system
It is considered that hardware is busy, and it will be sent again after DEV-> TBUSY 0. TBUSY 0 task is generally interrupted
carry out. The hard body generates an interrupt after the transmission, then TBUSY can be 0, then use the Mark_BH () call pass.
Know the system can be sent again. In the case where the transmission is unsuccessful, you can also don't set the dev-> TBUSY as non-0, so
The system will continue to retransmit. If the hard_start_xmit is unsuccessful, do not release SK_BUFF.
The information in the transmitted SK_BUFF already contains the frame header needed by the hardware. So there is no need in the transmission method
To fill the hard body frame, the data can be directly submitted to the hardware. SK_BUFF is locked (Locked),
Make sure that other programs do not access it.
2.2.5 Reception
There is no receiving method without the driver. There is a data receipt of the driver to notify the system.
General equipment will generate an interrupt after receiving the information, the driver program is applied in the interrupt processing program.
SK_BUFF (SKB), placed from the hardware read data to the buffer for the application. Next to populate SK_BUFF
Some information. SKB-> dev = dev = dev, judge the type of protocol received, fill in SKB-> Protocol
Supported support). Point the pointer SKB-> mac.RAW to the hardware data and discard the hard body frame head (SKB_PULL). Still
Set SKB-> PKT_TYPE, indicate the second layer (link layer) data type. Can be the following type:
Packet_Broadcast: Link Mass Broadcast
Packet_multicast: Link Layer Multicast
Packet_self: Frame sent to yourself
Packet_otherhost: Send it to the frame of others (this frame will have this frame when listening mode)
Finally, Netif_Rx () is called to transfer the data to the protocol layer. Netif_rx () in the data is put into the processing, then return
Back, the real process is to reduce the interrupt time after the interrupt is returned. After calling Netif_Rx (),
The drive program cannot access the data buffer SKB.
2.2.6 Hard_Header
Hardware generally adds their hardware frame head before sending it, such as Ethernet (Ethernet)
There is a 14-bit group of frame headers. This frame header is to add in front of the upper layer IP, IPX and other packets. Driver
A Hard_Header method, protocol layer (IP, IPX, ARP, etc.) call this section before sending information.
The length of the hardware frame must be filled in dev-> hard_header_len, so the agreement is returned to the information before the information
The space of the hardware frame header. This way, the hard_header program, only calls SKB_PUSH and then fills the hardware frame
Yes.
When the Hard_Head is called at the protocol layer, the transferred parameters include (2.0.xx): SK_BUFF of the data,
Device pointer, protocol, destination address (DADDR), source site (SADDR), data length (LEN). data
Length Do not use the parameters in SK_BUFF, because the information may not be fully organized yet when calling hard_header.
Saddr is NULL to use the default address. Daddr is NULL indicating that the protagonist does not know the hardware
the address of. If the hard_header completely fills the hardware frame header, the number of added bit groups is returned. If the hard body frame
The information in the head is not complete (such as Daddr is NULL, but the purpose of the hand is required in the frame header. Typical feelings
The condition is that the EtOAc. Hard_header returns a negative number
Next, the protocol layer will make a further build header work. The current Linux system is ARP
(If Hard_Header returns to positive, dev-> arp = 1, indicating that you don't need to do ARP, return to negative, dev-> arp = 0,
Do ARP).
The call to Hard_Header is in the process of each protocol layer. Such as ip_output.
2.2.7 Address Analysis (XARP)
Some networks have hardware sites (such as ethernet), and need to know the hardware when the hardware frame is transmitted.
address. This requires the upper layer coordination site (IP, IPX), and the corresponding corresponding to the hard body address. This correspondence is through the address
Analysis is done. The device that needs to do ARP will call the driver Rebuild_Header party before sending.
law. The main parameters of the call include indicators to the hard body frame header, the protocol layer dispensing. If the driver can solve
The hard body order will return 1, if not, return 0.
The call to Rebuild_Header in DO_DEV_QUE_XMIT () of NET / CORE / dev.c.
2.2.8 Parameter settings and statistics
Some methods are also provided in the driver for setting up and reading information on the device's parameters. general
Only the super user (root) permission can set the device parameters. The setting method is:
DEV-> set_mac_address ()
When the user calls the IOCTL type for SiocsiFHWADDR, it is to set the MAC address of this device. general
There is not much sense to set the settings of the MAC site.
DEV-> set_config ()
-------------------------------------------------
------------ Contact The Author by mailto: bordi@bordi.dhs.org ------
When the user calls IOCTL, the type of SiocsifMap is called, the system is called the SET_CONFIG method of the driver. Users will pass an IFMap structure containing the required I / O, interrupt and other parameters.
DEV-> do_iocTl ()
If the user calls IOCTL, the system is between SiocDevPrivate and SiocDevPrivate 15, the system
This method of the driver will be called. Generally, it is a dedicated material for the device.
Reading information is also conducted through the IOCTL call. A driver can also be provided in addition to the secondary
Dev-> get_stats method, return a ENET_STATISTICS structure, including statistics that send reception.
The processing of IOCTL is in dev_ioctl () and dev_ifsioc () in Net / Core / Dev.c.
2.3 Data structure used in network drivers
The most important thing is the data structure of network equipment. Define in include / Linux / NetDevice.h. it
The annotations are already exhausted.
Struct Device
{
/ *
* This is the first field of the "visible" part of this structure
* (i.ec "file). It is the name
* The interface.
* /
Char * name;
/ * I / O Specific Fields - fixme: Merge these and struct ifmap INTO One * /
Unsigned long rmem_end; / * shMem "Recv" end * /
Unsigned long rmem_start; / * shMem "Recv" start * /
Unsigned long Mem_end; / * shared mem end * /
Unsigned long mem_start; / * shared mem st * /
Unsigned long base_addr; / * device I / o address * /
Unsigned char Irq; / * Device Irq number * /
/ * Low-level status flags. * /
Volatile Unsigned Char Start, / * Start An Operation * /
Interrupt; / * Interrupt Arrived * /
/ * Interrupt is set to 1 when the interrupt is handled, and the processing is complete. * /
Unsigned long tbusy; / * Transmitter Busy Must
BE long for
Bitops * /
Struct Device * Next;
/ * The Device Initialization function. Called Only onCE. * /
/ * Point to the initialization method of the driver. * /
INT (* init) (Struct Device * dev);
/ * Some Hardware Also Needs There Fields, But They Are Not Part of The
USUAL SECIED IN SPACE.C. * /
/ * Some hardware can support multiple interfaces on a plate and may use if_port. * /
Unsigned char if_port; / * selectable aui, tp, .. * /
Unsigned char DMA; / * DMA Channel * /
Struct eNet_statistics * (* get_stats) (Struct Device * dev);
/ *
* This Marks the end of the "visible" part of the structure. All * fields herefter area in internal to the system, and may change at
* Will (Read: May Be Clealed Up at Will).
* /
/ * Sse May Be Needed for Future Network-Power-Down Code. * /
/ * Trans_start Record the time of the last successful transmission. Can be used to determine if the hardware is working properly.
* /
Unsigned long trans_start; / * Time (in jiffies) of last tx * /
Unsigned long last_rx; / * time of last rx * /
/ * There are a lot of content in flags, defined in include / linux / if.h. * /
UNSIGNED SHORT FLAGS; / * Interface Flags (A LA BSD) * /
Unsigned short family; / * address family id (AF_INET) * /
Unsigned short metric; / * routing metric (not used) * /
UNSIGNED SHORT MTU; / * Interface MTU Value * /
/ * Type indicates the type of physical hardware. This mainly shows whether the hardware needs ARP. Definition
INCLUDE / Linux / if_arp.h. * /
Unsigned short type; / * interface hardware type * /
The / * The upper layer protocol reserves the hard body frame header in front of the sending data buffer according to Hard_Header_len. * /
Unsigned short hard_header_len; / * hardware hdr length * /
/ * Priv points some parameters defined by the driver. * /
Void * priv; / * Pointer to Private Data * /
/ * Interface address info. * /
Unsigned char Broadcast [MAX_ADDR_LEN]; / * HW BCAST ADD * /
Unsigned charpa; / * make dev_addr
Aligned to 8
BYTES * /
Unsigned char dev_addr [max_addr_len]; / * hw address * /
Unsigned char addr_len; / * hardware address length * /
Unsigned long pa_addr; / * protocol address * /
Unsigned long pa_brdaddr; / * protocol Broadcast Addr * /
Unsigned long pa_dstaddr; / * protocol p-p Other Side Addr * /
Unsigned long pa_mask; / * protocol netmask * /
UNSIGNED SHORT PA_ALEN; / * Protocol Address Length * /
Struct dev_mc_list * mc_list; / * Multicast Mac Addresses * /
INT MC_COUNT; / * NUMBER OF Installed Mcasts * /
STRUCT IP_MC_LIST * IP_MC_LIST; / * ip multicast filter chain * /
__U32 TX_QUE_LEN; / * MAX FRAMES Per Queue Allowed * /
-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- ------- Contact the authailto: bordi@bordi.dhs.org ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
/ * For load balancing driver pair support * /
Unsigned long pkt_queue; / * packets queued * /
Struct Device * Slave; / * Slave Device * /
Struct Net_Alias_info * alias_info; / * main dev alias info * /
Struct Net_Alias * my_alias; / * alias devs * /
/ * Pointer to the interface buffers. * /
Struct SK_Buff_Head Buffs [dev_numbuffs];
/ * Pointers to Interface Service Routines. * /
INT (* Open) (Struct Device * dev);
INT (* STOP) (STRUCT Device * DEV);
INT (* hard_start_xmit) (Struct SK_Buff * SKB,
Struct Device * dev);
INT (* hard_header) (Struct Sk_buff * SKB,
Struct Device * dev,
Unsigned Short Type,
Void * Daddr,
Void * Saddr,
Unsigned len);
INT (* rebuild_header) (void * eth, struct device * dev,
Unsigned long raddr, struct SK_Buff * SKB);
#define have_multicast
void (* set_multicast_list); "Struct Device * dev);
#define Have_set_mac_addr
INT (* set_mac_address) (Struct Device * dev, void
* AddR);
#define have_private_ioctl
INT (* do_ioctl) (Struct Device * dev, Struct IFREQ
* IFR, int CMD);
#define have_set_config
INT (* set_config) (Struct Device * dev, struct ifmap
* Map);
#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;
#define have_change_mtu
INT (* CHANGE_MTU) (Struct Device * dev, int new_mtu);
Struct IW_Statistics * (* get_wireless_stats) (Struct Device * dev);
}
2.4 Common system support
2.4.1 Memory Application and Release
INCLUDE / Linux / kernel.h declares Kmalloc () and KFree (). Used to apply in kernel mode
Please release the memory.
Void * kmalloc (unsigned int Len, int priority);
Void Kfree (void * __ ptr);
Different from malloc () in user mode, the kmalloc () application space has a size limit. Length is 2
Second party. The maximum length of the application can be applied. In addition, kmalloc () has a priority parameter, usually used
Can be GFP_kernel, if you call with GFP_ATOMic parameters in the interrupt, because use GFP_kernel
The caller may enter the SLEEP state and is not allowed when the interrupt is processed.
The memory released by Kfree () must be a kmalloc () application. If you know the size of your memory, you can also use it.
Kfree_s () is released.
2.4.2 Request_irq (), Free_IRQ ()
This is the call to the driver application interruption and release interrupt. Declare in include / linux / sched.h.
Request_irq () Call definition:
INT Request_irq (unsigned int IRQ,
Void (* Handler) (int IRQ, Void * dev_id, struct pt_regs
* regs),
Unsigned long Irqflags,
Const char * devname,
Void * dev_id);
IRQ is the hardware interrupt number to apply. In the Intel platform, ranges 0--15. Handler is registered to the system
Interrupt handler. This is a callback function, when interrupted, the system calls this function, incoming participation
The number includes a hard body interrupt number, a device ID, a register value. DEV_ID is passed when the following Request_IRQ
Parameters DEV_ID to the system. Irqflags is some properties of interrupt processing. More important
SA_Interrupt,
Indicating that the interrupt processing program is a quick process (setting sa_interrupt) or slow processing (not set)
SA_Interrupt). Mask all interrupts when the rapid process is called. Slow processing is not obscured. and also
A SA_SHIRQ property sets after running multiple devices in the future. DEV_ID will be used when interrupts
. Generally set to the Device structure itself or NULL of this device. Interrupt processing program can be used in DEV_ID
Find the corresponding device that controls this interrupt, or use IRQ2DEV_MAP to find the device corresponding to the interrupt.
Void free_irq (unsigned int IRQ, VOID * DEV_ID);
2.4.3 clock
The processing of the clock is similar to the interrupt, but also the registration of a time handler, after a predetermined time, the system
This function will be called. Declare in include / linux / timer.h.
Struct Timer_List {
Struct Timer_list * next;
Struct Timer_List * prev;
Unsigned long expires;
UNSIGNED Long Data;
VOID (* Function) (UNSIGNED Long);
}
Void add_timer (struct timer_list * time);
INT DEL_TIMER (Struct Timer_List * Timer);
Void init_timer;
Use the clock, first declare a Timer_List structure, call the init_timer to initialize it.
ExpiRes in the Time_List structure is the cycle of this clock, and units use Jiffies units.
Jiffies is a general variable in Linux, representing time. Its unit is different from the hardware platform.
A constant Hz is defined in the system that represents the number of minimum time intervals per second. In this way, Jiffies
It is 1 / Hz. The unit of Intel platform Jiffies is 1/100 seconds, which is the minimum time that the system can distinguish.
The interval. Therefore, Expires / Hz is the cycle of this clock in seconds. Function is the time reached a callback function, and its parameters are DATA in Timer_List.
DATA This parameter assigns a value when initializing the clock, generally assigned to the Device structure indicator of the device.
In the preset time to the system call function, the system will clear this Time_List from timing
except. So if you need to use a timing function, call add_timer () again in the function.
-------------------------------------------------
------------ Contact The Author by mailto: bordi@bordi.dhs.org ------
Timer_list is added to the timed.
2.4.4 I / O
I / O access:
INLINE UNSIGNED INT INB (UNSIGNED SHORT Port)
INLINE UNSIGNED INT INB (UNSIGNED SHORT Port);
Inline void Outb (Char Value, Unsigned Short Port);
Inline void Outb_p (Char Value, Unsigned Short Port)
Definition in include / adm / o.h.
INB_P (), OUTB_P () and INB (), Outb_p () are different lies in the former waiting for I / O
(PAUSE) an I / O device adapts to a slow speed.
In order to prevent conflicts from accessing I / O, Linux provides control of the use of 埠. In use
Previously, you can check if needed I / O is being used, if not, mark the port as being used.
Release it after use. The system provides the following functions to do these work.
INT CHECK_REGION (unsigned int extent);
Void Request_Region (unsigned int extent, const char
* Name);
Void Release_Region (unsigned int extent);
Where the parameter from from From the start address used, Extent indicates the end starting from the FROM
The number of mouths. Name is the name of the device.
2.4.5 Interrupt Turn on
The system is provided to the drive program open and closes the ability to break the interrupt. Is in include / asm / system.h
Two definitions in it.
#DEfine CLI () __ASM__ __Volatile__ ("CLI": :)
#DEfine STI () __ASM__ __Volatile__ ("STI": :)
2.4.6 Print Information
Similar Printf (), drive program to output information using Printk (). In Include
/Linux/kernel.h declaration.
INT Printk (const char * fmt, ...);
Where FMT is a formatted string. ... is the parameter. It is the same as the Printf () format.
2.4.7 Registration Driver
If you load a driver using an Module mode, you need to register your device when you initialize the module.
Go to the system equipment table. When using it, remove the device from the system from the system. Definition
Drivers / Net / Net_init.h
The two functions have completed this job.
INT register_netdev (struct device * dev);
Void Unregister_netDev (Struct Device * dev);
DEV is the device structure indicator to register into the system. At register_netdev (), the DEV structure
Fill in the front of 11 in front, that is, to init, and the next temporary can not initialize. The most important thing is the Name pointer and init method. Name indicator empty (NULL) or content / or Name [0] is space (SPACE), the system
Treat your device as an EtOAc. Other Nets equipment has a unified naming format, Ethx. Bai Net
So particularly related to the history of Linux.
The init method must provide, register_netdev () call this method to let you detect hardware and
Set.
Register_netdev () returns 0 means success, non-0 is unsuccessful.
2.4.8 SK_Buff
The data transfer between the layers of the Linux network is through SK_BUFF. SK_BUFF provides a set of management buffers
The method of the area is the key to the efficient operation of Linux system network. Each SK_BUFF includes some control methods and one
Block data buffer. The control method is divided into two types according to the function. One is a method of controlling the entire Buffer chain.
The other is a method of controlling a data buffer. SK_BUFF organizes the form of a two-way linked list, according to network applications
Features, the operation of the linked list is mainly to delete the elements of the linket head and add to the tail. SK_BUFF control
The method is very short to minimize system load. (Translated from article write by alan
COX)
Common methods include:
.alloc_skb () applies for a SK_BUFF and initializes it. The return is the application-to-SK_BUFF.
.dev_alloc_skb () Similar to ALLOC_SKB, after applying for a buffer, the 16-bit set of frame heads are retained
between. Mainly used in the Ethernet driver.
Kfree_skb () Releases a SK_BUFF.
.skb_clone () Copys a SK_BUFF, but does not copy the data section.
.skb_copy () completely copies a SK_BUFF.
.skb_dequeue () Remove the first element from a SK_BUFF list. Returns the removed SK_BUFF,
Returns NULL if the chain is returned. This is a common operation.
.skb_queue_head () puts an element in a SK_BUFF list header.
.skb_queue_tail () puts an element in a SK_BUFF linked list. This is also a commonly used
operating. The processing of online data is mainly for a first-first-out, SKB_QUEUE_TAIL ()
And SKB_DEQUEUE () completes this work.
.skb_insert () inserts an element before an element of the linked list.
.skb_append () Insert an element after an element of the linked list. Some protocols (such as TCP) are not pressed
SKB_INSERT () and SKB_APPpend () are used when the order arrives.
.skb_reserve () keeps a piece of space in a buffer for a request SK_Buff. This space
It is generally used to make the headspace of the next level agreement.
.skb_put () keeps a space for the data in a buffer for a request SK_Buff. in
After alloc_skb, the buffer of the application-in SK_BUFF is in an air state, there is a
The TAIL indicator points to the free space, and Tail is actually starting to the buffer. SKB_RESERVE ()
Apply for an agreement header in the free space, SKB_PUT () application data space. See the figure below.
.skb_push () moves in the SK_BUFF buffer to the front. That is, the spatial movement in HEAD ROOM
Part of Data Area.
.skb_pull () moves a part of the space in the Data Area in the SK_BUFF buffer to Head Room.
--------------------------------------------------
TAIL Room (Free) |
--------------------------------------------------
After alloc_skb ()
-------------------------------------------------- | Head room | Tail Room (Free) |
--------------------------------------------------
After SKB_RESERVE ()
--------------------------------------------------
Head Room | Data Area | Tail Room (Free) |
--------------------------------------------------
After SKB_PUT ()
--------------------------------------------------
| HEAD | SKB_ | Data | Tail Room (Free) |
| Room | Push | | | | |
| | Data Area | |
--------------------------------------------------
After SKB_PUSH ()
--------------------------------------------------
| HEAD | SKB_ | Data Area | Tail Room (Free) |
| | Pull | | | |
| Head room | | | | | |
--------------------------------------------------
After SKB_PULL ()
-------------------------------------------------
------------ Contact The Author by mailto: bordi@bordi.dhs.org ------
3. Writing the problem that needs attention in the Linux network driver
3.1 Interrupt
The Linux system runs several devices share the same interrupt. If you need to share, indicate when you apply
Shared way. The definition of the request_irq () call provided:
INT Request_irq (unsigned int IRQ,
Void (* Handler) (int IRQ, Void * dev_id, struct pt_regs
* regs),
Unsigned long Irqflags,
Const char * devname,
Void * dev_id);
If the interrupt is shared, Irqflags sets the SA_SHIRQ property, so that other devices are allowed to apply for the same one.
Interrupt. Need to note that all devices that use this interrupt must be set to request_irq ().
Sex. When the system is turned back to each interrupt processing, the corresponding device can be found with the parameters of DEV_ID. One
The DEV_ID is set to the Device structure itself. System processing shared interrupt is used in subsistence with respective dev_id parameters
Use each interrupt process.
3.2 Treatment of hardware transmission
The processing capability of the main CPU is generally fast than the network, so it often encounters the system's information, but
The last package of information network equipment has not been sent yet. Because in Linux network equipment drivers, do not do information
The cache, the information that cannot be sent is unsuccessful in the notification system, so there must be a mechanism to be hardware.
When you are busy, you will notify the system to send the following information.
Generally, the transmission is already described in the transmitting method of the front device (hard_start_xmit),
That is, if it is sent, set TBUSY to 1. After processing the sending information, the end interrupt in the transmitted TBUSY, the same
The notification system continues to be sent with the Mark_BH () call notification system.
But when I realize my driver, I found that such a processing system seems to know in time.
The piece has been idle, that is, after mark_bh (), the system will wait for some time to send it. There is a low transmission efficiency. The 2M line is only 10% less than the usage. The kernel version is 2.0.35.
My last implementation does not set TBusy 1, so that the system always thinks that hardware is idle, but the report is not
Work. The system will have been trying to return. This is normal. But the network drive in the internal nuclear source code
Shutdown does not seem to do this. I don't know where the crux is.
3.3 Flow Control (Flow Control)
The transmission and reception of network data require traffic control. These controls are implemented in the system, no need
Driver works. There is a parameter dev-> tx_queueue_len, this parameter in each device data structure.
Sign up for the most cached data package when sending. Other Bar equipment (10 / 100Mbps) in Linux system
TX_QUEUE_LEN is typically set to 100, and the serial line (non-synchronous serial port) is 10. In fact, if you want to see the source code
Knowing, setting dev-> TX_QUE_LEN is not to apply for space for cache these information. This parameter is just
Judging the information in the sending 伫 伫 伫 限 限 限 限 限 限,,,,,
To determine this package information is not added to send a column. The flow control of another aspect is a higher level agreement.
Send the window (there is a send window in the TCP agreement). The window size is reached, and the high-level agreement will not send the information.
Receiving flow control is also divided into two levels. Netif_rx () cached information package has restrictions. Different high-rise agreements
There is a maximum amount of information waiting for processing.
Send and receive flow control processing in NET / CORE / Dev.c DO_DEV_QUE_XMIT () and Netif_Rx ()
in.
3.4 debugging
Many Linux drivers are compiled into the kernel, forming a large kernel file. But debugging
It is quite troublesome. The debug driver can be loaded in Module. Support module
Drive must provide two functions: int init_module (void) and Void
Cleanup_Module (Void).
INIT_MODULE () calls when loading this module, can register in register_netdev () in this function
equipment. INIT_MODULE () Returns 0 means success, return negative means failure. Cleanup_module () is driven
Call when the program is unloaded, cleared the resource, call unregister_netdev ().
The module can be loaded, unloaded. In version 2.0.xx, there is also a KernelD automatic load module.
However, Kerneld has been canceled in 2.2.xx. Manual load uses the insmod command, uninstall the RMMOD command,
See the module in the kernel with the lsmod command.
Compile the driver with GCC, the main command line parameter -Dkernel -dmodule. And be loaded as a module
The drive program is compiled into an OBJ form (plus -c parameter). Compiled good target file / lib / modules
Under /2.x.xx/misc, use INSMOD in the startup file.
Fourth. Further reading
Linux programming materials can be obtained online. This is the benefits of open source code. And there is no
"Unapproved secret". The main information on the preparation of the driver includes:
Linux kernel source code
<
> by Michael K. Johnson
<
> by Ori Pomerantz
<
> by olly in bbs Shuimu Tsinghua Station
You can choose a template as a beginning, and the kernel source code has a network driver model.
DRIVERS / NET / SKELETON.C. The basic content of the driver is included. But this template is too too
The network equipment is the object, and the processing of the Ethernet is special "treatment" in the Linux system, so if not
Taiwanese equipment, pay attention to some details, mainly in the initialization. Finally, more than the program written by others, listening to other developers' experience is probably the most effective help
.