u-boot-2009.08在mini2440上的移植 增加DM9000网卡驱动

发布者:SereneHarmony最新更新时间:2024-07-01 来源: elecfans关键字:u-boot  mini2440  移植  DM9000网卡驱动 手机看文章 扫描二维码
随时随地手机看文章

移植环境

1,主机环境:VMare下CentOS 5.5 ,1G内存。

2,集成开发环境:Elipse IDE

3,编译编译环境:arm-linux-gcc v4.4.3,arm-none-eabi-gcc v4.5.1。

4,开发板:mini2440,2M nor flash,128M nand flash。

5,u-boot版本:u-boot-2009.08


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】修改static int dm9000_init函数中部分代码,如果不修改这一部分,在使用网卡的时候会报“could not establish link”的错误。

打开/drivers/net/dm9000x.c,定位到377行,修改如下:

 /* Activate DM9000 */
 /* RX enable */
 DM9000_iow(DM9000_RCR, RCR_DIS_LONG | RCR_DIS_CRC | RCR_RXEN);
 /* Enable TX/RX interrupt mask */
 DM9000_iow(DM9000_IMR, IMR_PAR);

 #if 0 //default to link MII interface
 i = 0;
 while (!(phy_read(1) & 0x20)) { /* autonegation complete bit */
  udelay(1000);
  i++;
  if (i == 1650) {
   //printf('could not establish linkn');
   //return 0;
   break;
  }
 }
#endif

【2】对于NFS,增加了延时,否则会出现“*** ERROR: Cannot mount”的错误。

打开/net/nfs.c,定位到36行,修改如下:

#if defined(CONFIG_CMD_NET) && defined(CONFIG_CMD_NFS)

#define HASHES_PER_LINE 65 /* Number of 'loading' hashes per line */
#define NFS_RETRY_COUNT 30
#define NFS_TIMEOUT (CONFIG_SYS_HZ/1000*2000UL) //2000UL

【3】添加网卡芯片(DM9000)的初始化函数

打开board/samsung/mini2440/mini2440.c,定位到194行附近,文件末尾处,修改如下:

int dram_init (void)
{
 gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
 gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;

 return 0;
}

extern int dm9000_initialize(bd_t *bis);//implicit declaration of function 'dm9000_initialize'
#ifdef CONFIG_DRIVER_DM9000
int board_eth_init(bd_t *bis)
{
 return dm9000_initialize(bis);
}
#endif

【4】添加串口 Xmodem 传输协议(可不修改)

对于使用串口传输数据到内存的操作,有可能会用到Xmodem协议。但是原本的kermit协议传输就挺好用的,速度也比较快,所以可添加此功能。

打开/common/cmd_load.c,定位到37行,修改如下:

#if defined(CONFIG_CMD_LOADB)
#if defined(ENABLE_CMD_LOADB_X)
static ulong load_serial_xmodem (ulong offset);
#endif
static ulong load_serial_ymodem (ulong offset);
#endif

然后再定位到480行附近,修改如下:

 if (load_baudrate != current_baudrate) {
  printf ('## Switch baudrate to %d bps and press ENTER ...n',
   load_baudrate);
  udelay(50000);
  gd->baudrate = load_baudrate;
  serial_setbrg ();
  udelay(50000);
  for (;;) {
   if (getc() == 'r')
    break;
  }
 }
#if defined(ENABLE_CMD_LOADB_X)
 if (strcmp(argv[0],'loadx')==0) {
  printf ('## Ready for binary (xmodem) download '
   'to 0x%08lX at %d bps...n',
   offset,
   load_baudrate);

  addr = load_serial_xmodem (offset);

 } else if (strcmp(argv[0],'loady')==0) {
#else
 if (strcmp(argv[0],'loady')==0) {
#endif
  printf ('## Ready for binary (ymodem) download '
   'to 0x%08lX at %d bps...n',
   offset,
   load_baudrate);

  addr = load_serial_ymodem (offset);

再定位到998行附近,修改如下:

static int getcxmodem(void) {
 if (tstc())
  return (getc());
 return -1;
}
#if defined(ENABLE_CMD_LOADB_X)
static ulong load_serial_xmodem (ulong offset)
{
 int size;
 char buf[32];
 int err;
 int res;
 connection_info_t info;
 char xmodemBuf[1024];
 ulong store_addr = ~0;
 ulong addr = 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;
#ifndef CFG_NO_FLASH
   if (addr2info (store_addr)) {
    int rc;

    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 ('%sn', xyzModem_error (err));
 }

 xyzModem_stream_close (&err);
 xyzModem_stream_terminate (false, &getcxmodem);


 flush_cache (offset, size);

 printf ('## Total Size      = 0x%08x = %d Bytesn', size, size);
 sprintf (buf, '%X', size);
 setenv ('filesize', buf);

 return offset;
}
#endif
static ulong load_serial_ymodem (ulong offset)

再定位到1169行,修改如下:

#if defined(CONFIG_CMD_LOADB)
U_BOOT_CMD(
 loadb, 3, 0, do_load_serial_bin,
 'load binary file over serial line (kermit mode)',
 '[ off ] [ baud ]n'
 '    - load binary file over serial line'
 ' with offset 'off' and baudrate 'baud''
);
#if defined(ENABLE_CMD_LOADB_X)
U_BOOT_CMD(
 loadx, 3, 0,    do_load_serial_bin,
 'load binary file over serial line (xmodem mode)',
 '[ off ] [ baud ]n'
 '    - load binary file over serial line'
 ' with offset 'off' and baudrate 'baud''
);
#endif

U_BOOT_CMD(
 loady, 3, 0, do_load_serial_bin,
 'load binary file over serial line (ymodem mode)',
 '[ off ] [ baud ]n'
 '    - load binary file over serial line'
 ' with offset 'off' and baudrate 'baud''
);

【5】修改配置文件,在mini2440.h中加入相关定义

打开/include/configs/mini2440.h,定位到60行附近,修改如下:

/*
 * 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_NET_MULTI  1
#define CONFIG_DRIVER_DM9000 1
#define CONFIG_DM9000_BASE 0x20000300 //网卡片选地址
#define DM9000_IO CONFIG_DM9000_BASE
#define DM9000_DATA (CONFIG_DM9000_BASE+4) //网卡数据地址
#define CONFIG_DM9000_NO_SROM  1
//#define CONFIG_DM9000_USE_16BIT
#undef CONFIG_DM9000_DEBUG

注意:
u-boot-2009.08 可以自动检测DM9000网卡的位数,根据开发板原理图可知网卡的数据位为16位,并且网卡位
于CPU的BANK4上,所以只需在 board/samsung/mini2440/lowlevel_init.S中设置 #define B4_BWSCON (DW16) 即
可,不需要此处的 #define CONFIG_DM9000_USE_16BIT 1

给u-boot加上ping命令,用来测试网络通不通

/*
 * Command line configuration.
 */
#include

#define CONFIG_CMD_CACHE
#define CONFIG_CMD_DATE
#define CONFIG_CMD_ELF
#define CONFIG_CMD_NAND
#define CONFIG_CMD_JFFS2  /* JFFS2 Support*/
#define CONFIG_CMD_PING /*ping command support*/

恢复被注释掉的网卡MAC地址和修改你合适的开发板IP地址以及内核启动参数:

#define CONFIG_BOOTDELAY 3
#define CONFIG_ETHADDR 08:00:3e:26:0a:5b
#define CONFIG_NETMASK     255.255.255.0
#define CONFIG_IPADDR  10.1.0.129
#define CONFIG_SERVERIP  10.1.0.128
#define CONFIG_GATEWAYIP 10.1.0.1
#define CONFIG_OVERWRITE_ETHADDR_ONCE
/*#define CONFIG_BOOTFILE 'elinos-lart' */

定位到139行附近,加入使能串口传输数据到内存的操作:

#define ENABLE_CMD_LOADB_X    1 //使能串口传输数据到内存的操作

#if defined(CONFIG_CMD_KGDB)
#define CONFIG_KGDB_BAUDRATE 115200  /* speed to run kgdb serial port */
/* what's this ? it's not used anywhere */
#define CONFIG_KGDB_SER_INDEX 1  /* which serial port to use */
#endif

4.2,重新编译u-boot,下载到Nand中从Nand启动,查看启动信息和环境变量并使用ping命令测试网卡,操作如下:

Enter your selection: a
USB host is connected. Waiting a download.

Now, Downloading [ADDRESS:30000000h,TOTAL:154934]
RECEIVED FILE SIZE:  154934 (151KB/S, 1S)
Downloaded file at 0x30000000, size = 154924 bytes
Write to flash ok: skipped size = 0x0, size = 0x25d2c

... ...

nand 方式上电重启后:

U-Boot 2009.08 ( 5鏈?09 2011 - 15:01:04)

DRAM:  64 MB
Flash:  2 MB
NAND:  128 MiB
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

Environment size: 141/131068 bytes

ping测试:
[u-boot@MINI2440]# ping 10.1.0.128
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 00:00:00:00:00:00
operating at 100M full duplex mode
*** ERROR: `ethaddr' not set
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 00:00:00:00:00:00
operating at 100M full duplex mode
ping failed; host 10.1.0.128 is not alive

需要设定IP地址和MAC地址

[u-boot@MINI2440]# setenv ipaddr 10.1.0.129
[u-boot@MINI2440]# setenv serverip 10.1.0.128
[u-boot@MINI2440]# setenv setenv ethaddr 12:34:56:78:9A:BC
[u-boot@MINI2440]# saveenv
Saving Environment to NAND...
Erasing Nand...
Erasing at 0x4000000000002 --   0% complete.
Writing to Nand... done
[u-boot@MINI2440]#

然后再进行ping测试:

[u-boot@MINI2440]# ping 10.1.0.128
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 12:34:56:78:9a:bc
operating at 100M full duplex mode
Using dm9000 device
ping failed; host 10.1.0.128 is not alive
[u-boot@MINI2440]#

可以看到,启动信息里面显示了Net:dm9000,printenv查看的环境变量也和include/configs/mini2440.h中设置的一致。但是现在有个问题就是ping不能通过。
经过一段时间在网上搜索,原来有很多人都碰到了这种情况。出现问题的地方可能是DM9000网卡驱动中关闭网卡的地方,如是就试着修改代码如下:

打开drivers/net/dm9000x.c ,定位到456行附近,屏蔽掉dm9000_halt函数中的内容:

/*
  Stop the interface.
  The interface is stopped when it is brought.
*/
static void dm9000_halt(struct eth_device *netdev)
{
#if 0 
 DM9000_DBG('%sn', __func__);

 /* 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 */
#endif 
}

重新编译下载,nand启动,运行结果:

[u-boot@MINI2440]# ping 10.1.0.128
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 00:00:00:00:00:00
operating at unknown: 0 mode
*** ERROR: `ethaddr' not set
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 00:00:00:00:00:00
operating at unknown: 0 mode
ping failed; host 10.1.0.128 is not alive

[1] [2]
关键字:u-boot  mini2440  移植  DM9000网卡驱动 引用地址:u-boot-2009.08在mini2440上的移植 增加DM9000网卡驱动

上一篇:u-boot-2009.08在mini2440上的移植 增加nand flash功能
下一篇:u-boot-2009.08在mini2440上的移植 增加LCD显示功能

推荐阅读最新更新时间:2026-03-19 15:38

【嵌入式】从零开始移植U-bootmini2440(一)——U-boot编译篇
U-boot版本:2020/5/2 编译环境:Ubuntu 16.04 arm-none-eabi-gcc version 4.9.3 20150529 (prerelease) (15:4.9.3+svn231177-1) 运行环境:mini2440(s3c2440,arm920t) 代码仓库:git@github.com:JingyeLi/u-boot_2440.git commit hash:45516b370859b022b9bf2c9fb87318b1fa2d34a3 GitHub上下载最新的u-boot git@github.com:u-boot/u-boot.git 实际上最新的u-boot(好像是从2017年开
[单片机]
【嵌入式】从零开始移植U-bootmini2440(二)——烧录篇
烧录 相关工具:j-link 软件:j-flash ARM V4.70 在编译成功之后,会生成u-boot.bin在output目录下,这个二进制文件就可以直接用于烧录。 烧录位置的确定方法 烧录的时候,我这里选择直接烧写在NOR中,看S3C2440的SPEC和开发板的原理图(找NOR的CE接口和S3C2440哪个引脚相连),当我们选择从NOR启动的时候,NOR Flash被映射到内存0x0000_0000 ~ 0x0800_0000,也就是说我们直接把bin文件烧录到0地址即可。 这里有一篇写的蛮好的blog,解释了ARM是如何通过NOR和NAND启动的。 https://www.cnblogs.com/aaron
[单片机]
【嵌入式】从零开始<font color='red'>移植</font><font color='red'>U-boot</font>到<font color='red'>mini2440</font>(二)——烧录篇
从零开始移植U-bootmini2440(三)——CPU初始化篇
经过前两节的准备,我们现在可以开始肝u-boot的代码了 U-boot版本:2020/5/2 编译环境:Ubuntu 16.04 arm-none-eabi-gcc version 4.9.3 20150529 (prerelease) (15:4.9.3+svn231177-1) 运行环境:mini2440(s3c2440,arm920t) 代码仓库:git@github.com:JingyeLi/u-boot_2440.git https://github.com/JingyeLi/u-boot_2440/tree/v0.1 u-boot.lds 这是一个很容易被人忽略的一个文件,包括我自己,以前一般用keil的时候都是自
[单片机]
搭建一个mini2440开发板U-Boot的框架
一、移植环境 主 机: Ubuntu 开发板:友善之臂mini2440 编译器:arm-linux-gcc-4.3.2 u-boot:u-boot-2009.03.tar.bz2 二、移植步骤 目前u-boot对很多CPU直接支持,可以查看board目录的一些子目录,如:board/samsung/目录下就是对三星一些ARM处理器的支持,有smdk2400、smdk2410和smdk6400,但没有2440,所以我们就在这里建立自己的开发板项目。 1)因2440和2410的资源差不多,主频和外设有点差别,所以我们就在board/samsung/下建立自己开发板的项目,取名叫mini2440 #tar -jx
[单片机]
tiny210(s5pv210)移植u-boot(基于 2014.4 版本号)——移植u-boot.bin(打印串口控制台)
在之前我们移植的代码中,都没看到明显的效果,这节我们实现控制台的信息打印。 在上节。我们看到调用 relocate_code 重定位。在 u-boot 的帮助文档 doc/README.arm-relocation 中对重定位有说明。 u-boot 为了生成位置无关码,在链接时指定了-pie 选项,这个选项在 u-boot-2014.04/arch/arm/config.mk 中指定: 当使用-pie 选项后。链接器会生成一个修正表(fixup tables)。在终于的二进制文件 u-boot.bin 中表现为多了 2 个段 .rel.dyn 和 .dynsym。还须要在链接脚本文件里添加这 2 个段,u-boot.b
[单片机]
tiny210(s5pv210)<font color='red'>移植</font><font color='red'>u-boot</font>(基于 2014.4 版本号)——<font color='red'>移植</font>u-boot.bin(打印串口控制台)
tiny210(s5pv210)移植u-boot(基于 2014.4 版本号)——NAND 8位硬件ECC
这节我们实现nand的ecc,保存环境变量到nand flash 中。然后把我们之前的led灯烧写到nand flash 中。开机启动。在 tiny210.h 中定义宏 CONFIG_S5PV210_NAND_HWECC、CONFIG_SYS_NAND_ECCSIZE、CONFIG_SYS_NAND_ECCBYTES CONFIG_SYS_NAND_ECCSIZE 定义了消息长度。即每多少字节进行 1 次 ECC 校验 CONFIG_SYS_NAND_ECCBYTES 定义为 13Byte,将 drivers/mtd/nand/s5pv210_nand.c 中的 CONFIG_S3C2410_NAND_HWECC 替换为CON
[单片机]
tiny210(s5pv210)<font color='red'>移植</font><font color='red'>u-boot</font>(基于 2014.4 版本号)——NAND 8位硬件ECC
u-boot 移植 --->6、引导Linux启动测试
在引导Linux开机之前需要先清楚Linux启动的必要或者说是先决条件,这里就是提到了u-boot的作用了引用百度云---主要用于嵌入式系统的引导加载,其实在我调试下来总结一下就是初始化硬件这里的硬件包括必要部分和不必要的部分,比如SOC的时钟,外部RAM(DDR内存),栈等。因为linux的内核相对于SOC内部的RAM而言还是比较庞大的,并且运行Linux的SOC的主频普遍是比较高的,受限于flash的访问速度,Linux肯定是不能像单片机的程序一样放在片上flash运行的,毕竟在48M以上的时候常见的单片机都是需要加wait以匹配CPU和flash的速度差距了。所以u-boot一定的需要先初始化好RAM(DDR)然后将linu
[单片机]
u-boot 移植 --->4、Tiny210核心板的DDR初始化下详解
RAM的原理简单学习 DDR是RAM的一种,RAM常见的类型有SRAM,SDRAM,DDR他们的共同特点是,随机存储意味着读写速度快,掉电后数据丢失,所以常用来存储程序中的变量。 SRAM 静态随机存储器英文是static random-access memory 就是保持上电就可以保存数据而不需要刷新。数据线和地址线分离以IS62WV51216这个芯片为例,他数据位宽为16,大小为1MB,地址线宽是19。所以可以访问的空间大小就是2的19次方即524288=512KB,然后数据线是16位了,所以512KB*2 就是这个芯片的全部容量。然后在加上一些必要的控制线比如片选,字节选择等就可以完成读写控制,他的特点是不需要刷新
[单片机]
<font color='red'>u-boot</font> <font color='red'>移植</font> --->4、Tiny210核心板的DDR初始化下详解
小广播
最新单片机文章
何立民专栏 单片机及嵌入式宝典

北京航空航天大学教授,20余年来致力于单片机与嵌入式系统推广工作。

厂商技术中心

 
EEWorld订阅号

 
EEWorld服务号

 
汽车开发圈

 
机器人开发圈

电子工程世界版权所有 京ICP证060456号 京ICP备10001474号-1 电信业务审批[2006]字第258号函 京公网安备 11010802033920号 Copyright © 2005-2026 EEWORLD.com.cn, Inc. All rights reserved