七、移植u-boot-2016.03到Jz2440之修改代码支持DM9000网卡

7. 移植u-boot-2016.03修改代码支持DM9000网卡

从前面uboot的打印信息可知, 网卡打印的是CS8900,然后Jz2440开发板的网卡是DM9000网卡,u-boot-2016.03也带有DM9000网卡的驱动程序,我们需要把移植过来支持JZ2440开发板。
在这里插入图片描述

7.1 网卡初始化过程分析

通过之前uboot启动过程的分析,我们知道网卡的初始化在uboot初始化的第二阶段,通过board_init_r函数调用init_sequence_r函数指针数组里的initr_net进行网卡的初始化,initr_net的函数代码如下:

static int initr_net(void)
{
    
    
	puts("Net:   ");
	eth_initialize();
#if defined(CONFIG_RESET_PHY_R)   /*CONFIG_RESET_PHY_R未定义*/
	debug("Reset Ethernet PHY\n");
	reset_phy();
#endif
	return 0;
}

接着跳转到eth_initialize函数,代码如下:(在net/eth_legacy.c)

int eth_initialize(void)
{
    
    
	int num_devices = 0;

	eth_devices = NULL;
	eth_current = NULL;
	eth_common_init();
	/*
	 * If board-specific initialization exists, call it.
	 * If not, call a CPU-specific one
	 */
	if (board_eth_init != __def_eth_init) {
    
    
		if (board_eth_init(gd->bd) < 0)
			printf("Board Net Initialization Failed\n");
	} else if (cpu_eth_init != __def_eth_init) {
    
    
		if (cpu_eth_init(gd->bd) < 0)
			printf("CPU Net Initialization Failed\n");
	} else {
    
    
		printf("Net Initialization Skipped\n");
	}

	if (!eth_devices) {
    
    
		puts("No ethernet found.\n");
		bootstage_error(BOOTSTAGE_ID_NET_ETH_START);
	} else {
    
    
		struct eth_device *dev = eth_devices;
		char *ethprime = getenv("ethprime");

		bootstage_mark(BOOTSTAGE_ID_NET_ETH_INIT);
		do {
    
    
			if (dev->index)
				puts(", ");

			printf("%s", dev->name);

			if (ethprime && strcmp(dev->name, ethprime) == 0) {
    
    
				eth_current = dev;
				puts(" [PRIME]");
			}

			if (strchr(dev->name, ' '))
				puts("\nWarning: eth device name has a space!"
					"\n");

			eth_write_hwaddr(dev, "eth", dev->index);

			dev = dev->next;
			num_devices++;
		} while (dev != eth_devices);

		eth_current_changed();
		putc('\n');
	}

	return num_devices;
}

从上面的代码中,我们看到了board_eth_init函数,继续跳转,它的代码如下:(在board/samsung/jz2440/jz2440.c)

int board_eth_init(bd_t *bis)
{
    
    
	int rc = 0;
#ifdef CONFIG_CS8900
	rc = cs8900_initialize(0, CONFIG_CS8900_BASE);
#endif
	return rc;
}

从上面代码可知,board_eth_init函数只调用了cs8900_initialize函数。

7.2 修改代码支持DM9000网卡

(1) 在uboot顶层目录下搜索dm9000相关的文件,输入命令:find -name "dm9000*",搜索结果如下;可知dm9000网卡的驱动程序dm9000x.cdrivers/net/ 下。
在这里插入图片描述
(2) 去drivers/net/目录下的Makefile搜索dm9000字符串,搜索结果如下:
在这里插入图片描述
从图中可知,定义了CONFIG_DRIVER_DM9000,dm9000x.c才会被编译进uboot里(同时去掉CONFIG_CS8900)
(3) 去到uboot的配置文件jz2440.h,找到下面的宏定义:

/*
 * Hardware drivers
 */
#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 */

这是cs8900网卡的定义,把它去掉,加上dm9000所需要的宏:

#ifdef 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

(4) 修改board_eth_init函数为如下:

int board_eth_init(bd_t *bis)
{
    
    
	int rc = 0;
#ifdef CONFIG_CS8900
	rc = cs8900_initialize(0, CONFIG_CS8900_BASE);
#endif
#ifdef CONFIG_DRIVER_DM9000
	rc = dm9000_initialize(bis);
#endif
	return rc;
}

(5) 从前面的u-boot-2012.04.01移植笔记的第十节DM9000网卡移植科知道以下信息:① DM9000网卡的片选引脚是nGCS4,该管脚对应的基地址是0x20000000,即DM9000网卡的基地址是0x20000000;② DM9000网卡内的CMD引脚接LADDR2,也就是说当向0x20000000地址上读写数据时,此时CMD为低,则读写的便是DM9000C的地址;向0x20000000+4地址上读写数据时,此时CMD为高,则读写的便是DM9000C的数据。所以,关于DM9000网卡总体的配置如下:

#ifdef 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

(5) 修改BANK4控制寄存器:因为DM9000网卡的片选引脚是nGCS4,它对应的内存空间是Bank4,BANKCON4寄存器要设置正确,需要确保BANKCON4寄存器设置为0x00000740如下图所示,否则,有可能会在数据传是出错。
在这里插入图片描述

7.3 测试

(1) 重新编译uboot,把uboot烧写到开发板,重新启动,串口打印信息如下:
在这里插入图片描述
由上图可知,串口已经打印出dm9000网卡。

(2) 设置MAC地址、IP地址、ping测试

set ethaddr 00:0c:29:4d:e4:f4  //MAC可以随便设置
set ipaddr 192.168.0.200
ping 192.168.0.106

ping的打印结果如下:(注:ping一次可能不成功,需要多ping几次)
在这里插入图片描述
上图显示:host 192.168.0.103 is alive,说明已经ping成功。

(3) 下面我们试一下看看能不能用tftp下载。因为uboot没有集成TFTP工具,那么我们就用windows上的tftp工具进行下载内核:
在这里插入图片描述
由上图可知服务器的IP地址是:192.168.0.104
所以需要在开发板设置服务器IP地址:

set serverip 192.168.0.104

然后使用fttp命令从window下载内核:

tftp 30000000 uImage_4.3

在这里插入图片描述
启动内核:

bootm 30000000

打印信息如下,从图中可知,可以启动内核,同时也说明uboot支持了DM9000网卡。
在这里插入图片描述

猜你喜欢

转载自blog.csdn.net/qq_35031421/article/details/104468734
今日推荐