4、 用飞凌官方自带的uboot改写成支持dm9000网卡

时间:2022-06-06 17:13:15

                          参考自http://bbs.witech.com.cn/forum.php?mod=viewthread&tid=16373

1.修改include/configs/smdk6410.h 

       //注释掉下面几行

//#ifdef  CONFIG_DRIVER_SMC911X

//#undef  CONFIG_DRIVER_CS8900  u
//#define CONFIG_DRIVER_SMC911X_BASE  0x18800300   / Z' i2 L( P5 h8 m# H0 F
//#else 
//#define CONFIG_DRIVER_CS8900  0   /* we have a CS8900 on-board */   
//#define CS8900_BASE       0x18800300 
//#define CS8900_BUS16      1   /* the Linux driver does accesses as shorts */ 

//增加下面4行    ) h6 _! A- v9 u+ E
#define CONFIG_DRIVER_DM9000                1   8 W9 a4 G2 F/ d& w3 {- w
#define CONFIG_DM9000_BASE          0x18000000  
#define DM9000_IO                   CONFIG_DM9000_BASE  
#define DM9000_DATA                 (CONFIG_DM9000_BASE+4)  
#define CONFIG_DM9000_USE_16BIT   1
//#define CONFIG_DM9000_DEBUG  3 F* L4 d" n- Y+ B9 g( s( V . X$ S# s- X3 S
3 W7 D) P# j6 S- m, I
2.修改drivers/dm9000x.c 
a.在dm9000x.c中注释以下内容:(从环境变量中读取MAC地址) 4 |' ?7 x* I# C9 u+ o4 D! b& o* R
/* Set Node address */
/* for (i = 0; i < 6; i++)
   ((u16 *) bd->bi_enetaddr)[i] = read_srom_word(i);
*/ 5 s& D1 v( m- o
添加以下内容,代替以上注释内容: * P1 K" U/ \- M3 ~
    char *s, *e;
     s = getenv ("ethaddr");
     for (i = 0; i < 6; ++i) $ o$ c5 w  N# @
{
  bd->bi_enetaddr[i] = s ? simple_strtoul (s, &e, 16) : 0;
    if (s) 6 M# M7 a3 S4 }' A. F: \
      s = (*e) ? e + 1 : e;
}
b.参考Linux内核中代码,发现Linux的dm9000在rx函数中添加do while循环,于是按照Linux内核源码在u-boot中也添加do while循环。红色部分为添加代码。 / z1 P3 z% O; [2 h. e1 y2 P
  g; }  T& o+ s6 S3 H; `
DM9000_ior(DM9000_MRRH);   # J$ }* h9 K. N& N; S. N( `
DM9000_ior(DM9000_MRRL);
do{
/* Check packet ready or not */ ) W: B+ e9 H" y* h
DM9000_ior(DM9000_MRCMDX); /* Dummy read */
rxbyte = DM9000_inb(DM9000_DATA); /* Got most updated data */
if (rxbyte == 0)
          return 0; + q9 V9 E3 m  h, H( V6 Z4 l) N
/* Status check: this byte must be 0 or 1 */
if (rxbyte > 1) {
   DM9000_iow(DM9000_RCR, 0x00); /* Stop Device */
   DM9000_iow(DM9000_ISR, 0x80); /* Stop INT request */ ( _' t7 w3 K; M+ w. H* L3 F: j
   DM9000_DBG("rx status check: %d\n", rxbyte); ; K# ?. R, X( B
}
DM9000_DBG("receiving packet\n"); % j# G" P( a9 ~; ?
/* A packet ready now & Get status/length */ & j2 V1 n5 K. }- i$ ^
DM9000_outb(DM9000_MRCMD, DM9000_IO);
     /* */
RxStatus = DM9000_inw(DM9000_DATA); ( K3 x. u) r* c. x; v2 @3 u; l$ U
RxLen = DM9000_inw(DM9000_DATA);
     /* */ ' Z. Q( ?! S$ M
DM9000_DBG("rx status: 0x%04x rx len: %d\n", RxStatus, RxLen);
/* Move data from DM9000 */ 5 i5 X' @4 u1 u$ x9 k3 i- v
/* Read received packet from RX SRAM */ * l( o$ y4 U/ H* z7 ^$ W% Q
tmplen = (RxLen + 1) / 2;
for (i = 0; i < tmplen; i++)
   {
    ((u16 *) rdptr)[i] = DM9000_inw(DM9000_DATA); 5 K6 r# ]2 l" O+ T! C
    //printf("%d ",((u16 *) rdptr)[i]); - h7 S+ l. D$ m0 [) E  `+ }, n
   }
     /* */ 6 }7 G, x- B  W* X% B! p; b" S5 E
if ((RxStatus & 0xbf00) || (RxLen < 0x40) 9 p# H& K( W. X
     || (RxLen > DM9000_PKT_MAX)) {
   if (RxStatus & 0x100) {
    printf("rx fifo error\n"); . C' ~" R. q2 \
   } 2 B, j+ q& X/ G$ l4 j0 S& d
   if (RxStatus & 0x200) { 1 I0 Y; p! Y% Y' {9 U
    printf("rx crc error\n");
   }
   if (RxStatus & 0x8000) {
    printf("rx length error\n");
   } : @" d6 Q1 o9 K0 \: K
   if (RxLen > DM9000_PKT_MAX) { 3 s* k) E3 y2 ~
    printf("rx length too big\n");
    dm9000_reset();
   }
} else {
   /* Pass to upper layer */ / X! E  A' P9 O, J
   DM9000_DBG("passing packet to upper layer\n");
   NetReceive(NetRxPackets[0], RxLen); 8 L! O. m, }6 m) M, b
   //return RxLen;
} * I/ F( i( V6 Z" p6 B4 T
} 3 Y3 Q2 K# @/ r
while (rxbyte == DM9000_PKT_RDY);
//return 0;
return RxLen;
# m* _2 F( z: ^) t6 v8 X" d1 J
c. 注释掉下面2行,修正一直无法收到数据的错误,不要每次调用halt的时候都对PHY进行复位操作,否则会引起无法接受到数据的情况 .
void eth_halt(void)
{
DM9000_DBG("eth_halt dummy by kyon\n");
/* RESET devie */
//phy_write(0, 0x8000); /* PHY RESET */
//DM9000_iow(DM9000_GPR, 0x01); /* Power-Down PHY */
DM9000_iow(DM9000_IMR, 0x80); /* Disable all interrupt */
DM9000_iow(DM9000_RCR, 0x00); /* Disable RX */ 5 F, o& g

}

4、至此,修改已完成。若ping不通linux主机,可能是环境变量没设好,同时注意有时要将无线关掉,切记:网线要插上

5、精简uboot

smdk6410.h中去掉了有关I2C、USB、RTC、KGDB、等的包涵定义,编译时出错,在/common目录下修改Makefile文件,去掉有关usb的.o文件和cmd_date.o,编译通过。u-boot.bin原来为192k,现在为160k。