详解u-boot

发布时间:2014-07-28 11:01:09

一、u-boot-1.1.4yl2410上的移植过程

1. 例行准备

3.2.1 修改Makefile

[uboot@localhost uboot]#vi Makefile

#crane2410建立编译项

yl2410_config : unconfig

@./mkconfig $(@:_config=) arm arm920t yl2410 NULL s3c24x0

各项的意思如下:

arm: CPU的架构(ARCH)

arm920t: CPU的类型(CPU),其对应于cpu/arm920t子目录。

yl2410: 开发板的型号(BOARD),对应于board/yl2410目录。

NULL: 开发者/或经销商(vender)

s3c24x0: 片上系统(SOC)

3.2.2 board子目录中建立yl2410

#cp rf board/smdk2410 board/yl2410

#cd board/yl2410

#mv smdk2410.c yl2410.c

3.2.3 include/configs/中建立配置头文件

#cd ../..

#cp include/configs/smdk2410.h include/configs/yl2410.h

3.2.4 指定交叉编译工具的路径

#vi ~/.bashrc

export PATH=/usr/local/arm/2.95.3/bin:$PATH

3.2.5 测试编译能否成功

#make yl2410_config /*产生include/config.mk*/

#make

1. make的过程中,出现:cc1: invalid option `abi=apcs-gnu'
解决方法:
出错的文件是/cpu/s3c44b0/下的config.mk:
PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,-mabi=apcs-gnu)
改成:
PLATFORM_CPPFLAGS +=$(call cc-option,-mapcs-32,$(call cc-option,-mabi=apcs-gnu),)

2. 修改了第一个错误后,继续make,出现了如下的报错:
make[1]: *** No rule to make target `hello_world.srec', needed by `all'.  Stop.
make[1]: Leaving directory `/home/mort/src/targa/u-boot/u-boot-TOT/examples'
make: *** [examples] Error 2
解决方法:
修改examples/Makefile
126行和129行改为:
     %.srec: %.o
     %.bin: %.o
继续make

3. 出现 crane2410.a needed by smdk2410.o
解决方法:
修改board/crane2410/Makefile
28行的
OBJS    := smdk2410.o flash.o
改为
OBJS    := crane2410.o flash.o
继续make获得u-boot

4. 初步调试,主要是在sdram上调试要打开CONFIG_SKIP_LOWLEVEL_INIT

即可看到打印信息

5. 读写NorFlashSST39VF1601

include/configs/yl2410.h添加

#ifdef CONFIG_SST_39VF1601

#define PHYS_FLASH_SIZE 0x00200000 /* 2MB */

#define CFG_MAX_FLASH_SECT (35) /* max number of sectors on one chip */

#define CFG_ENV_ADDR (CFG_FLASH_BASE + 0x1F0000) /* addr of environment */

#endif

修改board/yl2410/flash.c 参考board/dave/common/flash.c

#elif defined(CONFIG_SST_39VF1601)

(SST_MANUFACT & FLASH_VENDMASK) |

(SST_ID_xF1601 & FLASH_TYPEMASK);

int flash_erase (flash_info_t * info, int s_first, int s_last)

#if defined(CONFIG_SST_39VF1601) /* Ali + */

*addr = CMD_ERASE_BLOCK;

#else

*addr = CMD_ERASE_CONFIRM;

#endif

volatile static int write_hword (flash_info_t * info, ulong dest, ushort data)

#if defined(CONFIG_SST_39VF1601) /* Ali + */

MEM_FLASH_ADDR1 = CMD_PROGRAM;

#else

MEM_FLASH_ADDR1 = CMD_UNLOCK_BYPASS;

*addr = CMD_PROGRAM;

#endif

即可正确操作flash,其中monitor_flash_len(_bss_start - _armboot_start)和环境参数保存区是受保护的,标示为(RO)

6. norflash启动

打开选项CONFIG_S3C2410_NOR_BOOT

编译生成u-boot.bin

Loadb 0x32000000 115200 (set baud rate to 115200,download u-boot to 0x32000000 by Kermit protocol)

Cp.b 0x32000000 0 0x20000 (u-boot write to norflash)

重启,OK

7. 如要看到调试信息

include/configs/yl2410.h添加

#define DEBUG

8. ping命令时,输出“*** ERROR: `ethaddr' not set”,板上网卡CS8900本身没有固化MAC地址,自己在include/configs/yl2410.h设定一个,或者运行时设定环境参数,接下来使用pingtftp都正常

9. 支持nandflash读写

include/configs/yl2410.h添加CFG_CMD_NAND

编译,在cmd_nand.c产生很多错误,原因是yl2410根本就没有nandflash的驱动支持,如:

NAND_DISABLE_CE()

NAND_ENABLE_CE()

NAND_WAIT_READY()

WRITE_NAND_COMMAND()

WRITE_NAND_COMMANDW()

WRITE_NAND_ADDRESS()

WRITE_NAND()

这些函数的实现都很简单,参考at91rm9200dk.h,对nand的驱动支持全部添加在include/configs/yl2410.h

加载运行,nand write 0x32000000 0x20000 0x200 (nand flash512字节),报错,nand_write_page : Failed write verify 应该是sector(page)没擦除,nand erase 0x20000 0x200,出错,提示边界没对齐,查得资料获知,erase单位是一个block(16k)program单位是一个sector(512B),按要求先擦除后写入,正确

10. 支持nandflash启动

cpu/arm920t/start.S添加对nandflash重定位的支持,在board/yl2410/nand_boot.c添加对nandflash的初始化和读取操作,在nandflash启动时被start.s调用,注意nand_boot.c的所有代码以及被调用的代码不能超出4k,因为按nandflash启动模式,开始只有4k的运行空间。

编译获得u-boot.bin

Tftp 0x32000000 u-boot.bin (load u-boot.bin to 0x32000000)

Nand erase 0 0x20000 (erase nandflash first 128k)

Nand write 0x32000000 0 0x20000 (write u-boot.bin to nandflash)

设置跳线到nandflash启动模式,重启即可

二、流程图

三、答疑

1. 关于入口地址

board/yl2410/u-boot.lds

OUTPUT_ARCH(arm)

ENTRY(_start)

SECTIONS

{

. = 0x00000000;

. = ALIGN(4);

.text :

{

cpu/arm920t/start.o (.text)

*(.text)

}

}

_start的入口地址为0x00000000为何编译出来的代码。链接地址是从0x33f80000(TEXT_BASE)开始的?

答:

lds文件中的起始地址为0x00000000是不起作用的,由链接参数替代的。见u-boot-1.1.4/config.mkL145LDFLAGS += -Bstatic -T $(LDSCRIPT) -Ttext $(TEXT_BASE) $(PLATFORM_LDFLAGS)

2. 关于ADR的编译原理

adr r0, _start /* r0 <- current position of code */

_startflash运行是0,在sdram运行是0x33f80000

答:

伪指令:ADRADRLALIGNDCxEQUxOPT

ADR:小范围的地址读取伪指令.ADR 指令将基于PC 相对偏移的地址值读取到寄存器中.

在汇编编译源程序时,ADR 伪指令被编译器替换成一条合适的指令.通常,编译器用一条

ADD 指令或SUB 指令来实现该ADR 伪指令的功能,若不能用一条指令实现,则产生错误,

编译失败.

所以adr r0, _start,实际产生的汇编是sub r0,pc,#0x9c ; #0x33f80000

3. 关于nandflash启动

如何保证nandflash启动模式下,启动代码定位在前4k

一个是直接在start.s用汇编写nandflash的初始化和重定位代码,或者用Cnandflash启动代码nand_boot.c,进而修改编辑board/yl2410/u-boot.lds

*(.text) 之前添加board/yl2410/nand_boot.o (.text)(当然,运气好的话,不用也可以)

为了避免代码运行超出4knand_boot.c不能调用其它库函数,不能引用数据段(.data)的数据,因为*(.data)*(.text)之后,超出了4k

注意:在修改cpu/arm920t/start.S, nandflash启动模式不能引用_TEXT_BASE,因为

_TEXT_BASE:

.word TEXT_BASE

放于数据段,超出了4k的限制,可以用立即数或者宏定义替代。

4. nandflash启动模式下保存环境变量

u-boot启动后,出现“Warning - bad CRC, using default environment”,没有正确的环境变量。

查看S3C2410的数据手册,在图表“S3C2410A Memory Map after Reset”中显示,如果“Using NAND flash for boot ROM”,bank 0(128M)仅映射到片内的4k sram,所以同时位于bank 0norflash无效,这时候的环境变量只能保存于nandflash,修改include/configs/yl2410.h相关的宏定义,重新烧入到nandflash,启动后,输入“saveenv”即可。

5. 关于mmu

u-boot不需要中断重定位,可以关闭mmu

详解u-boot

相关推荐