分类: LINUX
2008-04-26 11:38:11
1. 我的开发板配置如下:
AT91rm9200, 180MHz; 32MB SDRAM, 由NCS1/SDCS片选; 64KB EEPROM, AT
2.首先我们要搞清楚,真正的理解和成功的移植uboot得先弄明白at91rm9200的启动流程和uboot的启动方法: at91rm9200有片内引导和片外引导 2 种启动方式,由一根跳线控制。上电MCU检测BMS的电平,如果是高则选择片内ROM启动, 如果是低则从外部flash启动。 (1) 片外引导 执行烧在flash上的引导程序。 (2) 片内引导 at91rm9200内部本身有128k的片内rom,其固化了一个bootloader和uploader,片内引导时启动uploader,uploader开启xmodem协议,等待用户上传程序,上传的程序将载入片内SRAM,重映射,然后pc跳转到片内SRAM执行上传的用户程序。注:片内SRAM只有16k,除去3-4k片内启动程序的占用的部分数据空间,因此下载的程序大小限制在12k内。
官方at91rm9200DK u-boot Flash Programming Solutions文档提供的解决方案如下。开发板flash上没有引导程序,于是只能用片内引导方式,载入一个12k以内的小程序到内部SRAM运行,而这个小程序初始化SDRAM后,再把u-boot下载到SDRAM运行(u-boot大于12k),pc跳到SDRAM的u-boot位置运行u-boot,u-boot启动后再用u-boot自己的flash烧写命令把自己烧到flash去,以后就可以片外flash启动了。
官方文档中并不是直接烧u-boot.bin,而是烧入了boot.bin和u-boot.gz2个文件。 Loader.bin 和 boot.bin我暂时用的是板子提供的修改好的,这里重点先研究研究uboot的启动和移植。不过我还是了解了一下它们的启动流程,以便更好的去移植uboot。 loader.bin, boot.bin, u-boot.bin代码执行流分析. 以上三个文件时at91rm9200启动所需要的三个bin,他们的实现代码并不难。如果是你是采用at91rm9200的评估版,应该能得到其源码。
loader.bin 执行流程,这个文件主要在片内启动从串口下载代码时会用到 loader/entry.S 初始化CPU
b main --->
crt0.S -->
copydata -->
clearbss -->
b boot main.c -->
boot --> /*Get internel rom service address*/
/* Init of ROM services structure */
pAT91 = AT
/* Xmodem Initialization */
--> pAT91->OpenSBuffer -->
pAT91->OpenSvcXmodem
/* System Timer initialization */
---> AT
/*
AT
AT
Jump.S // Jump to Uboot BaseAddr exec Jump((unsigned int)AT
boot.bin执行流程 该文件会在从片内启动时被下载到板子上,以后还会被烧写到片外Flash中,以便在片外启动时用它来引导并解压u-boot.bin.gz,并跳转到u-boot来执行。 boot/entry.S b main -->
crt0.S -->
copydata -->
clearbss -->
b boot boot/misc.s /* unzip uboot.bin.gz */ ----> decompress_image(SRC,DST,LEN) -->
gunzip //jump to ubootBaseAddr exec 这里跳转到解压u-boot.bin.gz的地址处直接开始执行u-boot asm("mov pc,%0" : : "r" (DST));
u-boot.bin执行流程 u-boot/cpu/at91rm9200/start.S
start --->
reset --->
copyex --->
cpu_init_crit --->
/* set up the stack */
--> start_armboot
u-boot/lib_arm/board.c
init_fnc_t*init_sequence[] = {
cpu_init, /* basic cpu dependent setup */
board_init, /* basic board dependent setup */
interrupt_init, /* set up exceptions */
env_init, /* initialize environment */
init_baudrate, /* initialze baudrate settings */
serial_init, /* serial communications setup */
console_init_f, /* stage 1 init of console */
display_banner, /* say that we are here */
dram_init, /* configure available RAM banks */
display_dram_config, checkboard, NULL,
};
---> start_armboot
---> call init_sequence
---> flash_init
---> display_flash_config
---> nand_init
---> AT
---> dataflash_print_info
---> env_relocate
---> drv_vfd_init
---> devices_init
---> jumptable_init
---> console_init_r
---> misc_init_r
---> enable_interrupts
---> cs8900_get_enetaddr
---> board_post_init
---> u-boot/common/main.c
for (;;)
{ /* shell parser */
main_loop () -->
u_boot_hush_start -->
readline -->
abortboot -->
printf("Hit any key to stop autoboot: %2d ", bootdelay);
}
以上是at91rm9200启动并进入u-boot的执行流分析。后面u-boot还会将uImage解压到特定的位置并开始启动内核代码。
3.1 修改Loader.bin的源码
1). 修改 include/main.h
#define AT
2). 修改init.c中对SDRAM的初始化 AT
3.2 修改Boot.bin的源码
1). 在main.c中添加两个外部函数的定义
Extern int deampress_image(void *src,void *dst,unsigned int len); 解压缩函数,用来解压缩UBOOT Extern void Jump() 跳转函数
2). 在main.c中修改宏定义
#define SRC 0x10010000 uboot在flash中的基地址
#define DST 0x
3) 修改main.c中打印语句 AT
AT
4.实战
从网上下载官方uboot
修改的地方在board/at91rm9200dk/atrm9200dk.c,对nand_init进行修改。主要是:
将 *AT
改为 *AT
将 *AT
改为 *AT
*AT
*AT
注:AT
AT
AT
AT
上述修改的目的是,使能BFCK信号线的GPIO输出。
在
/*Configure PC2 as input (signal READY of theSmartMedia)*/后增加
*AT
然后把调试信息打开-把#ifdef DEBUG给注释掉。看看你的nandflash的base对不对。
然后就是修改/include/cmd_confdefs.h
修改 #define CFG_CMD_NONSTD ()这个宏定义是决定uboot支持的功能,
如果需要支持就从括号中删除此行。例如源码支持 CFG_CMD_LOADB CFG_CMD_MEMORY 等。我们这里的修改是删除 “CFG_CMD_NAND | \ ” 这行,是uboot支持nandflash。然后你的nandflash的侦测ID等等,之类的东西都在cmd_nand.c里进行了,首先就是nand_probe,里面有两个重要的子函数。可以看看。然后把调试信息打开。看看是不是你想要的信息,比如: mfr=ec id=76 Flash chip found: Manufacturer ID: 0xEC, Chip ID: 0x76 (Samsung K