300字范文,内容丰富有趣,生活中的好帮手!
300字范文 > jz2440开发板移植U-boot之修改代码支持DM9000网卡

jz2440开发板移植U-boot之修改代码支持DM9000网卡

时间:2022-11-28 00:38:07

相关推荐

jz2440开发板移植U-boot之修改代码支持DM9000网卡

今天我们来移植U-boot到jz2440开发板,修改代码支持DM9000网卡。查看之前写的移植记录请点击链接:点击查看之前的移植记录

现在大多数开发板都支持DM9000网卡。我们的U-boot源码里面也是有DM9000网卡的驱动程序的。文件为Dm9000x.c(drivers\net).

首先我去网卡目录的Makefile文件中搜索dm9000字符串:

由Makefile得知,如果我们定义了CONFIG_DRIVER_DM9000这个宏,那么dm9000网卡就会被编译进去(同时要去掉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 */

这是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

重新编译uboot(肯定会显示有错误,不可能这么简单就弄好了,但是我们一步解决一个错误):

显示错误:

dm9000x.c:156: error: 'DM9000_DATA' undeclared (first use in this function)dm9000x.c:156: error: (Each undeclared identifier is reported only oncedm9000x.c:156: error: for each function it appears in.)。。。。。。。。

显示说dm9000x.c中的56行没有定义DM9000_DATA这个宏参数。在经验不足,对驱动程序了解不多的情况下,我们没有办法知道这个宏参数是干什么的,但是我们可以仿照uboot中现有的程序中相同的地方模仿。我们在uboot源码中搜索DM9000_DATA这个字符串:

输入:grep “DM9000_DATA” * -nR (这是Linux下搜索字符串的命令)

显示很多配置文件中用到了DM9000_DATA这个参数,我们随便找一个配置文件进去看看别人是怎么配置的,假如找的是这个吧:

include/configs/at91sam9261ek.h:159:#define DM9000_DATA (CONFIG_DM9000_BASE + 4)

好,进去看了之后,别的是这么配置DM9000的网卡参数的:

#define CONFIG_DRIVER_DM9000#define CONFIG_DM9000_BASE 0x04014000#define DM9000_IO CONFIG_DM9000_BASE#define DM9000_DATA (CONFIG_DM9000_BASE + 2)

原来是我们少定义了一些参数。那么我们来看看如何取值CONFIG_DM9000_BASE 与DM9000_DATA。

在分析之前先说一下:

DM9000属于内存类接口,想要操作内存类接口,需要知道它的1)访问地址,同时还要根据DM9000的实际情况2)设置内存控制器的时序以及位宽。

1)设置访问地址:

首先是 CONFIG_DM9000_BASE ,这个是DM9000的基地址,是CPU用来识别网卡的一个基地址。 查看DM9000网卡原理图:它的片选引脚是:nGCS4,那么我们查看2440手册,因为网卡是内存类的接口,所以我们看2440手册内存控制器那一章,找到片选信号的地址分配表:

从中可以看出:nGCS4这个片选引脚对应的初始地址是:0x20000000。那么我们就把CONFIG_DM9000_BASE这个值设为0x20000000,就会把nGCS4引脚设为低电平,从而片选到DM9000网卡设备。

然后是 DM9000_DATA的地址取值。查看原理图知,cpu只发出了LADDR2给DM9000网卡内的CMD引脚, 说明CPU只关心访问地址的第2位,所以我们把基地址加4,设置一下第二位的值:#define DM9000_DATA (CONFIG_DM9000_BASE + 4)

那么总的修改是:

#define CONFIG_DRIVER_DM9000#define CONFIG_DM9000_BASE 0x20000000#define DM9000_IO CONFIG_DM9000_BASE#define DM9000_DATA (CONFIG_DM9000_BASE + 4)

那么我们已经设置好了上面说的第一步,设置访问地址,下面再看如何设置内存控制器的时序以及位宽。

2)设置内存控制器的时序以及位宽:

uboot中lowlevel_init.S中有设置内存控制器寄存器的相关的代码:

SMRDATA:.long 0x2110//BWSCON.long 0x00000700//BANKCON0.long 0x00000700//BANKCON1.long 0x00000700//BANKCON2.long 0x00000700//BANKCON3 .long 0x00000700//BANKCON4.long 0x00000700//BANKCON5.long 0x00018005//BANKCON6.long 0x00018005//BANKCON7.long 0x008C04F4// REFRESH.long 0x000000B1//BANKSIZE.long 0x00000030//MRSRB6.long 0x00000030//MRSRB7

.long 0x2110 //BWSCON这个寄存器应该是设置的位宽,.long 0x00000700 //BANKCON4(nGCS4)这个应该是设置时序的寄存器

1)首先我们在2440手册中搜索BWSCON这个寄存器。在207页有设置位宽的寄存器位操作(其中19:18:17:16位对应的是BANK4,所以查看是否需要设置这四位):

DW4是设置位宽的的位,对应17:16位。我们计算.long 0x2110 //BWSCON这个寄存器的值,用寄存器位查看器知:

17:16位对应的是01.那么查看手册知01 = 16-bit。查看原理图得知,DM9000网卡的位宽刚好是16位,所以,不需要修改了。18位的等待信号DM9000上没有,不需要设置。19位的也没有用到,不需要设置。

2)再看如何设置时序(设置BANKCON4寄存器)。找到如下图:

这里面就是设置DM9000的时序了,至于怎么设置(为什么这么设置),可以参考韦东山第二期视频移植DM9000网卡驱动程序那一节里面有详细讲过,这里不再讲解。

看看原始设置的各个位是对少:

对比之前韦东山二期视频讲解的DM9000时序设置,我们在这里将位7:6设置为01。则对应的寄存器的值为:

所以将BANKCON4的值改为0x00000740。

然后重新编译:

编译顺利通过。

将生成的镜像文件烧写到NOR FLASH,启动:

看到,显示Net: No ethernet found。那么我们去源码中搜索看是哪个地方。

源码中搜索:Net:

Board.c中:

#if defined(CONFIG_CMD_NET)puts("Net: ");eth_initialize(gd->bd);

跳到:eth_initialize:

里面有一个函数board_eth_init:

我们找board_eth_init 函数(smdk2410.c,这个名字一直没有改成2440的,忘记了,暂时这么用吧,不影响):

int board_eth_init(bd_t *bis){int rc = 0;#ifdef CONFIG_CS8900rc = cs8900_initialize(0, CONFIG_CS8900_BASE);#endifreturn rc;}

发现没有初始化我们的DM9000网卡。我们在DM9000网卡驱动程序中找到:dm9000_initialize。应该是DM9000的初始化函数。我们在linux下搜索这个dm9000_initialize:grep “dm9000_initialize” * -nR,看看有没有类似的初始化。发现大多是这样的:

return dm9000_initialize(bis);

那么我们将上面的board_eth_init函数改成:

int board_eth_init(bd_t *bis){int rc = 0;#ifdef CONFIG_CS8900rc = cs8900_initialize(0, CONFIG_CS8900_BASE);#endif#ifdef CONFIG_DRIVER_DM9000rc = dm9000_initialize(bis);#endifreturn rc;}

重新编译,启动:

OK啦,我们的网卡终于加好了。

现在ping一下电脑看看:

先设置ip:

set ipaddr 10.11.235.102

ping 10.11.235.146

显示

*** ERROR: `ethaddr' not set

没有设置mac地址,重启设置:

set ipaddr 192.168.1.102

set ethaddr 00:0c:29:4d:e4:f4 (可以随便设置)

ping 192.168.1.102

显示如下:

OK!显示主机alive。已经ping通了。下面我们试一下看看能不能用tftp下载。因为uboot没有集成TFTP工具,那么我们就用windows上的tftp工具进行下载内核。

如图为TFTP下载工具(注意服务器ip)

在板子上uboot上设置:

set serverip 192.168.1.102

tftp 30000000 uImage_4.3

然后启动内核:

bootm 30000000

成功启动内核。说明我们已经成功了!!!现在下载比用dnw下载要方便快捷的多。

想一起探讨以及获得各种学习资源加我(有我博客中写的代码的原稿):

qq:1126137994

微信:liu1126137994

可以共同交流关于嵌入式,操作系统,C++语言,C语言,数据结构等技术问题

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。