Previous section We learned :  

Introduction of network card driver and making virtual network card driver :

Next, this section , Learn NIC chip DM9000C, How to write migration DM9000C Network card driver .



1. First of all to see DM9000C Schematic diagram

As shown in the figure below :


(#: Indicates that the low level is active )

  • SD0~15: 16 Bit data line , Yes CMD The pin determines the type of access
  • CMD:       Command line , When CMD For the high , Express SD It's data ,CMD Low means the address is being transmitted
  • INT:          Interrupt pin , Connect to 2440 Of GPF7 On the feet
  • IOR#:       Read pin , Connect to 2440 Of nOE On the feet
  • IOW#:      Write pin , Connect to 2440 Of nWE On the feet
  • CS#:        Chip selection , Put it in 2440 Of bank4 On the top of the movie selection

1.1 among 2440 Manual bank4 The address range is shown in the figure below :


bank4 The interval of is located in : 0X20000000~0X28000000, When we visit the address of this section , The memory controller enables the network card DM9000C The enabling foot of , So our DM9000C Of io Base address =0X20000000

among DM9000C Of CMD The pins are connected to bank4 Of LADDR2 above

For example, when the address 0X2000 0000 When reading and writing data on the computer , The data for reading and writing is DM9000C The address of

Address visited 0X2000 0004 When reading and writing data on the computer , The data for reading and writing is DM9000C The data of


1.2 DM9000C Sending and receiving process

When DM9000C After receiving external data , Will be stored in the internal address , Then a rising edge interrupt is generated , wait for 2440 Reading data

When DM9000C take 2440 After the data is forwarded , It will also produce a rising edge interrupt to 2440

As shown in the figure below ,DM9000C The interrupt pin of is located in pin34 foot


Connect to 2440 Of GPF7 On the pin , The interrupt used is EINT7


Next, we will modify the DM9000C Source code

2. Discover its init_module() There is a conditional compilation before the entry function

So comment out  “#ifdef MODULE”  and “#endif”

3. Modify the name of the entry and exit functions , And decorate them ( Modify function names to avoid duplicate names with other functions in the kernel )



4. Modify the hardware dissimilarity of the driver ( Set base address , register , Interrupt, etc )

4.1 Let's find out where the code is initialized DM9000C The hardware

Get into dm9000c_init()

       -> dmfe_probe()

among dmfe_probe() Function as follows :

 Copy code

struct net_device * __init dmfe_probe(void)
struct net_device *dev;
dev= alloc_etherdev(sizeof(struct board_info));          // Allocate one net_device Structure
... ...
err = dmfe_probe1(dev);                                 // call dmfe_probe1() function
... ...
err = register_netdev(dev);                            // Register with the kernel net_device Structure
... ...

 Copy code

obviously dmfe_probe1() Function is used to initialize DM9000C Hardware and settings net_device Members of the structure use


4.2 Get into dmfe_probe1() function

Here's the picture , This iobase Variables are us DM9000C Of io Base address 0x20000000



iobase The role of :

Pictured above , Read it once DM9000C Of VID Before the low byte , You need to assign the address to 0x20000000, Also is to DM9000C Of CMD Set up 0, And then to 0x20000000 Write what you want to read DM9KS_VID_L Address values

Finally, the address +4, That is to say, Fu is 0x20000100, take CMD Set up 1, Then read out 0x20000100 Value , That is to say DM9000C Of VID Low byte

DM9000C This is the way we read and write , First the CMD Set up 0, write in DM9000C The address of , And then CMD Set up 1, To read and write data


4.3 So in init Function iobase Variable , among iobase yes int type


And in exit In the exit function , add to iounmp()


4.4 Continue to enter dmfe_probe1() function , To look down

As shown in the figure below , Block the code in the red box , This code is used to check the version , our DM9000C The version number is different , therefore To shield

4.5 stay init Function , Modify the interrupt name , take irq Change it to IRQ_EINT7


4.6 Modify interrupt

When using the register_netdev() Registered network card driver net_device after , Use... In the kernel ifconfig Will enter net_device->open Member function request interrupt , Activate the queue, etc

So we have to modify open Application interrupt function of member function , Change the trigger interrupt to “IRQT_RISING”, Rising edge trigger


5. Next, set up 2440 Storage control register for

Set up 2440 Of bank4 Bit width of hardware , sequential , Because of the different hardware , The data involved are all different ,

5.1 Set up BWSCON Bus width control register

We just set up BANK4 The content of , So it's just the following 3 individual (BANK0 The bit width of is determined by OM[1:0] hardware setup )


Set up ST4=0, Don't use UB/LB(UB/LB: Indicates whether high byte and low byte data are transmitted separately )

Set up WS4=0, among WAIT Pin for PE4, And we DM9000C There is no pin in PE4, So it's forbidden

Set up DW4=0x01, our DM9000C Our data line is 16 position

5.2 Set up BANKCON4 Control register


  Before setting these timing , First of all to see DM9000C Chip manual sequence diagram and 2440 Sequence diagram


Refer to the above figure , obtain BANKCON4 The registers are set as follows (HCLK=100MHZ,1 One clock equals 10ns)

  • Set up Tacs=0, because CS and CMD It can end at the same time (bank4 Address ( That is to say CMD) How long after it's stable ,CS It's the movie selection that starts )
  • Set up Tcos=T1=0(CS After the film selection , How long can I read and write )
  • Set up Tacc=T2>=10ns=1, Express 2 A clock (access cycle , After reading and writing enable , How long to access the data )
  • Set up Tcoh=T4>=3ns=1, Express 1 A clock , Because when DM9000 After the write signal is cancelled , The data on the data line needs at least 3ns Just disappeared (nOE After reading and writing is cancelled , How long does the selection last )
  • Set up Tcah=0, because CS and CMD It can end at the same time (CS After the selection is cancelled , Address ( That is to say CMD) How long does it take )


The code is as follows , stay init Set... In the entry function



(PS: if DM9000C Can't drive , May be Tacc Time is too short , Result in no data to read , Can be Tacc Make it bigger )

The hardware related parts have been changed , Next, start compiling

6. Compile testing

Before compiling , First, add the kernel header file required by the driver :

#include <asm/delay.h>
#include <asm/irq.h>
#include <linux/irq.h>
#include <asm/io.h>
#include <asm/arch-s3c2410/regs-mem.h>


After the compilation is correct , And we started testing DM9000C The driver :

1) hold dm9dev9000c.c Put it in the kernel drivers/net Under the table of contents , To replace the original kernel DM9000C

2)  modify drivers/net/Makefile 

obj-$(CONFIG_DM9000) += dm9000.o
Change it to ( As shown in the figure below )
obj-$(CONFIG_DM9000) += dm9dev9000c.o



3) make uImage

Here's the picture , Indicates that the new driver has been compiled into the kernel



4)  Start with a new kernel

ifconfig eth0


Here's the picture , Sure ping through , It shows that the transplantation is successful