转载:http://blog.sina.com.cn/s/blog_640029b30100ubzg.html
转自 http://nervfzb.blog.163.com/blog/static/31481399201152810503015/
网络功能是UBOOT重要的功能之一,实现了网络功能之后UBOOT可以很方便的下载内核到板子上。毕竟通过JTAG来烧录实在是一种煎熬。
TQ2440上使用的网络芯片为DM9000,SMDK2410上使用的是CS8900。由于此次UBOOT移植借用的是SMDK2410的工程文件,所以自然要对这部分进行修改。
在UBOOT中,集成了一些设备的驱动代码。这些代码一般都分类存放于drivers/目录下面,而网络设备驱动存于drivers/net目录下面。可以看到UBOOT有dm9000x.c和dm9000x.h两个文件存在。说明UBOOT已经集成了DM9000的驱动程序,现在就来将这个驱动集成到UBOOT中。
其实多移植几次就会发现,UBOOT的移植修改还是遵循着一定的规律。即是先在配置头文件中打开相关宏定义支持,在到板级初始化(一般是第二阶段初始化过程)代码中添加需要支持功能的初始化函数。对于学习板子来说,很多芯片在UBOOT中都找得到驱动。所以省去了很多事,如同本次的网络功能调试支持一样。
修改配置头文件(include/configs/fzb2440.h)
026
029 #define CONFIG_NET_MULTI
030
031 //#define CONFIG_CS8900
032 //#define CONFIG_CS8900_BASE 0x19000300
033 //#define CONFIG_CS8900_BUS16
034
035 #define CONFIG_DRIVER_DM9000
036 #define CONFIG_DM9000_BASE 0x20000300
037 #define DM9000_IO CONFIG_DM9000_BASE
038 #define DM9000_DATA (CONFIG_DM9000_BASE + 4)
039 #define CONFIG_DM9000_NO_SROM 1
…………………………
085 #define CONFIG_ETHADDR 08:00:3e:26:0a:5b
086 #define CONFIG_NETMASK 255.255.255.0
087 #define CONFIG_IPADDR 192.168.0.110
088 #define CONFIG_SERVERIP 192.168.0.1
修改板级初始化函数,添加对DM9000初始化的支持(board\samsung\fzb2440\fzb2440.c)
01 #ifdef CONFIG_CMD_NET
02 int board_eth_init(bd_t *bis)
03 {
04 int rc = 0;
05 #ifdef CONFIG_CS8900
06 rc = cs8900_initialize(0, CONFIG_CS8900_BASE);
07 #endif
08 #ifdef CONFIG_DRIVER_DM9000
09 rc = dm9000_initialize(gd->bd);
10 #endif
11 return rc;
12 }
13 #endif
重新编译过后烧录到TQ2440中,如果网络设备初始化正常的话会打印出下列信息
UBOOT的网络结构分析
支持调试还算是简单,但是掌握相关流程更加重要。在以后碰到其他板子或者新芯片的时候也可以模仿成熟的构架添加相关的支持。
配置头文件修改说明
启动网络功能的时候首先需要定义宏CONFIG_NET_MULTI,这个宏就如同一个总开关一样。其他的宏往往都和具体芯片有关,要如何定义也应该是各个驱动作者来定义。所以上面DM9000的相关宏定义都是参考其他使用该芯片的板子和对驱动文件本身的理解而成型的。毕竟是开源工程,相关文档确实不是很完善。
DM9000的驱动中,宏CONFIG_DRIVER_DM9000是启动该驱动代码的总开关。然后我们需要自己去指定芯片所在的基地址TQ2440的基地址是0x20000300,这个也就是DM9000的IO口的基地址,数据接口的基地址是IO口的基地址加4得到。前者用于一些设置之类的,后者就是数据传输。当然还会有中断之类的概念,不过UBOOT这里没有用到就不需要了。最后关于CONFIG_DM9000_NO_SROM这个宏是用于DM9000芯片没有接EEPROM的时候所需要的一个宏。一般一个网卡都会有MAC地址之类的信息,而这些信息都是存储到一个和网络芯片连接的EEPROM中,但是TQ2440上没有这样设计,所以这些信息就只有编译到UBOOT让UBOOT在运行的时候指定。这个宏打开过后,一些从EEPROM芯片获取MAC信息的操作就不会被编译到UBOOT中了。
最后需要注意一个宏CONFIG_CMD_NET这个宏默认在config_cmd_default.h文件中已经得到了定义。不要再配置头文件中重复了。
驱动运行过程的总结
UBOOT中网络设备的初始化一般是在第二阶段初始化代码中执行。
01 #if defined(CONFIG_CMD_NET)
02 #if defined(CONFIG_NET_MULTI)
03 puts ("Net: ");
04 #endif
05 eth_initialize(gd->bd);
06 #if defined(CONFIG_RESET_PHY_R)
07 debug ("Reset Ethernet PHY\n");
08 reset_phy();
09 #endif
10 #endif
eth_initialize()函数就是网络设备初始化入口函数,在net/eth.c中实现。这个函数是通用函数,但是有两个版本,新版本的函数需预先定义宏CONFIG_NET_MULTI(这就是为何说这个宏是总开关的原因)。这里就着重分析新版本的eth_initialize()函数,在这个函数中不同芯片的初始化流程要利用其内部提供的默认回调函数(一般来说是board_eth_init()函数)在其他地方实现。
这个函数的一个运行流程图(着重展示本次一种网络芯片初始化过程,忽略未用到代码)
这个流程图显得很简单,其实大部分功能都是驱动中实现的(在board_eth_init()函数中调用dm9000_initialize()函数),这里不过是通用的流程罢了。
开启了UBOOT的网络功能后,我们就可以使用命令通过网络将要烧写的文件下载到内存中,提高了调试和烧写的速率,不必再忍受并口烧写程序的煎熬了:
速度大概在1MB/S左右(用的集线器最大带宽1MB)比用JTAG快多了。
到这里,UBOOT的网络功能算是基本调试完成。不过也可以看到UBOOT虽然有很丰富的代码资源,但是相关的文档并不丰富(很多功能没有完整的解释,一些宏定义往往只与一块芯片关联,但是却没有说明文档,基本都是只给出了一些只言片语的注释)。在