Uboot08支持DM9000.docx
《Uboot08支持DM9000.docx》由会员分享,可在线阅读,更多相关《Uboot08支持DM9000.docx(13页珍藏版)》请在冰豆网上搜索。
![Uboot08支持DM9000.docx](https://file1.bdocx.com/fileroot1/2023-1/27/73dec4c1-423c-4eac-9d1c-eac165ab1819/73dec4c1-423c-4eac-9d1c-eac165ab18191.gif)
Uboot08支持DM9000
这个移植要结合以下两篇文章
u-boot-2009.08在mini2440上的移植
u-boot-2009.08版本已经对CS8900、RTL8019和DM9000X等网卡有比较完善的代码支持(代码在drivers/net/目录下),而且在S3C24XX系列中默认对CS8900网卡进行配置使用。
而mini2440开发板使用的则是DM9000网卡芯片,所以只需在开发板上添加对DM9000的支持即可。
还有一点,以前的U-boot对于网络延时部分有问题,需要修改许多地方。
但是现在的U-boot网络
部分已经基本不需要怎么修改了,只有在DM9000的驱动和NFS的TIMEOUT参数上需要稍微修改一下。
4.1,DM9000驱动代码修改
【1】修改staticintdm9000_init函数中部分代码,如果不修改这一部分,在使用网卡的时候会报“couldnotestablishlink”的错误。
打开/drivers/net/dm9000x.c,定位到377行,修改如下:
/*ActivateDM9000*/
/*RXenable*/
DM9000_iow(DM9000_RCR,RCR_DIS_LONG|RCR_DIS_CRC|RCR_RXEN);
/*EnableTX/RXinterruptmask*/
DM9000_iow(DM9000_IMR,IMR_PAR);
#if0//defaulttolinkMIIinterface
i=0;
while(!
(phy_read
(1)&0x20)){ /*autonegationcompletebit*/
udelay(1000);
i++;
if(i==1650){
//printf("couldnotestablishlink\n");
//return0;
break;
}
}
#endif
【2】对于NFS,增加了延时,否则会出现“***ERROR:
Cannotmount”的错误。
打开/net/nfs.c,定位到36行,修改如下:
#ifdefined(CONFIG_CMD_NET)&&defined(CONFIG_CMD_NFS)
#defineHASHES_PER_LINE65 /*Numberof"loading"hashesperline */
#defineNFS_RETRY_COUNT30
#defineNFS_TIMEOUT(CONFIG_SYS_HZ/1000*2000UL)//2000UL
【3】添加网卡芯片(DM9000)的初始化函数
打开board/samsung/mini2440/mini2440.c,定位到194行附近,文件末尾处,修改如下:
intdram_init(void)
{
gd->bd->bi_dram[0].start=PHYS_SDRAM_1;
gd->bd->bi_dram[0].size=PHYS_SDRAM_1_SIZE;
return0;
}
externintdm9000_initialize(bd_t*bis);//implicitdeclarationoffunction'dm9000_initialize'
#ifdefCONFIG_DRIVER_DM9000
intboard_eth_init(bd_t*bis)
{
returndm9000_initialize(bis);
}
#endif
【4】添加串口Xmodem传输协议(可不修改)
对于使用串口传输数据到内存的操作,有可能会用到Xmodem协议。
但是原本的kermit协议传输就挺好用的,速度也比较快,所以可添加此功能。
打开/common/cmd_load.c,定位到37行,修改如下:
#ifdefined(CONFIG_CMD_LOADB)
#ifdefined(ENABLE_CMD_LOADB_X)
staticulongload_serial_xmodem(ulongoffset);
#endif
staticulongload_serial_ymodem(ulongoffset);
#endif
然后再定位到480行附近,修改如下:
if(load_baudrate!
=current_baudrate){
printf("##Switchbaudrateto%dbpsandpressENTER...\n",
load_baudrate);
udelay(50000);
gd->baudrate=load_baudrate;
serial_setbrg();
udelay(50000);
for(;;){
if(getc()=='\r')
break;
}
}
#ifdefined(ENABLE_CMD_LOADB_X)
if(strcmp(argv[0],"loadx")==0){
printf("##Readyforbinary(xmodem)download"
"to0x%08lXat%dbps...\n",
offset,
load_baudrate);
addr=load_serial_xmodem(offset);
}elseif(strcmp(argv[0],"loady")==0){
#else
if(strcmp(argv[0],"loady")==0){
#endif
printf("##Readyforbinary(ymodem)download"
"to0x%08lXat%dbps...\n",
offset,
load_baudrate);
addr=load_serial_ymodem(offset);
再定位到998行附近,修改如下:
staticintgetcxmodem(void){
if(tstc())
return(getc());
return-1;
}
#ifdefined(ENABLE_CMD_LOADB_X)
staticulongload_serial_xmodem(ulongoffset)
{
intsize;
charbuf[32];
interr;
intres;
connection_info_tinfo;
charxmodemBuf[1024];
ulongstore_addr=~0;
ulongaddr=0;
size=0;
info.mode=xyzModem_xmodem;
res=xyzModem_stream_open(&info,&err);
if(!
res){
while((res=
xyzModem_stream_read(xmodemBuf,1024,&err))>0){
store_addr=addr+offset;
size+=res;
addr+=res;
#ifndefCFG_NO_FLASH
if(addr2info(store_addr)){
intrc;
rc=flash_write((char*)xmodemBuf,
store_addr,res);
if(rc!
=0){
flash_perror(rc);
return(~0);
}
}else
#endif
{
memcpy((char*)(store_addr),xmodemBuf,
res);
}
}
}else{
printf("%s\n",xyzModem_error(err));
}
xyzModem_stream_close(&err);
xyzModem_stream_terminate(false,&getcxmodem);
flush_cache(offset,size);
printf("##TotalSize =0x%08x=%dBytes\n",size,size);
sprintf(buf,"%X",size);
setenv("filesize",buf);
returnoffset;
}
#endif
staticulongload_serial_ymodem(ulongoffset)
再定位到1169行,修改如下:
#ifdefined(CONFIG_CMD_LOADB)
U_BOOT_CMD(
loadb,3,0, do_load_serial_bin,
"loadbinaryfileoverserialline(kermitmode)",
"[off][baud]\n"
" -loadbinaryfileoverserialline"
"withoffset'off'andbaudrate'baud'"
);
#ifdefined(ENABLE_CMD_LOADB_X)
U_BOOT_CMD(
loadx,3,0, do_load_serial_bin,
"loadbinaryfileoverserialline(xmodemmode)",
"[off][baud]\n"
" -loadbinaryfileoverserialline"
"withoffset'off'andbaudrate'baud'"
);
#endif
U_BOOT_CMD(
loady,3,0, do_load_serial_bin,
"loadbinaryfileoverserialline(ymodemmode)",
"[off][baud]\n"
" -loadbinaryfileoverserialline"
"withoffset'off'andbaudrate'baud'"
);
【5】修改配置文件,在mini2440.h中加入相关定义
打开/include/configs/mini2440.h,定位到60行附近,修改如下:
/*
*Hardwaredrivers
*/
#if0
#defineCONFIG_DRIVER_CS8900 1 /*wehaveaCS8900on-board*/
#defineCS8900_BASE 0x19000300
#defineCS8900_BUS16 1/*theLinuxdriverdoesaccessesasshorts*/
#endif
#defineCONFIG_NET_MULTI 1
#defineCONFIG_DRIVER_DM90001
#defineCONFIG_DM9000_BASE0x20000300//网卡片选地址
#defineDM9000_IOCONFIG_DM9000_BASE
#defineDM9000_DATA(CONFIG_DM9000_BASE+4)//网卡数据地址
#defineCONFIG_DM9000_NO_SROM 1
//#defineCONFIG_DM9000_USE_16BIT
#undefCONFIG_DM9000_DEBUG
注意:
u-boot-2009.08可以自动检测DM9000网卡的位数,根据开发板原理图可知网卡的数据位为16位,并且网卡位
于CPU的BANK4上,所以只需在board/samsung/mini2440/lowlevel_init.S中设置#defineB4_BWSCON(DW16)即
可,不需要此处的#defineCONFIG_DM9000_USE_16BIT1
给u-boot加上ping命令,用来测试网络通不通
/*
*Commandlineconfiguration.
*/
#include
#defineCONFIG_CMD_CACHE
#defineCONFIG_CMD_DATE
#defineCONFIG_CMD_ELF
#defineCONFIG_CMD_NAND
#defineCONFIG_CMD_JFFS2 /*JFFS2Support*/
#defineCONFIG_CMD_PING/*pingcommandsupport*/
恢复被注释掉的网卡MAC地址和修改你合适的开发板IP地址以及内核启动参数:
#defineCONFIG_BOOTDELAY 3
#defineCONFIG_ETHADDR 08:
00:
3e:
26:
0a:
5b
#defineCONFIG_NETMASK 255.255.255.0
#defineCONFIG_IPADDR 10.1.0.129
#defineCONFIG_SERVERIP 10.1.0.128
#defineCONFIG_GATEWAYIP 10.1.0.1
#defineCONFIG_OVERWRITE_ETHADDR_ONCE
/*#defineCONFIG_BOOTFILE "elinos-lart"*/
定位到139行附近,加入使能串口传输数据到内存的操作:
#defineENABLE_CMD_LOADB_X 1//使能串口传输数据到内存的操作
#ifdefined(CONFIG_CMD_KGDB)
#defineCONFIG_KGDB_BAUDRATE 115200 /*speedtorunkgdbserialport*/
/*what'sthis?
it'snotusedanywhere*/
#defineCONFIG_KGDB_SER_INDEX 1 /*whichserialporttouse*/
#endif
4.2,重新编译u-boot,下载到Nand中从Nand启动,查看启动信息和环境变量并使用ping命令测试网卡,操作如下:
Enteryourselection:
a
USBhostisconnected.Waitingadownload.
Now,Downloading[ADDRESS:
30000000h,TOTAL:
154934]
RECEIVEDFILESIZE:
154934(151KB/S,1S)
Downloadedfileat0x30000000,size=154924bytes
Writetoflashok:
skippedsize=0x0,size=0x25d2c
......
nand方式上电重启后:
U-Boot2009.08(5鏈?
092011-15:
01:
04)
DRAM:
64MB
Flash:
2MB
NAND:
128MiB
In:
serial
Out:
serial
Err:
serial
Net:
dm9000
[u-boot@MINI2440]#
显示下环境变量:
[u-boot@MINI2440]#printenv
bootdelay=3
baudrate=115200
netmask=255.255.255.0
stdin=serial
stdout=serial
stderr=serial
ipaddr=10.1.129
serverip=10.1.0.128
ethact=dm9000
Environmentsize:
141/131068bytes
ping测试:
[u-boot@MINI2440]#ping10.1.0.128
dm9000i/o:
0x20000300,id:
0x90000a46
DM9000:
runningin16bitmode
MAC:
00:
00:
00:
00:
00:
00
operatingat100Mfullduplexmode
***ERROR:
`ethaddr'notset
dm9000i/o:
0x20000300,id:
0x90000a46
DM9000:
runningin16bitmode
MAC:
00:
00:
00:
00:
00:
00
operatingat100Mfullduplexmode
pingfailed;host10.1.0.128isnotalive
需要设定IP地址和MAC地址
[u-boot@MINI2440]#setenvipaddr10.1.0.129
[u-boot@MINI2440]#setenvserverip10.1.0.128
[u-boot@MINI2440]#setenvsetenvethaddr12:
34:
56:
78:
9A:
BC
[u-boot@MINI2440]#saveenv
SavingEnvironmenttoNAND...
ErasingNand...
Erasingat0x4000000000002-- 0%complete.
WritingtoNand...done
[u-boot@MINI2440]#
然后再进行ping测试:
[u-boot@MINI2440]#ping10.1.0.128
dm9000i/o:
0x20000300,id:
0x90000a46
DM9000:
runningin16bitmode
MAC:
12:
34:
56:
78:
9a:
bc
operatingat100Mfullduplexmode
Usingdm9000device
pingfailed;host10.1.0.128isnotalive
[u-boot@MINI2440]#
可以看到,启动信息里面显示了Net:
dm9000,printenv查看的环境变量也和include/configs/mini2440.h中设置的一致。
但是现在有个问题就是ping不能通过。
经过一段时间在网上搜索,原来有很多人都碰到了这种情况。
出现问题的地方可能是DM9000网卡驱动中关闭网卡的地方,如是就试着修改代码如下:
打开drivers/net/dm9000x.c ,定位到456行附近,屏蔽掉dm9000_halt函数中的内容:
/*
Stoptheinterface.
Theinterfaceisstoppedwhenitisbrought.
*/
staticvoiddm9000_halt(structeth_device*netdev)
{
#if0
DM9000_DBG("%s\n",__func__);
/*RESETdevie*/
phy_write(0,0x8000); /*PHYRESET*/
DM9000_iow(DM9000_GPR,0x01); /*Power-DownPHY*/
DM9000_iow(DM9000_IMR,0x80); /*Disableallinterrupt*/
DM9000_iow(DM9000_RCR,0x00); /*DisableRX*/
#endif
}
重新编译下载,nand启动,运行结果:
[u-boot@MINI2440]#ping10.1.0.128
dm9000i/o:
0x20000300,id:
0x90000a46
DM9000:
runningin16bitmode
MAC:
00:
00:
00:
00:
00:
00
operatingatunknown:
0mode
***ERROR:
`ethaddr'notset
dm9000i/o:
0x20000300,id:
0x90000a46
DM9000:
runningin16bitmode
MAC:
00:
00:
00:
00:
00:
00
operatingatunknown:
0mode
pingfailed;host10.1.0.128isnotalive
[u-boot@MINI2440]#setenvgatewayip10.1.0.1
[u-boot@MINI2440]#setenvethaddr12:
34:
56:
78:
9a:
bc//MAC地址,随便设
[u-boot@MINI2440]#ping10.1.0.128
dm9000i/o:
0x20000300,id:
0x90000a46
DM9000:
runningin16bitmode
MAC:
12:
34:
56:
78:
9a:
bc
operatingatunknown:
0mode
Usingdm9000device
host10.1.0.128isalive
[u-boot@MINI2440]#saveenv
SavingEnvironmenttoNAND...
ErasingNand...
Erasingat0x4000000000002-- 0%complete.
WritingtoNand...done
[u-boot@MINI2440]#ping10.1.0.128
dm9000i/o:
0x20000300,id:
0x90000a46
DM9000:
runningin16bitmode
MAC:
12:
34:
56:
78:
9a:
bc
operatingatunknown:
0mode
Usingdm9000device
host10.1.0.128isalive
[u-boot@MINI2440]#
结果,只是第一次ping不通,以后都是可以ping通的(据网友们说这是正常的)。
4.3,tftp功能测试
首先需要将友善官方移植好的有关mini2440的内核文件zImage_T35复制到linux宿主机的/tftpboot目录下,因为u-boot默认的此目录,然后执行:
[u-boot@MINI2440]#tftp0x