U-Boot1.1.6移植DM9000網卡

原文鏈接 http://www.100ask.org/bbs/forum.php?mod=viewthread&tid=3655&extra=&highlight=DM9000&page=1

https://blog.csdn.net/bood123/article/details/51482758

 

根據書《嵌入式Linux應用開發完全手冊》移植網卡驅動,對於Jz2440開發板好像並不適用,Jz2440開發板使用的是DM9000網卡,已經不是書上講的CS8900網卡了。DM9000網卡與CS8900網卡接口方式不一樣,經過幾天的折騰,終於移植成功,現將筆記整理如下。


一、移植環境
 

1.u-boot版本1.1.6

2.開發板Jz2440(ARM9       S3C2440

                          NAND       K9F2G08

                          SDRAM     K4S561632 * 2

               網卡      DM9000)

3.Linux: ubuntu 9.10


二、移植思路
 

       查看u-boot-1.1.6源碼發現,u-boot中已經包含dm9000的驅動文件dm9000x.c,所以我們只需要設置u-boot支持網卡就行。總體思路主要完成以下幾件事情:

       1.設置存儲控制器,也就是設置S3C2440的BANK以使用DM9000;

       2.配置u-boot使用DM9000網卡;

       3.設置IP、serverIP等。


三、設置存儲控制器
 

       根據Jz2440開發板的原理圖可知,DM9000網卡  使用的是BANK4,如圖3.1所示。

 

圖3.1 DM9000原理圖

       由圖可知,DM9000網卡使用的片選信號是nGCS 4,也就說明DM9000使用了BANK4。修改lowlevel_init.S(路徑:board/smdk2410/lowlevel_init.S)。

/* BWSCON */

#define DW8      (0x0)

#define DW16    (0x1)

#define DW32    (0x2)

#define WAIT    (0x1<<2)

#define UBLB    (0x1<<3)

#define B1_BWSCON    (DW32)

#define B2_BWSCON    (DW16)

#if 0

#define B3_BWSCON    (DW16 + WAIT + UBLB)

#endif

#define B3_BWSCON    (DW16 + UBLB)

#define B4_BWSCON    (DW16 + WAIT + UBLB)

#define B5_BWSCON    (DW16)

#define B6_BWSCON    (DW32)

#define B7_BWSCON    (DW32)

    修改前BANK3外接的CS8900網卡,將BANK3註釋掉,修改數據寬度爲16位,設置BANK4數據寬度16位,使用WAIT和nBE信號。

#define B4_Tacs    0x0    /*0clk */

#define B4_Tcos    0x3    /*4clk */

#define B4_Tacc    0x7    /* 14clk */

#define B4_Tcoh    0x1    /*1clk */

#define B4_Tah      0x3    /*4clk */

#define B4_Tacp    0x6    /*6clk */

#define B4_PMC    0x0    /* normal */

    根據DM9000數據手冊設置時序,具體見DM9000數據手冊。


四、配置u-boot使用DM9000網卡
 

       修改配置文件smdk2410.h(路徑:include/configs/smdk2410.h)。

/** Hardware drivers*/

#if 0

#define CONFIG_DRIVER_CS8900    1
/* we have a CS8900 on-board */

#define CS8900_BASE                       0x19000300

#define CS8900_BUS16                      1 /* the Linux driver does accesses as shorts */

#endif

#define CONFIG_DRIVER_DM9000      1 /* we have a DM9000 on-board */

#define CONFIG_DM9000_USE_16BIT 1

#define CONFIG_DM9000_BASE          0x20000000

#define DM9000_DATA                        0x20000004

#define DM9000_IO                             0x20000000

    註釋掉CS8900的信息,添加DM9000的配置信息。

    宏定義CONFIG_DRIVER_DM9000爲1表示配置使用DM9000網卡,u-boot編譯時會將DM9000相關的驅動編譯進去。其中0x20000000是DM9000的基址(BANK4),由於DM9000只有一條地址線CMD(LADDR2,見圖3.1)用於區別是數據還是地址(CMD爲低時數據總線上傳輸的是地址信號,CMD爲高時傳輸的是數據信號),所以DM9000_DATA爲0x20000004,DM9000_IO爲0x20000000。


五、設置IP、serverIP
 

       在配置文件smdk2410.h(路徑:include/configs/smdk2410.h)中根據實際情況修改開發板的IP地址,serverIP。

    修改前:

#define CONFIG_NETMASK    255.255.255.0

#define CONFIG_IPADDR       10.0.0.110

#define CONFIG_SERVERIP    10.0.0.1

    修改後:

#define CONFIG_NETMASK    255.255.255.0

#define CONFIG_IPADDR       192.168.1.6

#define CONFIG_SERVERIP    192.168.1.2

    我的PC和開發板使用路由器相連,PC IP地址爲192.168.1.2,開發板設置爲192.168.1.6,保證在同一個網段就行。

增加ping命令:

#define CONFIG_COMMANDS \
               (CONFIG_CMD_DFL| \
                  CFG_CMD_CACHE| \
                /*CFG_CMD_NAND|*/ \
           /*CFG_CMD_EEPROM |*/ \
                     /*CFG_CMD_I2C|*/ \
                    /*CFG_CMD_USB|*/ \

                 FG_CMD_REGINFO| \

                     CFG_CMD_PING| \
                     CFG_CMD_DATE| \
                        CFG_CMD_ELF)

 

    仿照CMD命令格式,我們使用CFG_CMD_PING增加對ping的支持。


六、遇到問題vs解決方案
 

       以上任務完成,在u-boot根目錄下編譯,編譯成功!

使用OpenJtag將編譯完成的u-boot.bin燒入開發板運行。u-boot啓動後,使用print命令查看u-boot的參數:

Jz2440 # print

bootdelay=3

baudrate=115200

ethaddr=08:00:3e:26:0a:5b

ipaddr=192.168.1.6

serverip=192.168.1.2

netmask=255.255.255.0

stdin=serial

stdout=serial

stderr=serial

    看到開發板的IP、serverIP已經修改成功。我們使用ping命令ping一下PC 192.168.1.2。

Jz2440 # ping 192.168.1.2

dm9000 i/o: 0x20000000, id: 0x90000a46

MAC: 50:50:50:50:50:50

could not establish link

ping failed; host 192.168.1.2 is not alive


        host is not alive ,ping不通,看來存在問題!

    上網搜索了很久,網上的都是教你屏蔽這一段代碼,屏蔽那一段代碼,然後就可以了,都沒有詳細的分析,看不大明白。後來,通過研究高版本的u-boot,發現了問題所在。

    打開高版本u-boot,u-boot-1.3.4中的dm9000x.c,可以看到如下更新說明:

06/03/2008    Remy Bohmer <[email protected]>

-Fixed the driver to work with DM9000A.

 

    發現DM9000驅動在後續版本中更新了,老版本的(u-boot-1.1.6)對DM9000支持可能存在問題。

    發現了問題,馬上更新試試看,複製u-boot-1.3.4中的dm9000x.c到u-boot-1.1.6中,覆蓋掉原來的dm9000x.c,然後編譯。

出現了錯誤!

drivers/dm9000x.c:480: undefined reference to `is_zero_ether_addr'

/drivers/dm9000x.c:480: undefined reference to `is_multicast_ether_addr'

make: *** [u-boot] Error 1

    很明顯,缺少兩個函數定義。網上搜索也沒有找到,乾脆對u-boot-1.3.4建立SourceInsight工程搜索這兩個函數。發現這兩個函數都存在於net.h中(路徑:include/net.h)。

    複製這兩個函數,到自己的u-boot(目前爲u-boot-1.1.6)的net.h中(路徑:include/net.h)

/*

*
* is_zero_ether_addr - Determine if give Ethernet address is all zeros.
* @addr: Pointer to a six-byte array containing the Ethernet address
*
* Return true if the address is all zeroes.
*/

static inline int is_zero_ether_addr(const u8 *addr)

{
    return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]);

}



 

/*

*
* is_multicast_ether_addr - Determine if the Ethernet address is a multicast.
* @addr: Pointer to a six-byte array containing the Ethernet address
*
* Return true if the address is a multicast address.
* By definition the broadcast address is also a multicast address.
*/

static inline int is_multicast_ether_addr(const u8 *addr)

{
    return (0x01 & addr[0]);

}

 

    然後編譯,通過!

    燒寫到開發板,ping主機192.168.1.2:

Jz2440 # ping 192.168.1.2

ERROR: resetting DM9000 -> not responding

dm9000 i/o: 0x20000000, id: 0x90000a46

DM9000: running in 16 bit mode

MAC: 08:00:3e:26:0a:5b

could not establish link

host 192.168.1.2 is alive

    “host 192.168.1.2 is alive”, ping通了,DM9000移植OK!


七、網絡測試

1.測試tftp
 

     通過tftp傳輸一個程序到內存中運行試試看。在主機上打開tftp軟件,將leds.bin(運行地址在0x30000000)放在tftp軟件目錄中,在u-boot界面,輸入命令:

Jz2440 # tftp 0x30000000 leds.bin

ERROR: resetting DM9000 -> not responding

dm9000 i/o: 0x20000000, id: 0x90000a46

DM9000: running in 16 bit mode

MAC: 08:00:3e:26:0a:5b

could not establish link

TFTP from server 192.168.1.2; our IP address is 192.168.1.6

Filename 'leds.bin'.

Load address: 0x30000000

Loading: #

done

Bytes transferred = 168 (a8 hex)

    傳輸成功,在u-boot界面使用go命令運行程序

Jz2440 # go 0x30000000

## Starting application at 0x30000000 ...

    可以看到Jz2440開發板上led已經在循環閃爍了。


2.測試nfs
 

    由於虛擬機Linux上開啓了nfs服務,虛擬機Linux IP爲192.168.1.3,需要先更改serverIP。

Jz2440 # setenv serverip 192.168.1.3

Jz2440 # saveenv

    然後將leds.bin放在nfs目錄,/work/nfs_root/,在u-boot界面使用nfs傳輸文件

Jz2440 # nfs 0x30000000 192.168.1.3:/work/nfs_root/leds.bin

ERROR: resetting DM9000 -> not responding

dm9000 i/o: 0x20000000, id: 0x90000a46

DM9000: running in 16 bit mode

MAC: 08:00:3e:26:0a:5b

could not establish link

File transfer via NFS from server 192.168.1.3; our IP address is 192.168.1.6

Filename '/work/nfs_root/leds.bin'.

Load address: 0x30000000

Loading: #

done

Bytes transferred = 168 (a8 hex)

    傳輸成功,在u-boot界面使用go命令運行程序

Jz2440 # go 0x30000000

## Starting application at 0x30000000 ...

    可以看到Jz2440開發板上led已經在循環閃爍了。

    至此,DM9000網卡移植成功!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章