Samfei (samfei@163.com)
注: 本文第一次发布在 http://www.embedzone.com/bbs/dispbbs.asp?boardID=7&ID=266, 由于补丁问题,在此贴一下,.
简介: 本文是本人为工作需要而试验redboot的一个过程,我只是记录了试验的过程,希望能对别人使用redboot有些帮助. 本文没有系统性介绍redboot, 相关知识请参考其他资料.文章中具体修改的内容详细可以看附件patch.
一 目标
公司购买了EV40开发板:CPU AT91M40800, 内存2M+2M(扩展), FLASH 2M+4M(扩展), RTl8019AS芯片, FLASH是AM29LV160TE(2M)
公司自己开发自用的板子WX10: CPU AT91M40800, 内存4M, FLASH 8M, RTl8019AS芯片, FLASH是AM29LV641(8M)及其他应用功能芯片.
我主要的工作是开发系统的驱动软件,因此需要随时修改内核驱动,并调试,因此装入和启动的速度对工作效率是比较关键的.因为用hitool烧录方式启动 uclinux内核方式需要6~10分种一次.听”嵌入式linux群”kingmonkey说可以使用redboot, 因此决定试试.
二 环境建立
redboot是ecos操作系统的一部分,也是ecos操作系统最小配置的版本.因此要使用redboot,必须建立ecos操作系统环境. 到网站
http://sources.redhat.com/ecos/
查找其安装方法,按照说明采用了其网络方式安装,使用:
# wget --passive-ftp ftp://ecos.sourceware.org/pub/ecos/ecos-install.tcl
下载安装命令,并运行:
# sh ecos-install.tcl
安装了ecos 2.0.我把这个安装在/rh80/ecos下.ECOS_REPOSITORY就是/rh80/ecos/ecos-2.0.
运行 :
# cd /rh80/ecos
# . ecosenv.sh
设置环境变量.
由于linux操作系统中已经安装了
http://www.uclinux.org/pub/uClinux/m68k-elf-tools/arm-elf-tools-20030314.sh
因此我安装ecos时,没有选择安装arm-elf GNU tools工具.
三 编译redboot
由于ecos是个可配置的操作系统,因此下载安装的实际就是一个配置的仓库,要编译redboot就按照需要进行配置.配置的方式使用配置工具ecosconfig, 也有图形方式配置工具的,我没有用,只用字符界面的ecosconfig.
由于EV40类似EB40, 因此我的命令是:
# mkdir rom
# cd rom
# ecosconfig new eb40 redboot
#ecosconfig import /rh80/ecos/ecos-2.0/packages/hal/arm/at91/eb40/current/misc/redboot_ROMRAM.ecm
#ecosconfig tree
#make
结果编译出现错误.
因此怀疑编译器不兼容,于是重新安装ecos,此时选择arm-elf工具.此时运行. Ecosenv.sh 时,新下载的工具的路径包含在PATH中, 重新进行了redboot生成和编译,正确生成了install/bin/redboot.bin等文件.
将redboot.bin用hitool烧写到EV40的flash中,启动,没有任何反应.重新选择redboot的ROM版:
# ecosconfig new eb40 redboot
#ecosconfig import /rh80/ecos/ecos-2.0/packages/hal/arm/at91/eb40/current/misc/redboot_ROM.ecm
#ecosconfig tree
#make
编译,烧录,运行,仍然无反应.
四 配置硬件参数
由于EB40和EV40不完全相同,因此首先检查硬件参数的配置,找到配置的文件是: ecos/packages/hal/arm/at91/eb40/current/include/hal_platform_ints.h
主要是AT91_EBI配置参数表, EV40是:
_InitMemory:
.long 0x01002529 @ 0x01000000, 16MB, 2 cycles added after transfer, 16-bit, 6 wait states
.long 0x020020a1 @ 0x02000000, 16MB, 0x02002121 0 cycles added after transfer, 16-bit, 1 wait state
.long 0x03002529 @ unused
.long 0x40000000 @ unused
.long 0x02202021 @ unused ,CS 4
.long 0x02302021 @ unused ,CS 5
.long 0x60000000 @ unused
.long 0x70000000 @ unused
.long 0x00000001 @ REMAP commande
.long 0x00000006 @ 7 memory regions, standard read
.long AT91_EBI @ EBI address
.long 10f // address where to jump
WX10的配置是:
_InitMemory:
.long 0x01002529 // 0x01000000, 16MB, 2 cycles after transfer, 16-bit, 6 wait states
.long 0x020020a1 // 0x02000000, 16MB, 0 cycles after transfer, 16-bit, 1 wait state
.long 0x03002529 // unused
.long 0x30000000 // unused
.long 0x40000000 // unused
.long 0x50000000 // unused
.long 0x60000000 // unused
.long 0x70000000 // unused
.long 0x00000001 // REMAP command
.long 0x00000000 // 7 memory regions, standard read
.long AT91_EBI // External Bus Interface address
.long 10f // address where to jump
这里我要说明的一点是EV40和WX10的区别, EV40是用到CS6的,而WX10是不用CS6的, EV40有扩展内存,由CS4和CS5配置. EV40网卡地址是0x40010000, 而WX10的网卡地址是0x03210000.
修改了配置后, 编译,烧录,运行,仍然无反应.
向kingmonkey讨叫,kingmonkey认为可能是ecos版本不是最新的缘故,建议用cvs下载最新的版本. 用ecos-install.tcl是最新的稳定版,但不是最新的.
五 安装cvs版ecos
安装方法参考网站中Anonymous CVS:
# cd /rh80/ecos
# cvs -d
server:anoncvs@ecos.sourceware.org:/cvs/ecos login口令任意
# cvs -z3 -d
server:anoncvs@ecos.sourceware.org:/cvs/ecos co -P ecos这样呢就下载的最新的ecos,目录是/rh80/ecos/ecos, 修改ecosenv.sh中
ECOS_REPOSITORY=/rh80/ecos/ecos/packages ; export ECOS_REPOSITORY
这样呢,就使用最新用cvs下载的ecos了.原来的ecos-2.0仍然保留,并使用其下面的ecosconfig等工具,不用重新去下载ecosconfig工具了.
六 重新编译redboot
安装第三节的方法重新编译redboot,但仍然无法工作.因此只好去看资料和代码.并且下载了网站上预编译好的reboot.bin来试,仍然没有任何反应.
仔细阅读了ecos参考手册:
http://ecos.sourceware.org/docs-latest/ref/ecos-ref.html
中关于Installation and Testing部分中ARM/ARM7 Atmel AT91 Evaluation Boards (EBXX)的资料,它运行redboot的方式是通过angel和arm-elf-gdb的方式的,因此我就想先按照其方式试一下.
把angel烧录到EV40板上,然后编译出redboot的RAM板(上面命令中redboot_ROM.ecm改成 redboot_RAM.ecm就是).然后安装手册,成功启动了redboot! 结合前面看了redboot的一些代码,怀疑缺省的EV40配置是只能在angel方式下启动的.
七 修改redboot配置
经过阅读其文件, 发现编译命令文件install/lib/target.ld中:
__reserved_bootmon = 0x01000000; . = __reserved_bootmon + 0x10000;
将运行开始位置后移了一个0x10000, 这个可能是造成不能直接flash启动的原因.经过检查,修改了多处跟这个有关的地方:
1. ecos/packages/hal/arm/at91/eb40/current/include/hal_platform_ints.h中0x1010000 à 0x100000
2. ecos/packages/hal/arm/at91/eb40/current/include/pkgconf/mlt_arm_at91_eb40_rom.h中
#define CYGMEM_SECTION_reserved_bootmon_SIZE (0x10000) 改成
#define CYGMEM_SECTION_reserved_bootmon_SIZE (0x00000)
3. ecos/packages/hal/arm/at91/eb40/current/include/pkgconf/mlt_arm_at91_eb40_rom.ldi中
CYG_LABEL_DEFN(__reserved_bootmon) = 0x01000000; . = CYG_LABEL_DEFN(__reserved_bootmon) + 0x10000;
改成:
CYG_LABEL_DEFN(__reserved_bootmon) = 0x01000000; . = CYG_LABEL_DEFN(__reserved_bootmon) + 0x00000;
[mlt_arm_at91_eb40_rom.ldi就是生成rom版redboot中target.ld的依据.]
然后重新配置redboot和编译,运行,烧录到EV40,正常启动了redboot. ^_^
[此时出现一个非常讨厌的问题,就是EV40板子一运行redboot,蜂鸣器不停的叫.我没有去检查为什么这样!后来只好在自己公司的板子上试了.]
八 配置flash
由于EB40采用的flash芯片和EV40采用的芯片是不一样的,因此很正常的结果是我们第七节编译处理的redboot是不能正确识别EV40的flash芯片.因此就必须考虑修改flash驱动.
此时本人对如何修改还不是太清楚,因此只要乖乖地去看ecos的资料.正好同事买了一本ecos的书,这样就省了看英文资料的麻烦.
从资料上,可以知道修改配置,主要是修改cdl文件. 跟EB40有关的flash包是:
Package CYGPKG_DEVS_FLASH_EB40 (FLASH memory support for Atmel AT91/EB40):
Package CYGPKG_DEVS_FLASH_ATMEL_AT29CXXXX (Support for Atmel AT29Cxxxx flash memory):
我就把CYGPKG_DEVS_FLASH_EB40包中采用的ATMEL芯片的包改成:
CYGPKG_DEVS_FLASH_AMD_AM29XXXXX
具体修改的文件是ecos/packages/devs/flash/arm/eb40/current/cdl/flash_eb40.cdl:
修改 requires CYGPKG_DEVS_FLASH_ATMEL_AT29CXXXX 为
requires CYGPKG_DEVS_FLASH_AMD_AM29XXXXX
修改 cdl_interface CYGINT_DEVS_FLASH_ATMEL_AT29CXXXX_REQUIRED {
display "Generic Atmel AT29CXXXX driver required"
为 cdl_interface CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED {
display "Generic Amd AM29XXXXX driver required"
修改 implements CYGINT_DEVS_FLASH_ATMEL_AT29CXXXX_REQUIRED
为 implements CYGINT_DEVS_FLASH_AMD_AM29XXXXX_REQUIRED
增加 requires CYGHWR_DEVS_FLASH_AMD_AM29LV160.
这里特别是要说明的是最后这一行, 因为CYGPKG_DEVS_FLASH_AMD_AM29XXXXX支持多种芯片,在配置的时候,需要指定哪些芯片可以识别,刚开始的时候ecoscofing tree和编译后,就是没有看到驱动程序包含进去,弄了半天才搞明白,如果一种芯片也没有选,则驱动程序就不包含进去.因此需要加入至少一种芯片的选择,最后一行就是选择AM29LV160的芯片.
同时修改 ecos/packages/ecos.db 的target eb40中:
修改 CYGPKG_DEVS_FLASH_ATMEL_AT29CXXXX
为 CYGPKG_DEVS_FLASH_AMD_AM29XXXXX
再修改ecos/packages/devs/flash/arm/eb40/current/src/eb40_flash.c:
增加 #define CYGNUM_FLASH_WIDTH 16
修改 #include "cyg/io/flash_at29cxxxx.inl"
为 #include "cyg/io/flash_am29xxxxx.inl"
此时,由于EV40板子乱叫的原因,我是用我们自己的板子WX10来调试了,而WX10采用的flash是AM29LV641,与AM29LV160是有区别的,因此我打开了flash调试,自己增加了一些调试语句,运行后,然后增加了AM29LV641的驱动,具体文件是 ecos/packages/devs/flash/amd/am29xxxxx/current/include/flash_am29xxxxx_parts.inl, 增加了AM29LV641配置:
+ { // MBM29LV641
+ device_id : FLASHWORD(0x22d7),
+ block_size : 0x10000 * CYGNUM_FLASH_INTERLEAVE,
+ block_count: 32,
+ device_size: 0x200000 * CYGNUM_FLASH_INTERLEAVE,
+ base_mask : ~(0x200000 * CYGNUM_FLASH_INTERLEAVE - 1),
+ bootblock : true,
+ bootblocks : { 0x000000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x004000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x002000 * CYGNUM_FLASH_INTERLEAVE,
+ 0x008000 * CYGNUM_FLASH_INTERLEAVE,
+ _LAST_BOOTBLOCK
+ },
+ banked : false,
+ bufsiz : 1
+ },
具体还是放在CYGHWR_DEVS_FLASH_AMD_AM29LV160下,这样上面的cdl不用修改.[上面的修改中我没有修改flash的容量,因为AM29LV641是8M的,我还弄清楚如何改!我就先把它当成2M使用.]
经过上面的修改,重新编译运行后,redboot能够正确识别了flash的. ^_^
九 网卡驱动
google了”ecos 8019as driver”,查到了二个结果,我把二个驱动包都下载下来了.然后分别测试了一下,但都没有成功. 我最后选择dp83902a这种方式重点研究.
首先下载其软件包,解压到相应的目录. 然后增加了CYGPKG_DEVS_ETH_RLTK_ISA8019AS 定义.
由于EB40没有网卡驱动,因此只好自己增加配置.具体是redboot_ROM.ecm中增加:
package -hardware CYGPKG_DEVS_ETH_RLTK_ISA8019AS current ;
package -hardware CYGPKG_DEVS_ETH_NS_DP83902A current
package CYGPKG_IO_ETH_DRIVERS current ;
然后在文件ecos/packages/devs/eth/rltk/isa8019as/current/include/devs_eth_rltk_isa8019as.inl中修改网卡的起始地址和中断:
static dp83902a_priv_data_t dp83902a_eth0_priv_data = {
base: (cyg_uint8*) 0x03210000,
interrupt: 17,
tx_buf1: 0x40,
tx_buf2: 0x48,
rx_buf_start: 0x50,
rx_buf_end: 0x80,
hardwired_esa: false,
};
然后编译,烧录,运行.但运行到网卡时就没有反应了.网卡能检测到. 此时只好调试原代码,打开了dp83902a驱动的开关.发现发送数据包时,就不动了.经过检查其代码,发现mac地址有二种方式,一种是从网卡eprom中取,另一种就是指定,于是我就把配置改成了指定:
static dp83902a_priv_data_t dp83902a_eth0_priv_data = {
base: (cyg_uint8*) 0x03210000,
interrupt: 17,
tx_buf1: 0x40,
tx_buf2: 0x48,
rx_buf_start: 0x50,
rx_buf_end: 0x80,
hardwired_esa: true,
esa: {0x00, 0x05, 0x0c, 0x04, 0x05, 0x06},
};
但效果仍然一样. 通过多次调试和分析, 想起了寄存器偏移量的问题. 我在EV40板子上用uclinux驱动网卡时也是同样的问题,后来把 所有寄存器的偏移量*2就可以了.于是动手将全部寄存器偏移量*2.这样呢, 网卡驱动就可以了, 并能发送和接收数据包了.【这个呢,我自己也不太明白,是不是跟硬件的设置有关?】
但redboot启动时, 经过很长时间才到redboot提示符出来.原来是redboot启动时,自动通过bootp去取的IP地址,由于没有bootp服务器,因此要等待一段时间才出现超时, 让我误以为死机了.
建立好bootp服务器, redboot就正常启动,并且配置了ip地址. 然后ping也通了.
此时大功告成.!!!
十 启动uclinux
uclinux编译时必须注意的是: 由于 redboot运行时,必须要是使用部分内存,你可以用version命令看出使用了什么内存, 因此uclinux的入口地址就不能是0x2000000, 我选择了0x2010000, 前面留了64K.
将linux.elf拷贝到bootp和tftp服务器的/tftpboot下. 运行:
> load –m tftp linux.elf
> go 0x2010000
注意: 由于redboot串口使用38400波特率,而uclinux采用9600波特率,因此uclinux启动后出现乱码,没有关系,把波特率改成9600, 然后重新连接终端就可以了.
附: 修改的patch. Patch是针对WX10板子的. 由于我修改的ecos是cvs版本,每次checkout的不一定一样.因此patch就不一定能够直接使用, 另外呢,我的patch中也有一些我增加的调试语句,如果你要产品中使用,建议删除好了.