转载 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 link\n”);
//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 (“%s\n”, xyzModem_error (err));
}
xyzModem_stream_close (&err);
xyzModem_stream_terminate (false, &getcxmodem);
flush_cache (offset, size);
printf (“## Total Size = 0x%08x = %d Bytes\n”, 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 <config_cmd_default.h>
#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(“%s\n”, __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
[u-boot@MINI2440]# setenv gatewayip 10.1.0.1
[u-boot@MINI2440]# setenv ethaddr 12:34:56:78:9a:bc //MAC地址,随便设
[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 unknown: 0 mode
Using dm9000 device
host 10.1.0.128 is alive
[u-boot@MINI2440]# saveenv
Saving Environment to NAND…
Erasing Nand…
Erasing at 0x4000000000002 – 0% complete.
Writing to Nand… done
[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 unknown: 0 mode
Using dm9000 device
host 10.1.0.128 is alive
[u-boot@MINI2440]#
结果,只是第一次ping不通,以后都是可以ping通的(据网友们说这是正常的)。
4.3,tftp功能测试
首先需要将友善官方移植好的有关mini2440的内核文件zImage_T35复制到linux 宿主机的/tftpboot目录下,因为u-boot默认的此目录,然后执行:
[u-boot@MINI2440]# tftp 0x30008000 zImage_T35
dm9000 i/o: 0x20000300, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 12:34:56:78:9a:bc
operating at unknown: 0 mode
Using dm9000 device
TFTP from server 10.1.0.128; our IP address is 10.1.0.129
Filename ‘zImage_T35’.
Load address: 0x30008000
Loading: T ################################################T #################
#############T T ######################T ##############################
T T
########
done
Bytes transferred = 2022348 (1edbcc hex)
[u-boot@MINI2440]#
至此DM9000网卡驱动移植成功。但是还发现一个问题:”这里之前还是”operating at 100M full duplex mode“,而现在怎么是”operating at unknown: 0 mode“?原来是dm9000的phy_read(int reg)函数延时出了问题,现操作如下:
打开/drivers/net/dm9000x.c,定位到595行附近,修改如下:
/*
Read a word from phyxcer
*/
static u16
phy_read(int reg)
{
u16 val;
/* Fill the phyxcer register into REG_0C */
DM9000_iow(DM9000_EPAR, DM9000_PHY | reg);
DM9000_iow(DM9000_EPCR, 0xc); /* Issue phyxcer read command */
udelay(1000); //udelay(100); /* Wait read complete */
DM9000_iow(DM9000_EPCR, 0x0); /* Clear phyxcer read command */
val = (DM9000_ior(DM9000_EPDRH) << 8) | DM9000_ior(DM9000_EPDRL);
/* The read data keeps on REG_0D & REG_0E */
DM9000_DBG(“phy_read(0x%x): 0x%x\n”, reg, val);
return val;
}
重新编译下载后:
[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 unknown: 15 mode
Using dm9000 device
ping failed; host 10.1.0.128 is not alive
[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
host 10.1.0.128 is alive
[u-boot@MINI2440]#
可以看到”operating at 100M full duplex mode“这样的信息了
上面还有一个问题,就是问什么第一次ping不通呢?经过尝试,操作如下:
打开/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 1 //internet delay loop
i = 0;
while (!(phy_read(1) & 0x20)) { /* autonegation complete bit */
udelay(1000);
i++;
if (i == 3000) {
printf(“could not establish link\n”);
return 0;
//break;
}
}
#endif
修改后重新编译下载:
[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
host 10.1.0.128 is alive
[u-boot@MINI2440]#
OK! 第一次ping不通的问题解决了!
接下来将进入u-boot的第五阶段,为u-boot-2009.08增加yaffs2文件系统。
转载 DM9000的调试相关推荐
- linux下jtag命令,[转载]LINUX内核调试过程(使用OpenJtag + OpenOCD)
[转载]LINUX内核调试过程(使用OpenJtag + OpenOCD) (2012-04-12 02:02:27) 标签: 杂谈 [转载]LINUX内核调试过程(使用OpenJtag + Open ...
- x210ii DM9000驱动调试成功-基于x210ii/s5pv210开发板
//-------------------------------------------------------------------------------------------------- ...
- 单片机驱动DM9000网卡芯片(详细调试过程)【下】
http://hi.baidu.com/mcu8031/blog/item/c95903138671c625dc540171.html 单片机驱动DM9000网卡芯片(详细调试过程)[下] 4.验证初 ...
- linux内核调试指南
Hunnad的专栏 * 条新通知 * 登录 * 注册 * 欢迎 * 退出 * 我的博客 * 配置 * 写文章 * 文章管理 * 博客首页 * * * * 空间 * 博客 * 好友 * 相册 * 留言 ...
- art-template入门(四)之调试
转载自 art-template调试 template.defaults.debug art-template 内建调试器,能够捕获到语法与运行错误,并且支持自定义的语法.在 NodeJS 中调试模 ...
- TWR_MPC8309调试日志
版权声明:本文为博主原创文章,未经博主允许不得转载. TWR_MPC8309调试日志 --------By Moresung Chan , At 12:00 ,Sep 16,2012 一.软硬件: P ...
- CLion调试redis6源码
背景 clion使用cmake来管理编译redis源码,而redis源码本身使用原生的make,因此直接将redis源码导入clion无法直接运行,需要配置cmake. 写c程序大体步骤为: 1).用 ...
- kdevelop怎么调试_使用Kdevelop4调试ns
在ubuntu12下,写了一个C++模块和tcl脚本,结果运行出现Segmentation fault错误,这一般是C++程序的问题.怎么调试呢? 使用Kdevelop4调试ns(kdevelop的安 ...
- pycharm一直没显示运行步骤,只是出现waiting for process detach;各类音乐免费软件;最棒的下载torch-geometric
pycharm一直没显示运行步骤,只是出现waiting for process detach: (92条消息) [转载]pycharm调试卡住问题_糖豆豆今天也要努力鸭的博客-CSDN博客_pych ...
- VsCode写C# 猜猜随机数0-9(限制三次机会)可循环使用
VsCode写C# 猜猜随机数(限制三次机会)可循环使用 前言 最近在跟着老师学习C#,老师推荐用的是Visual Studio,但是自从装过各种各样的软件后,c盘容量日益减少,实在不敢给c盘装Vis ...
最新文章
- DotNetNuke安装与下载
- C++的那些事:你真的了解引用吗
- mysql 修改配置生效_linux下面MySQL变量修改及生效
- UVALive 4035 - Undetectable Tour(并查集)
- apollo集群部署_ribbon+apollo实现灰度发布
- append有时加载不出来_关于艾拉浏览器看漫画,有时加载慢的解决方法,你知道了吗...
- .NET Standard 来日苦短去日长
- redis将散裂中某个值自增_Redis总结
- 时空大数据实践之GeoWave安装部署实践
- 滑动窗口解决最小子串问题 leetcode3. Longest Substring Without Repeating Characters
- (16)FPGA面试技能提升篇(Python)
- linux平台设备驱动模型是什么意思,Linux设备驱动模型之我理解
- 朋友很喜欢打篮球,我用Python爬取了1000张他喜欢的NBA球星图片送给他【内附源码】
- testng_TestNG注释
- PyQt5 电报实时聊天软件 BB-Telegram Pt.0
- python实现搜索功能_python实现百度识图搜索功能
- 一文搞定学术英语写作 (斯坦福SCI论文写作课程笔记)
- 电动车实名制挂牌管理系统java+springboot+ssm
- Activity及其生命周期
- 史上最全的数据库面试题,面试前刷一刷!
热门文章
- 图论邮递员问题程序代码_图论的简短实用程序员指南
- 计算广告学习资料汇总
- 百度移动开放平台认领应用--apk 空包签名
- 安防摄像头移动侦测和遮挡侦测基本原理
- 【自制】3D全息投影
- Linux下报ora-12162,ORA-12162: TNS:net service name is incorrectly specified
- WIN10桌面美化(折腾)
- 静态树表的查找(最优查找树和次优查找树)
- 数据总线,地址总线,控制总线
- e480Linux无法发现无线网卡,ThinkPad无线不能用无法连接无线网络的具体排查流程图解...