Snull compilation in Linux Device Driver (LDD)

Source: Internet
Author: User
Tags diff

For the snull program in LDD, there will be many problems during compilation. In view of the fact that there is no proper solution on the internet, make a summary and sort out the knowledge. This article is run on debian6.0 and the kernel version is 2.6.32.

It is necessary to learn about the network driver in LDD and understand the principles of the snull program. Snull does not rely on hardware, and packet sending and receiving all belong to memory operations. However, the principle of the entire network driver has been well elaborated. The program is not complex, much easier to understand than e100.c; 8139too. C; pci-skeleton.c. This book was written by the author in the 2.6.11 age. Compared with the current kernel version, some interfaces have changed, which is the direct cause of snull compilation failure. This article describes the snull modification method and points out the changed interface. This article is run on debian6.0 and the kernel version is 2.6.32.

This article provides makefile and snull. C after modification, and generates a patch file.

 

Content

1) FAQs

2) Correct snull Compilation Method

3) File Download

FAQ

This is what I have encountered and some problems I have seen on the Internet. I will explain the reasons one by one and explain the solution in Section 2 (see below. If you have any questions, you can leave a message to facilitate discussion. As for the detailed interface changes, I will write another article to describe them one by one.

 

1) Error description:

Make-C/lib/modules/2.6.32-5-686/build M =/home/xiebiwei/dev/code/LDD/snull modules
Make: ***/lib/modules/2.6.32-5-686/Build: no such file or directory. Stop.
Make: *** [Default] Error 2

Cause: the kernel source code tree is not installed, or the kerneldir in makefile is not modified after the kernel source code tree is installed.

 

2) Error description:

Make-C/lib/modules/2.6.32/build M =/home/xiebiwei/dev/code/LDD/snull modules
Make [1]: Entering directory '/usr/src/linux-source-2.6.32'
Scripts/makefile. Build: 49: *** cflags was changed in "/home/xiebiwei/dev/code/LDD/snull/makefile". Fix it to use extra_cflags. Stop.
Make [1]: *** [_ module _/home/xiebiwei/dev/code/LDD/snull] Error 2
Make [1]: Leaving directory '/usr/src/linux-source-2.6.32'
Make: *** [Default] Error 2

Cause: the kernel version is different. The latest version has changed cflags to extra_cflags.

 

3) Error description:

Make-C/lib/modules/2.6.32/build M =/home/xiebiwei/dev/code/LDD/snull modules
Make [1]: Entering directory '/usr/src/linux-source-2.6.32'
CC [m]/home/xiebiwei/dev/code/LDD/snull. o
/Home/xiebiwei/dev/code/LDD/snull. C: 18: 26: Error: Linux/config. h: no such file or directory
/Home/xiebiwei/dev/code/LDD/snull. C: In function 'snull _ poll ':
/Home/xiebiwei/dev/code/LDD/snull. C: 289: Error: 'struct net_device 'has no member named 'quota'
/Home/xiebiwei/dev/code/LDD/snull. C: 289: Warning: Type defaults to 'int' in Declaration of '_ min1'
/Home/xiebiwei/dev/code/LDD/snull. C: 289: Error: 'struct net_device 'has no member named 'quota'
/Home/xiebiwei/dev/code/LDD/snull. C: 319: Error: 'struct net_device 'has no member named 'quota'
/Home/xiebiwei/dev/code/LDD/snull. C: 321: Error: Implicit declaration of function 'netif _ rx_complete'
/Home/xiebiwei/dev/code/LDD/snull. C: In function 'snull _ napi_interrupt ':
/Home/xiebiwei/dev/code/LDD/snull. C: 406: Error: Implicit declaration of function 'netif _ rx_schedule'
/Home/xiebiwei/dev/code/LDD/snull. C: In function 'snull _ init ':
/Home/xiebiwei/dev/code/LDD/snull. C: 647: Error: 'struct net_device 'has no member named 'open'
/Home/xiebiwei/dev/code/LDD/snull. C: 648: Error: 'struct net_device 'has no member named 'stop'
/Home/xiebiwei/dev/code/LDD/snull. C: 649: Error: 'struct net_device 'has no member named 'set _ config'
/Home/xiebiwei/dev/code/LDD/snull. C: 650: Error: 'struct net_device 'has no member named 'hard _ start_xmit'
/Home/xiebiwei/dev/code/LDD/snull. C: 651: Error: 'struct net_device 'has no member named 'do _ ioctl'
/Home/xiebiwei/dev/code/LDD/snull. C: 652: Error: 'struct net_device 'has no member named 'get _ stats'
/Home/xiebiwei/dev/code/LDD/snull. C: 653: Error: 'struct net_device 'has no member named' change _ MTU'
/Home/xiebiwei/dev/code/LDD/snull. C: 654: Error: 'struct net_device 'has no member named 'rebuild _ head'
/Home/xiebiwei/dev/code/LDD/snull. C: 655: Error: 'struct net_device 'has no member named 'hard _ head'
/Home/xiebiwei/dev/code/LDD/snull. C: 656: Error: 'struct net_device 'has no member named 'tx _ timeout'
/Home/xiebiwei/dev/code/LDD/snull. C: 659: Error: 'struct net_device 'has no member named 'Poll'
/Home/xiebiwei/dev/code/LDD/snull. C: 660: Error: 'struct net_device 'has no member named 'weight'
/Home/xiebiwei/dev/code/LDD/snull. C: 665: Error: 'struct net_device 'has no member named' hard _ header_cache'
Make [2]: *** [/home/xiebiwei/dev/code/LDD/snull. O] Error 1
Make [1]: *** [_ module _/home/xiebiwei/dev/code/LDD/snull] Error 2
Make [1]: Leaving directory '/usr/src/linux-source-2.6.32'
Make: *** [Default] Error 2

Cause:

1 config. h does not exist in the 2.6.32 kernel and must be replaced with the corresponding header file.

2 The structure of struct net_device has changed in the new kernel version, and the quota member is deleted. The (open, stop, set_config, hard_start_xmit, etc.) is encapsulated into struct net_device_ops; (poll, (weight, etc.) encapsulated into struct napi_struct; (hard_header, hard_header_cache, rebuild, etc.) encapsulated into struct header_ops. Some function names and parameters are changed.

3 netif_rx_complete and netif_rx_schedule are functions in the poll mechanism. The interface names have changed to napi_complete and napi_schedule.

 

 

 

Ii. Correct snull Compilation Method

1) construct the kernel source code tree

This is the necessary preparation for writing the driver; otherwise, the driver cannot be compiled. The module must call the kernel functions during compilation (the module is part of the kernel and cannot call glibc). Therefore, it is necessary to construct the source code tree.

See detailed steps On Debian: http://blog.csdn.net/xiebiwei/archive/2011/02/20/6196818.aspx

It is easier to download the kernel In Debian. The common method for downloading the kernel is as follows:

Use "uname-R" to view the system kernel version, go to the Linux kernel website (http://www.kernel.org/pub/linux/kernel/v2.6/) to find the corresponding version of the kernel source file, download and place it under "/usr/src.

Next we can use the method in the above link to decompress the kernel source code and compile it.

 

2) Modify makefile

(I) Change cflags to extra_cflags, which is an interface change caused by kernel upgrade. View

Ii) Change kerneldir to the correct module compiling directory, that is, the directory generated when the kernel source code tree is constructed, generally "/lib/modules/**/build ". View

 

3) modify the source file snull. C.

I) The <Linux/config. h> file in the header file has been deleted from the new kernel. Check and replace the file in the old kernel version. View

Ii) Modify struct snull_priv and add member variables of struct napi_struct and struct net_device. 2.6.32 the kernel encapsulates poll () and weight into napi_struct. Therefore, to implement the polling mechanism, you must define napi_struct in private. View

Iii) modify the function: snull_poll. In kernel 2.6.32, struct net_device removes quota. quota is the device's limit on the number of packets received. The poll function interface parameters also change to static int (* poll) (struct napi_struct, INT), so the function body also needs to be slightly adjusted, such as obtaining the priv pointer. View

Iv) modify the snull_napi_interrupt function. The function interface for Poll Scheduling in this function is changed to napi_schedule (struct napi_struct *). View

V) modify the snull_init function. The definition of struct net_device has changed. View

Encapsulate open, stop, set_config, and other operations into the struct net_device_ops struct. View

Encapsulate operations such as harder_header and rebuild_header into struct header_ops, and poll into struct napi_stuct. View

Three sample file downloads

Download link (including snull. c makefile snull_2.6.32.patch)

Usage: You can directly overwrite snull. C and makefile. You can also copy the patch file to snull/and run patch-P1 <snull_2.6.32.patch

Patch file

Diff-unr snull_original/makefile snull/makefile
--- Snull_original/makefile 15:31:02. 000000000-0500
++ Snull/makefile 17:45:39. 000000000-0500
@-9,8 + 9,8 @@
Debflags =-O2
Endif
 
-Cflags + = $ (debflags)
-Cflags + =-I ..
+ Extra_cflags + = $ (debflags)
+ Extra_cflags + =-I ..
 
Ifneq ($ (kernelrelease ),)
# Call from kernel build system
-19,7 + 19,7 @@
 
Else

-Kerneldir? =/Lib/modules/$ (shell uname-R)/build
+ Kerneldir? =/Lib/modules/2.6.32/build
PWD: = $ (shell PWD)
 
Default:
Diff-unr snull_original/snull. c snull/snull. c
--- Snull_original/snull. c 15:31:02. 000000000-0500
++ Snull/snull. c 19:50:06. 000000000-0500
@-+ @@
*
* $ ID: snull. C, V 1.21 2004/11/05 02:36:03 Rubini exp $
*/
-
-# Include <Linux/config. h>
+ # Ifdef linux_config_h
+ # Define linux_config_h
+ # Include <Linux/Autoconf. h>
+ # Endif
# Include <Linux/module. h>
# Include <Linux/init. h>
# Include <Linux/moduleparam. h>
@-87,6 + 89,9 @@
U8 * tx_packetdata;
Struct sk_buff * SKB;
Spinlock_t lock;
+
+ Struct napi_struct napi;
+ Struct net_device * dev;
};
 
Static void snull_tx_timeout (struct net_device * Dev );
@-284,11 + 289,12 @@
/*
* The poll implementation.
*/


-Static int snull_poll (struct net_device * Dev, int * budget)
+ Static int snull_poll (struct napi_struct * napi, int budget)
{
-Int npackets = 0, quota = min (Dev-> quota, * budget );
+ Int npackets = 0, quota = budget;
Struct sk_buff * SKB;
-Struct snull_priv * priv = netdev_priv (Dev );
+ Struct snull_priv * priv = container_of (napi, struct snull_priv, napi );
+ Struct net_device * Dev = priv-> dev;
Struct snull_packet * Pkt;

While (npackets <quota & priv-> rx_queue ){
@-315,10 + 321,8 @@
Snull_release_buffer (Pkt );
}
/* If we processed all packets, We're re done; tell the kernel and reenable ints */
-* Budget-= npackets;
-Dev-> quota-= npackets;
If (! Priv-> rx_queue ){
-Netif_rx_complete (Dev );
+ Napi_complete (& priv-> napi );
Snull_rx_ints (Dev, 1 );
Return 0;
}
@-403,7 + 407,7 @@
Priv-> Status = 0;
If (statusword & snull_rx_intr ){
Snull_rx_ints (Dev, 0);/* disable further interrupts */
-Netif_rx_schedule (Dev );
+ Napi_schedule (& priv-> napi );
}
If (statusword & snull_tx_intr ){
/* A transmission is over: Free the SKB */
@-585, 8 + 589,8 @@
 
 
Int snull_header (struct sk_buff * SKB, struct net_device * Dev,
-Unsigned short type, void * daddr, void * saddr,
-Unsigned int Len)
+ Unsigned short type, const void * daddr, const void * saddr,
+ Unsigned Len)
{
Struct ethhdr * Eth = (struct ethhdr *) skb_push (SKB, eth_hlen );
 
@-627,6 + 6325 @@
* The init function (sometimes called probe ).
* It is invoked by register_netdev ()
*/
+
+ Static const struct net_device_ops snull_dev_ops = {
+
+. Ndo_open = snull_open,
+. Ndo_stop = snull_release,
+. Ndo_set_config = snull_config,
+. Ndo_start_xmit = snull_tx,
+. Ndo_do_ioctl = snull_ioctl,
+. Ndo_get_stats = snull_stats,
+. Ndo_change_mtu = snull_change_mtu,
+. Ndo_tx_timeout = snull_tx_timeout,
+ };
+
+ Static const struct header_ops snull_header_ops = {
+. Create = snull_header,
+. Rebuild = snull_rebuild_header,
+. Cache = NULL,/* disable caching */
+ };
+
Void snull_init (struct net_device * Dev)
{
Struct snull_priv * priv;
@-644,25 + 667,13 @@
*/
Ether_setup (Dev);/* assign some of the fields */
 
-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-> change_mtu = snull_change_mtu;
-Dev-> rebuild_header = snull_rebuild_header;
-Dev-> hard_header = snull_header;
-Dev-> tx_timeout = snull_tx_timeout;
+ Dev-> netdev_ops = & snull_dev_ops;
+ Dev-> header_ops = & snull_header_ops;
Dev-> watchdog_timeo = timeout;
-If (use_napi ){
-Dev-> poll = snull_poll;
-Dev-> Weight = 2;
-}
+
/* Keep the default flags, just add noarp */
Dev-> flags | = iff_noarp;
Dev-> features | = netif_f_no_csum;
-Dev-> hard_header_cache = NULL;/* disable caching */
 
/*
* Then, initialize the priv field. This encloses the statistics
@-670,9 + 681,15 @@
*/
Priv = netdev_priv (Dev );
Memset (priv, 0, sizeof (struct snull_priv ));
+ Priv-> Dev = dev;
+
Spin_lock_init (& priv-> lock );
Snull_rx_ints (Dev, 1);/* enable receive interrupts */
Snull_setup_pool (Dev );
+ If (use_napi ){
+ Netif_napi_add (Dev, & priv-> napi, snull_poll, 2 );
+}
+
}

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.