Redboot安装历程(转自:http://www.linuxforum.net) Samfei ([email protected]) 注: 本文第一次发布在 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:[email protected]:/cvs/ecos login 口令任意 # cvs -z3 -d server:[email protected]:/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中也有一些我增加的调试语句,如果你要产品中使用,建议删除好了. |