我的博客已迁移至自建服务器:博客传送门,CSDN博客暂时停止,如有机器学习方面的兴趣,欢迎来看一看。
此外目前我在gitHub上准备一些李航的《统计学习方法》的实现算法,目标将书内算法全部手打实现,欢迎参观并打星。GitHib传送门
一. 在Uboot中搜索DM9000,可以找到dm9000x.c,说明uboot是可以支持dm9000的。该文件的路径为:drivers\net\Dm9000x.c
,找到net目录下的Makefile
COBJS-$(CONFIG_DRIVER_DM9000) += dm9000x.o
dm9000x是否编译取决于宏CONFIG_DRIVER_DM9000
,同样,uboot原先默认的网卡是cs8900
,它的宏取决于CONFIG_CS8900
。进入smdk2440.h
对宏进行配置
#define CONFIG_CS8900 /* we have a CS8900 on-board */
#define CONFIG_CS8900_BASE 0x19000300
#define CONFIG_CS8900_BUS16 /* the Linux driver does accesses as shorts */
把原先的8900的宏取消,添加dm9000的宏
#if 0
#define CONFIG_CS8900 /* we have a CS8900 on-board */
#define CONFIG_CS8900_BASE 0x19000300
#define CONFIG_CS8900_BUS16 /* the Linux driver does accesses as shorts */
#else
#define CONFIG_DRIVER_DM9000
#endif
二. 编译,出错,结果如下
dm9000x.c: In function 'dm9000_outblk_8bit':
dm9000x.c:156: error: 'DM9000_DATA' undeclared (first use in this function)
dm9000x.c:156: error: (Each undeclared identifier is reported only once
dm9000x.c:156: error: for each function it appears in.)
dm9000x.c: In function 'dm9000_outblk_16bit':
dm9000x.c:165: error: 'DM9000_DATA' undeclared (first use in this function)
dm9000x.c: In function 'dm9000_outblk_32bit':
dm9000x.c:173: error: 'DM9000_DATA' undeclared (first use in this function)
dm9000x.c: In function 'dm9000_inblk_8bit':
dm9000x.c:180: error: 'DM9000_DATA' undeclared (first use in this function)
dm9000x.c: In function 'dm9000_inblk_16bit':
dm9000x.c:189: error: 'DM9000_DATA' undeclared (first use in this function)
dm9000x.c: In function 'dm9000_inblk_32bit':
dm9000x.c:197: error: 'DM9000_DATA' undeclared (first use in this function)
dm9000x.c: In function 'dm9000_rx_status_32bit':
dm9000x.c:204: error: 'DM9000_IO' undeclared (first use in this function)
dm9000x.c:206: error: 'DM9000_DATA' undeclared (first use in this function)
dm9000x.c: In function 'dm9000_rx_status_16bit':
dm9000x.c:213: error: 'DM9000_IO' undeclared (first use in this function)
dm9000x.c:215: error: 'DM9000_DATA' undeclared (first use in this function)
dm9000x.c: In function 'dm9000_rx_status_8bit':
dm9000x.c:221: error: 'DM9000_IO' undeclared (first use in this function)
dm9000x.c:224: error: 'DM9000_DATA' undeclared (first use in this function)
dm9000x.c: In function 'dm9000_probe':
dm9000x.c:243: error: 'CONFIG_DM9000_BASE' undeclared (first use in this function)
dm9000x.c: In function 'dm9000_send':
dm9000x.c:420: error: 'DM9000_IO' undeclared (first use in this function)
dm9000x.c: In function 'dm9000_rx':
dm9000x.c:484: error: 'DM9000_DATA' undeclared (first use in this function)
dm9000x.c: In function 'DM9000_ior':
dm9000x.c:574: error: 'DM9000_IO' undeclared (first use in this function)
dm9000x.c:575: error: 'DM9000_DATA' undeclared (first use in this function)
dm9000x.c: In function 'DM9000_iow':
dm9000x.c:584: error: 'DM9000_IO' undeclared (first use in this function)
dm9000x.c:585: error: 'DM9000_DATA' undeclared (first use in this function)
make[1]: *** [dm9000x.o] Error 1
make[1]: Leaving directory `/work/system/u-boot-2012.04.01/drivers/net'
make: *** [drivers/net/libnet.o] Error 2
找打第一个错误,是说DM9000_DATA
未定义。在linux中uboot的文件夹内搜索这个宏,看看别人怎么使用的
book@book-desktop:/work/system/u-boot-2012.04.01$ grep "DM9000_DATA" * -nR
结果如下:
drivers/net/dm9000x.c:156: DM9000_outb((((u8 *) data_ptr)[i] & 0xff), DM9000_DATA);
drivers/net/dm9000x.c:165: DM9000_outw(((u16 *) data_ptr)[i], DM9000_DATA);
drivers/net/dm9000x.c:173: DM9000_outl(((u32 *) data_ptr)[i], DM9000_DATA);
drivers/net/dm9000x.c:180: ((u8 *) data_ptr)[i] = DM9000_inb(DM9000_DATA);
drivers/net/dm9000x.c:189: ((u16 *) data_ptr)[i] = DM9000_inw(DM9000_DATA);
drivers/net/dm9000x.c:197: ((u32 *) data_ptr)[i] = DM9000_inl(DM9000_DATA);
drivers/net/dm9000x.c:206: tmpdata = DM9000_inl(DM9000_DATA);
drivers/net/dm9000x.c:215: *RxStatus = __le16_to_cpu(DM9000_inw(DM9000_DATA));
drivers/net/dm9000x.c:216: *RxLen = __le16_to_cpu(DM9000_inw(DM9000_DATA));
drivers/net/dm9000x.c:224: __le16_to_cpu(DM9000_inb(DM9000_DATA) +
drivers/net/dm9000x.c:225: (DM9000_inb(DM9000_DATA) << 8));
drivers/net/dm9000x.c:227: __le16_to_cpu(DM9000_inb(DM9000_DATA) +
drivers/net/dm9000x.c:228: (DM9000_inb(DM9000_DATA) << 8));
drivers/net/dm9000x.c:484: rxbyte = DM9000_inb(DM9000_DATA) & 0x03;
drivers/net/dm9000x.c:575: return DM9000_inb(DM9000_DATA);
drivers/net/dm9000x.c:585: DM9000_outb(value, DM9000_DATA);
include/configs/trizepsiv.h:303:#define DM9000_DATA (CONFIG_DM9000_BASE+0x8004)
include/configs/scb9328.h:249:#define DM9000_DATA (CONFIG_DM9000_BASE+4)
include/configs/pm9261.h:258:#define DM9000_DATA (CONFIG_DM9000_BASE + 4)
include/configs/M5253DEMO.h:95:# define DM9000_DATA (CONFIG_DM9000_BASE + 4)
include/configs/devkit8000.h:81:#define DM9000_DATA (CONFIG_DM9000_BASE + 0x400)
include/configs/ip04.h:78:#define DM9000_DATA (CONFIG_DM9000_BASE + 2)
include/configs/colibri_pxa270.h:84:#define DM9000_DATA (CONFIG_DM9000_BASE + 4)
include/configs/davinci_dm355evm.h:56:#define DM9000_DATA (CONFIG_DM9000_BASE + 2)
include/configs/at91sam9261ek.h:159:#define DM9000_DATA (CONFIG_DM9000_BASE + 4)
include/configs/vpac270.h:113:#define DM9000_DATA (CONFIG_DM9000_BASE + 4)
include/configs/davinci_dm355leopard.h:55:#define DM9000_DATA (CONFIG_DM9000_BASE + 16)
随便找了一个文件进入看看(后面的+Num是打开以后定位到该文件的某行)
vi include/configs/vpac270.h +113
结果如下:
#define CONFIG_DM9000_BASE 0x08000300 /* CS2 */
#define DM9000_IO (CONFIG_DM9000_BASE)
#define DM9000_DATA (CONFIG_DM9000_BASE + 4)
所以我也把它直接这样加我的我文件里了
#if 0
#define CONFIG_CS8900 /* we have a CS8900 on-board */
#define CONFIG_CS8900_BASE 0x19000300
#define CONFIG_CS8900_BUS16 /* the Linux driver does accesses as shorts */
#else
#define CONFIG_DRIVER_DM9000
#define CONFIG_DM9000_BASE 0x20000000 //这三个是新加的
#define DM9000_IO CONFIG_DM9000_BASE //这三个是新加的
#define DM9000_DATA (CONFIG_DM9000_BASE + 4) //这三个是新加的
#endif
网卡属于内存设备,它的片选由写入的地址范围决定,我的dm9000根据硬件接线,如果写入的地址在0x20000000
到0x30000000
,它会被选中,所以其中CONFIG_DM9000_BASE
值改为0x20000000
,DM9000_DATA
是命令数据引脚,我的是bit2,1时为数据,用十进制表示是4,所以值修改为(CONFIG_DM9000_BASE + 4)
三,编译,烧写,运行
U-Boot 2012.04.01 (Aug 13 2016 - 17:00:33)
CPUID: 32440001
FCLK: 400 MHz
HCLK: 100 MHz
PCLK: 50 MHz
DRAM: 64 MiB
WARNING: Caches not enabled
Flash: 2 MiB
NAND: 256 MiB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Net: No ethernet found.
SMDK2410 #
没有检测到网卡,还是有问题。网卡那块重头检查一遍
start.S
cpu_init_crit
lowlevel_init
先检查了一遍寄存器位宽和时间参数有没有正确,我最后没有做修改。
start.S
board_init_r
eth_initialize
board_eth_init
在这个函数中发现了问题
#ifdef CONFIG_CMD_NET
int board_eth_init(bd_t *bis)
{
int rc = 0;
#ifdef CONFIG_CS8900
rc = cs8900_initialize(0, CONFIG_CS8900_BASE);
#endif
return rc;
}
#endif
网卡的初始化,只宏定义了8900,现在宏没有定义,程序里面什么都没执行,9000没有进行初始化,进入dm9000x.c,看看有没有提供初始化函数。
int dm9000_initialize(bd_t *bis)
找到了函数,在board_eth_init中添加进去
#ifdef CONFIG_DRIVER_DM9000
rc = dm9000_initialize(bis);
#endif
只要定义了dm9000,就执行9000的初始化,如果定义了8900,就初始化8900。
四. 编译,烧写
U-Boot 2012.04.01 (Aug 13 2016 - 17:38:05)
CPUID: 32440001
FCLK: 400 MHz
HCLK: 100 MHz
PCLK: 50 MHz
DRAM: 64 MiB
WARNING: Caches not enabled
Flash: 2 MiB
NAND: 256 MiB
*** Warning - bad CRC, using default environment
In: serial
Out: serial
Err: serial
Net: dm9000
SMDK2410 #
已经检测到dm9000了,设置一下ip地址,地址随便设的,然后试试ping一下
SMDK2410 # set ipaddr 192.168.1.120
SMDK2410 # ping 192.168.1.119
ERROR: resetting DM9000 -> not responding
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 00:00:00:00:00:00
could not establish link
*** ERROR: `ethaddr' not set
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 00:00:00:00:00:00
could not establish link
ping failed; host 192.168.1.119 is not alive
出现了错误,ethaddr
还没有设置,mac
地址copy
的lunix
虚拟机的mac
,mac
不能自己随便写,它有自己的格式。
SMDK2410 # set ethaddr 00:0c:29:d3:fe:1d
再次ping
SMDK2410 # ping 192.168.1.119
ERROR: resetting DM9000 -> not responding
dm9000 i/o: 0x20000000, id: 0x90000a46
DM9000: running in 16 bit mode
MAC: 00:0c:29:d3:fe:1d
could not establish link
Using dm9000 device
host 192.168.1.119 is alive
成功了,试着用网络下载内核试试,在winPC端打开tftp服务器,文件地址写为包含内核的文件地址,在板子上设置服务器ip
set serverip 192.168.1.119
这个ip一定要和tftp服务器上显示的ip一样,向板子输入命令等待传输
tftp 30000000 uImage
烧写完成了,启动内核
SMDK2410 # bootm 30000000
之后内核正常启动,但在启动过程中依然报了一些错,这些在之后解决