分类: LINUX
2005-09-21 10:48:59
在基于ARCA方舟GT2000 CPU系统上做嵌入式linux开发过程中遇到大内核时的启动问题解决
顺便修改了bootloader "redboot",这些都是平台移植的问题
主要描述其解决过程。
# 大系统映象的支持和改造
#
# 系统硬件平台
# ARCA gt2000/ 16M flash/ 128M DIMM SDRAM
#
# 20050823 由 LG 完成
一 原来的问题
整体系统包括两个部分
1. redboot, 属于Ecos(V2.0)的一部分
2. linux kernel + rootfs 映象 (.gz)
每次对内核编译会产生三个有用的东东,
kersrc/vmlinux 他是一个未经压缩的ELF文件, 可以通过tftp load启动, loader 地址为 RAM_BASE + 0x00100000, 由 kersrc/arch/xxx/vmlinux.lds决定
kersrc/arch/xxx/boot/compress/vmlinux 一个经过压缩的ELF文件, 可以通过tftp load启动, loader 地址为 RAM_BASE + 0x00500000, 由 kersrc/arch/xxx/boot/compress/Makefile 决定
kersrc/arch/xxx/boot/zImage 是一个从 kersrc/arch/xxx/boot/compress/vmlinux OBJCOPY的来得BIN文件, 用于写入flash
当 kernel + rootfs (kersrc/vmlinux) 小于 5M 时, tftp load 和 fis load 均无问题,
但是在 大于 5M 时
kersrc/vmlinux load -m tftp 可以正常启动
kersrc/arch/xxx/boot/compress/vmlinux load -m tftp 毫无反应
主要显示信息如下:
Redboot infomation (大于 5M)
RAM: 0x90000000 - 0x91000000, 0x90015208 - 0x90fdd000 available
FLASH: 0x80000000 - 0x81000000, 128 blocks of 0x00020000 bytes each.
... ...
RedBoot> load -m tftp -h 192.168.18.168 embker
RedBoot> exec -c "mem=128M console=ttyUART1,115200 ip=192.168.18.152:::::eth0 nfsroot=192.168.18.168:/ARCA/nfsroot rw"
Now booting linux kernel:
Entry : 0x90500000 (对于 kersrc/vmlinux 显示 0x90100000)
Cmdline : mem=128M console=ttyUART1,115200 ip=192.168.18.152:::::eth0 nfsroot=192.168.18.168:/ARCA/nfsroot rw
好了, 到此为止, 再无下文.
二 问题分析和解决
根据linux的启动机制, 对于压缩内核要将其先解压到低地址空间, 对于0x90500000预留的<5M空间就不够用了, 所以计划将其改为8M即0x90800000.
对于这个地址是linux必须确定知道的压缩内核loader地址, 存放在 kersrc/arch/xxx/boot/compress/Makefile 中
找到并改为0x90800000, 实际如下
原: ZIMAGE_OFFSET = $(shell printf "0x%8x" $$[0x80000000+0x$(CONFIG_MEMORY_START)+0x0500000])
改: ZIMAGE_OFFSET = $(shell printf "0x%8x" $$[0x80000000+0x$(CONFIG_MEMORY_START)+0x0800000])
至此, kersrc/arch/xxx/boot/compress/vmlinux 可以通过 load -m tftp 启动
三 问题再现
将 kersrc/arch/xxx/boot/zImage 写入flash后, 通过 fis load 启动
主要显示信息如下:
Redboot infomation (大于 5M)
RAM: 0x90000000 - 0x91000000, 0x90015208 - 0x90fdd000 available
FLASH: 0x80000000 - 0x81000000, 128 blocks of 0x00020000 bytes each.
... ...
RedBoot> fis load "kernel" -b 0x90800000
Not a loadable image
RedBoot> exec -c "mem=128M console=ttyUART1,115200" 0x90800000
Now booting linux kernel:
Entry : 0x90800000
Cmdline : mem=128M console=ttyUART1,115200
好了, 到此为止, 再无下文.
四 继续解决
首先怀疑是BIN文件有问题, 但是相应的ELF文件正常, 排除此可能 (纯数经验, 并不可信).
又发现 Redboot 的 RAM 信息一直不正常, 在 fis create 时也有提示, 应该是Redboot的问题吧!
查看源码并进行修改:
有关的信息出自
Ecos_SRC/packages/redboot/v2_0/src/main.c 中
diag_printf("RAM: %p-%p, %p-%p available ",
(void*)ram_start, (void*)ram_end,
(void*)user_ram_start, (void *)user_ram_end);
Ecos_SRC/packages/redboot/v2_0/src/flash.c 中
// Load image from FLASH into RAM
if ((mem_addr < (CYG_ADDRESS)user_ram_start) ||
((mem_addr+img->data_length) >= (CYG_ADDRESS)user_ram_end)) {
diag_printf("Not a loadable image ");
return;
与其相关的定义来自
Ecos_SRC/packages/hal/arca/gt2000/bootes/current/include/pkgconf/mlt_arca_ram.h 中 和
Ecos_SRC/packages/hal/arca/gt2000/bootes/current/include/pkgconf/mlt_arca_rom.h 中
#define CYGMEM_REGION_ram_SIZE (0x1000000) 竟然写死了!!!, 那在HCI中的信息还有用么?
改为
#define CYGMEM_REGION_ram_SIZE (0x8000000) 控制了 ram_end
#define CYGMEM_SECTION_heap1_SIZE (0x91000000 - (size_t)CYG_LABEL_NAME(__heap1)) 竟然也写死了!!!
改为
#define CYGMEM_SECTION_heap1_SIZE (CYGMEM_REGION_ram + CYGMEM_REGION_ram_SIZE - (size_t)CYG_LABEL_NAME(__heap1))
控制 user_ram_end
五 至少现在有了不错的结局
编译ecos redboot
1. 声明环境变量, 主要是 ECOS_REPOSITORY
# Redboot and Ecos config
ECOS_SOURCE_DIR=/root/bak/arca-kernel/redboot/ecos2/ecos-2.0
ECOS_REPOSITORY=$ECOS_SOURCE_DIR/packages
export ECOS_SOURCE_DIR ECOS_REPOSITORY
2. 整理配置代码和编译
新建一个目录 mytest/, cd mytest // 后面的指令会在这个目录下组织一些代码
ecosconfig new bootes redboot
ecosconfig add flash eth_drivers
ecosconfig tree // 会建立相应的 makefile
make
编译完成的 bin 和 elf 文件会在 mytest/install/bin/