EDN首页   博客首页

日志档案

发表于 2007-3-26 17:39:06

0

标签: Redboot  bootloader  ecos  

Redboot安装历程

一 目标
公司购买了EV40 开发板 :CPU AT 91M 40800, 内存 2M + 2M ( 扩展 ), FLASH 2M + 4M ( 扩展 ), RTl8019AS 芯片 , FLASH 是 AM29LV160TE( 2M )
公司自己开发自用的板子 WX10: CPU AT 91M 40800, 内存 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 0x 020020a 1 @ 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 0x 020020a 1 // 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 ” , 查到了二个结果 , 我把二个驱动包都下载下来了 . 然后分别测试了一下 , 但都没有成功 . 我最后选择 dp 83902a 这种方式重点研究 .
首先下载其软件包 , 解压到相应的目录 . 然后增加了 CYGPKG_DEVS_ETH_RLTK_ISA8019AS 定义 .
由于 EB40 没有网卡驱动 , 因此只好自己增加配置 . 具体是 redboot_ROM.ecm 中增加 :
package -hardware CYGPKG_DEVS_ETH_RLTK_ISA8019AS current ;
package -hardware CYGPKG_DEVS_ETH_NS_DP 83902A current
package CYGPKG_IO_ETH_DRIVERS current ;
然后在文件 ecos/packages/devs/eth/rltk/isa8019as/current/include/devs_eth_rltk_isa8019as.inl 中修改网卡的起始地址和中断 :
static dp 83902a _priv_data_t dp 83902a _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,
};
然后编译 , 烧录 , 运行 . 但运行到网卡时就没有反应了 . 网卡能检测到 . 此时只好调试原代码 , 打开了 dp 83902a 驱动的开关 . 发现发送数据包时 , 就不动了 . 经过检查其代码 , 发现 mac 地址有二种方式 , 一种是从网卡 eprom 中取 , 另一种就是指定 , 于是我就把配置改成了指定 :
static dp 83902a _priv_data_t dp 83902a _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, 0x 0c , 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中也有一些我增加的调试语句 , 如果你要产品中使用 , 建议删除好了 .

作者:Samfei

系统分类: 嵌入式   |   用户分类: ARM专栏   |   来源: 转贴   |   【推荐给朋友】   |   【添加到收藏夹】

    阅读(862)    回复(0)  

投一票您将和博主都有获奖机会!