移植uboot第七步:支持DM9000

写在前面:

我的博客已迁移至自建服务器:博客传送门,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根据硬件接线,如果写入的地址在0x200000000x30000000,它会被选中,所以其中CONFIG_DM9000_BASE值改为0x20000000DM9000_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地址copylunix虚拟机的macmac不能自己随便写,它有自己的格式。

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

之后内核正常启动,但在启动过程中依然报了一些错,这些在之后解决

你可能感兴趣的:(boot相关)