U-BOOT全线移植分析系列之三
――U-BOOT在AT91RM9200上的移植
Sailor_forever [email protected] 转载请注明
http://blog.csdn.net/sailor_8318/archive/2008/08/05/2773307.aspx
【摘要】本节介绍了U-boot在AT91RM9200上移植的详细过程。首先分析AT91RM9200片内片外启动的详细流程,接着介绍了AT91RM9200启动所需几个文件的执行流程。针对片内片外存储器的映射情况,介绍了bootloader、内核及文件系统的内存分布。最后介绍了uboot在AT91RM9200上移植所需要的基本文件,并根据开发板的配置情况介绍了详细的移植过程。
【关键词】AT91RM9200,U-boot,片内启动,片外启动,loader,内存分布
三 U-BOOT在AT91RM9200上的移植
在这里我主要介绍通过片内引导和片外引导, 片内引导通常主要采用串口下载并引导u-boot,并将程序被烧写到 Flash上,然后就可以通过跳线的方式从片外引导执行已经烧写到片外Flash上的引导程序(bootloader)。
3.1.1 片内引导
1) 片内引导的基本原理
系统上电,检测BMS,选择系统的启动方式,如果BMS为高电平,则系统从片内ROM启动。AT91RM9200的内部ROM上电后被映射到了0x0和0x100000处,在这两个地址处都可以访问到ROM。由于9200的ROM中固化了一个BOOTLOAER程序。所以PC从0X0处开始执行这个BOOTLOAER(准确的说应该是一级BOOTLOADER)。这个BOOTLOADER依次完成以下步骤:
² PLL SETUP。设置PLLB产生 48M 时钟频率提供给USB DEVICE。同时DEBUG USART也被初始化为 48M 的时钟频率。
² 相应模式下的堆栈设置
² 检测主时钟源(Main oscillator)
² 中断控制器(AIC)的设置
² C 变量的初始化
² 跳到主函数
完成以上步骤后,我们可以认为BOOT过程结束,接下来的就是LOADER的过程,或者也可以认为是装载二级BOOTLOER。AT91RM9200按照DATAFLASH、EEPROM、连接在外部总线上的8位并行FLASH的顺序依次来找合法的BOOT程序。所谓合法的指的是在这些存储设备的开始地址处连续的存放的32个字节,也就是8条指令必须是跳转指令或者装载PC的指令,其实这样规定就是把这8条指令当作是异常向量表来处理。必须注意的是第6条指令要包含将要装载的映像的大小。关于如何计算和写这条指令可以参考用户手册。一旦合法的映像找到之后,则BOOT程序会把找到的映像搬到内部SRAM中去,所以映像的大小是非常有限的,不能超过16K的大小。当BOOT程序完成了把合法的映像搬到SRAM的任务以后,接下来就进行存储器的REMAP,经过REMAP之后,SRAM从映设前的0X200000地址处被映设到了0X0地址并且程序从0X0处开始执行。而ROM这时只能在0X100000这个地址处看到了。至此9200就算完成了一种形式的启动过程。
如果BOOT程序在以上所列的几种存储设备中未找到合法的映像,则自动初始化DEBUG USART口和USB DEVICE口以准备从外部载入映像,大多数情况都是如此。对DEBUG口的初始化包括设置参数115200 8 N 1以及运行XMODEM协议。对USB DEVICE进行初始化以及运行DFU协议。现在用户可以从外部(假定为PC平台)载入你的映像了。在PC平台下,以WIN2000为例,你可以用超级终端来完成这个功能,但是还是要注意你的映像的大小不能超过13K。一旦正确从外部装载了映像,接下来的过程就是和前面一样重映设然后执行映像了。
注意:通常所说的片内引导是指没有烧写合法的印象的情况下,但并不意外着烧些了合法印象的情况下不能采用片内引导的方式。通常第一次下载了启动印象后就会选择片外启动的方式了。并且烧些的印象通常第6条指令都不含将要装载的映像的大小,所以片内启动时一般不能运行这些印象。关于片内引导的详细过程可以参看at91rm9200的芯片说明书――引导程序一章。
Boot program Flow Diagram
Device Setup
|
Boot SPI DataFlash Boot --> Download from DataFlash --> run
|
TWI EEPROM Boot --> Download from EEPROM --> run
|
Parallel Boot --> Download from 8-bit Device -->
|
| Xmodem protocol
| |---DBGU Serial Download ---------------------> run
|____|
| DFU protocol
|-----USB download -----------------------> run
at91rm9200片内引导流程图
2) at91rm9200片内引导u-boot的实现过程
at91rm9200内部本身有128k的片内rom,其固化了一个bootloader和uploader,其他存储设备上没有合法的映象时,片内引导将启动uploader,uploader开启xmodem协议,等待用户上传程序,上传的程序将载入片内SRAM,重映射,然后pc跳转到片内SRAM执行上传的用户程序,即loader.bin。
注:片内SRAM只有16k,除去3-4k片内启动程序的占用的部分数据空间,因此下载的程序大小限制在12k内。
裸板只能用片内引导方式,载入一个12k以内的小程序loader.bin到内部SRAM运行,而这个小程序初始化SDRAM后,再把u-boot.bin下载到SDRAM的高端运行(u-boot大于12k,不能直接下载的原因就在于此),pc跳到SDRAM的u-boot位置运行u-boot,u-boot启动后再用u-boot自己的命令把boot.bin 及u-boot.gz下载到SDRAM的低端,再用flash烧写命令烧到flash去,以后就可以片外flash启动了。
3.1.2 片外引导
如果BMS为低电平,则AT91RM9200会从片外的FLASH启动,这时片外的FLASH的起始地址就是0X0了,要求已经在此地址烧些了启动映象了,接下来的过程和片内启动的过程是一样的,只不过这时就需要自己写启动代码了,至于怎么写,大致的内容和ROM的BOOT差不多,不同的硬件设计可能有不一样的地方,但基本的都是一样的。由于片外FLASH可以设计的大,所以这里编写的BOOTLOADER可以一步到位,也就是说不用像片内启动可能需要BOOT好几级了。
对于AT91RM9200,通常选择在flash的首地址处放的是boot.bin,由其将u-boot.bin.gz解压到高端RAM中,再运行真正的u-boot.bin,也就是实际的启动映象。
以上三个文件是at91rm9200启动所需要的三个bin,他们的实现代码并不难。
3.2.1 loader.bin
执行流程,这个文件主要在片内启动从串口下载U-boot.bin代码时会用到,一般固化在CPU的内部ROM中,用户无需改动。
loader/entry.S init cpu
b main ---> crt0.S
--> copydata --> clearbss --> b boot
main.c --> boot -->
/*Get internel rom service address*/
/* Init of ROM services structure */
pAT91 = AT 91C _ROM_BOOT_ADDRESS;
/* Xmodem Initialization */
--> pAT91->OpenSBuffer
--> pAT91->OpenSvcXmodem
/* System Timer initialization */
---> AT 91F _AIC_ConfigureIt
/* Enable ST interrupt */
AT 91F _AIC_EnableIt
AT 91F _DBGU_Printk("XMODEM: Download U-BOOT ");
Jump.S
// Jump to Uboot BaseAddr exec
Jump((unsigned int)AT 91C _UBOOT_BASE_ADDRESS) 跳到下载的U-boot.bin执行
××××××××××××××××××××××××××××××××××
lader.bin主要有3个功能,初始化SDRAM,启动xmodem接收u-boot并写到SDRAM中,pc跳转到SDRAM运行。
xmodem的实现
只需要接收部分,发送部分用win下的”超级终端”等工具就可。先找来协议文档,熟悉协议,看看现有的xmodem协议源码。协议本身并不复杂,只是它的握手部分实现有点技巧。接收端要不停的发送字符“C”到串口,发送端收到“C”后发送数据SOH和第一个数据包。接收端检测到SOH后停止发送“C”并开始处理数据。官方的loader启动了一个时间服务,每隔1s发送一个“C”,在这个我使用了偷懒的算法。
while(Getchar()!=AT 91C _XMODEM_SOH)
{
if (0xFFFF==++n )
{
SendChar(AT 91C _XMODEM_CRCCHR);
n=0;
}
}
握手解决了,后面的处理都没什么问题。
写SDRAM
unsigned char *pSdram = (unsigned char *)AT 91C _UBOOT_BASE_ADDRESS;
for ( n = 0; n<128 ; n ++ )
{
*pSdram++=data[n];
}
PC跳转
添加一个文件jump.S到工程
AREA reset, CODE, READONLY
EXPORT Jump
Jump
mov pc, r0
END
;---------------------------------------------------------------------------------
在main中使用下面的函数跳转
Jump((unsigned int)AT 91C _UBOOT_BASE_ADDRESS);
loader的调试过程
xmodem部分可以传一个调试文件,传进去后全部send回串口,看返回的信息就可以判断是否正常工作。
写SDRAM,依然是写入后再读出来看看是否一致,在这里卡了很久,发现每隔2个地址就不能使用,后来发现是SDRAM没有初始化,重写后正常。
Jump测试,得传入一个可以运行的程序到内存才能判断,用先前编译好的u-boot- 1.0.0 试一试,出现u-boot的提示符了,也就是说jump没问题。
×××××××××××××××××××××××××××××××××××
3.2.2 boot.bin执行流程
该文件会在从片内启动时由U-boot.bin下载到板子上,以后还会被烧写到片外Flash中,以便在片外启动时用它来引导并解压u-boot.gz,并跳转到解压后的u-boot来执行。
boot/entry.S
b main --> crt0.S --> copydata --> clearbss --> b boot
T 91F _DBGU_Printk(" ");
AT 91F _DBGU_Printk("************************************** ");
AT 91F _DBGU_Printk("** Welcome to at91rm9200 ** ");
AT 91F _DBGU_Printk("************************************** ");
boot/misc.s /* unzip uboot.bin.gz */
----> decompress_image(SRC,DST,LEN) --> gunzip
//jump to ubootBaseAddr exec 这里跳转到解压后的u-boot地址处直接开始执行u-boot
asm("mov pc,%0" : : "r" (DST));
修改main.c中下面2项
#define SRC 0x10010000 (u-boot.gz将烧入flash的位置)
#define DST 0x 21f 00000 (u-boot.gz被解压后载入SDRAM的位置,和loader中保持一致)
3.2.1 uboot.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 91F _DataflashInit
---> 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解压到特定的位置并开始执行内核代码。
第一级地址译码由存储控制器执行,即由具有附加功能的高级系统总线(ASB) 执行。译码将32位地址总线决定的 4G 的地址空间分为16 个 256M 字节的区域。区域1 ~ 8 对应EBI,和外部片选NC0 ~NCS7相联系。区域0为内部存储器地址,第二级译码提供 1M 字节内部存储空间。区域15为外设地址,且提供对高级外设总线(APB) 的访问。其它区域未使用,使用它们进行访问时将向发出访问请求的主机发出异常中断。注意,地址的转换都是按照字节为单位的。
物理存储空间分布
3.3.1 内部存储器映射
内部ROM:AT91RM9200集成了一个128-K字节的内部ROM。任何时候,ROM均被映射到地址0x10 0000。若复位时BMS 为高,即片内启动时,则在复位后到重新映射命令执行前,ROM有两个地址,可访问地址0x0。重映射之后SRAM将变为0地址,内部ROM地址就只为0x10 0000。
ROM容量为128KB,即对应0x20000。所以范围为0x100000-0x120000。
内部RAM:AT91RM9200集成了高速,16-K 字节的内部SRAM。复位后到重新映射命令执行前,只可访问SRAM 中0x20 0000的地址空间。重新映射后, SRAM 在地址0x0有效。
RAM容量为16KB,即对应0x4000,所以范围为0x200000-0x204000。
USB 主机端口:AT91RM9200集成了一个USB主机端口开放主机控制器接口(OHCI)。ASB可直接访问该接口寄存器,且同标准内部存储器一样映射到地址0x30 0000。
内部存储器映射
3.3.2 外部存储器映射
嵌入式存储设备通常主要是外部RAM 和作为永久存储媒质的Flash。
现在所用的AT91RM9200开发板所用的SDRAM是K4S 281632F ,其容量为4banks×2Mbits×16,即128Mbits=16Mbytes。SDRAM共有两片K4S 281632F ,数据总线位宽16,两片组成32位位宽,所以SDRAM容量为32MB。
现在所用的Flash芯片为Intel的 28F 128J 3A ,容量为 16M ,地址映射从0x10000000到0x10FF FFFF。现在将Flash分为128个扇区,每个扇区为128KB=0x20000,每个扇区分为两个擦除块,为64KB=0x10000。
-------------------------------------------------------------------
Chip Select 0――Flash(0x1000 0000-0x10FF FFFF)
0x1000 0000(第0扇区)
boot.bin Flash
0x1001 0000(第0扇区)
u-boot.bin.gz Flash
0x1002 0000(第1扇区)
uImage Flash
.。。。。
0x1012 0000(第9扇区)
ramdisk Flash
.
0x107E 0000(第127扇区)
u-boot环境变量 Flash
-------------------------------------------------------------------
Chip Select 1――SDRAM(0x2000 0000-0x2200 0000)
0x2000 0000
SDRAM
.。。。。
0x2100 0000
uImage SDRAM
0x2110 0000
ramdisk SDRAM
------------------------------------------------------------------
0x0000 0000 ROM |
0x1000 0000 boot.bin FLASH |
0x1001 0000 uboot.gz FLASH |
0x1002 0000 ulmage FLASH |
0x1012 0000 ramdisk FLASH |
U-BOOT环境变量 8M _FLASH 63 扇区 FLASH 16M _FLASH 127扇区 |
0x2000 0000 SDRAM |
0x2100 0000 ulmage SDRAM |
0x2110 0000 ramdisk SDRAM |
各种文件的内存分布图
为了使u-boot- 1.0.0 支持新的开发板,一种简便的做法是在u-boot已经支持的开发板中参考选择一种较接近板的进行修改, 幸运的是在u-boot-1.0.0中已经有了at91rm9200的支持。 下面将详细阐述对其进行移植所需要关注的几个方面:
l 修改原因:
硬件平台不同部分:由于目标板对GPIO、串口等硬件的使用不同或选择的RAM、flash等芯片的不同,都需要对相应的控制寄存器和硬件设备进行不同的初始化。
向bootloader增加新的功能:比如,有时想在目标平台上增加USB或Ethernet下载功能等,同样需要在源码中加入相应的代码。
l 移植相关内容:
² 在include/configs/at91rm9200dk.h 它包括开发板的CPU、系统时钟、RAM、Flash系统及其它相关的配置信息。与具体的板子相关,是移植的最重要文件。
² 在include/asm-arm/AT91RM9200.h, 该文件描述了9200寄存器的结构及若干宏定义。具体内容要参考相关处理器手册。相同CPU的此文件相同,拷贝一份即可,无需修改。
² 在cpu/at91rm9200/目录下别为cpu.c、interrupts.c和serial.c等文件。
Ø cpu.c 无需改动,缓存,中断堆栈初始化,MMU映射等
Ø interrupts.c无需修改。各种中断的处理函数,U-boot运行无需中断,同时实现为重启;定时中断实现为查询方式,主要用于Xmodem协议传输文件。
Ø serial.c 无需修改,串口初始化,接收发送等。
Ø 上述文件都是与CPU相关的,与板子本身的配置无关。通常选择一个相同的CPU下的相关文件即可,无需修改。
² 在board/at91rm9200dk/目录下分别为flash.c、at91rm9200dk.c、config.mk、Makefile和u-boot.lds。
Ø flash.c : u-boot读、写和删除Flash设备的源代码文件。由于不同开发板中Flash存储器的种类各不相同(是移植的重点,可以从其他CPU目录下看是否有相同的flash),所以,修改flash.c时需参考相应的Flash芯片手册。
Ø at91rm9200dk.c
板级初始化,DRAM地址初始化。修改文件
/* arch number of AT91RM9200DK-Board */
gd->bd->bi_arch_number = 251;
/* adress of boot parameters */
gd->bd->bi_boot_params = PHYS_SDRAM + 0x100;
体系结构号,CPU相关,同CPU此值相同。
bi_boot_params内核启动参数的首地址,通常为PHYS_SDRAM + 0x100;即SDRAM的100处,很重要,Linux内核移植时,此值需要匹配。
Ø config.mk
TEXT_BASE = 0x 21f 00000(u-boot将被载入SDRAM的高端部分)
注意,对于不同的系统RAM大小可能不一样,要根据实际情况调整。
Ø Makefile 无需修改,除非改动了at91rm9200dk.c的名字,目标文件要改动。
OBJS := at91rm9200dk.o flash.o
Ø u-boot.lds 链接脚本, 设置u-boot中各个目标文件的连接地址。无需修改
² Makefile
在u-boot- 1.0.0 /Makefile中
at91rm9200dk_config : unconfig
./mkconfig $(@:_config=) arm at91rm9200 at91rm9200dk
其中ARM是CPU的种类, at91rm9200是ARM CPU对应的代码目录,at91rm9200dk是自已主板对应的目录。
关于u-boot的移植如下,由于u-boot的软件设计体系非常清晰,它的移植工作并不复杂,相信各位的代码阅读功力不错的话,参照如下就可以完成。
×××××××××××××××××××××××××××××××××××
If the system board that you have is not listed, then you will need to port U-Boot to your hardware platform. To do this, follow these steps:
1. Add a new configuration option for your board to the toplevel "Makefile" and to the "MAKEALL" script, using the existing entries as examples. Note that here and at many other places boards and other names are listed in alphabetical sort order. Please keep this order.
2. Create a new directory to hold your board specific code. Add any files you need. In your board directory, you will need at least the "Makefile", a ".c", "flash.c" and "u-boot.lds".
3. Create a new configuration file "include/configs/.h" for your board
4. If you're porting U-Boot to a new CPU, then also create a new directory to hold your CPU specific code. Add any files you need.
5. Run "make _config" with your new name.
6. Type "make", and you should get a working "u-boot.srec" file
7. Debug and solve any problems that might arise. [Of course, this last step is much harder than it sounds.]
××××××××××××××××××××××××××××××××××××
(一)在board文件夹下面建立自己的开发板的文件夹。一般的,要选取与自己的开发板硬件设置最为接近的型号。在u-boot- 1.1.1 中,已经支持at91rm9200,所以可以选取at91rm9200dk作为模板进行修改。设置你的开发板的名字,随意即可,我的设置为:myboard。
[root@dding u-boot- 1.1.1 ]$ cd board
[root@dding board]$ cp -R at91rm9200dk/ myboard/
[root@dding board]$ cd myboard
[root@dding myboard]$ ls
at91rm9200dk.c config.mk flash.c Makefile u-boot.lds
(二)可以看到,这里共有5个文件。首先,要修改主文件的名字,即要把at91rm9200dk.c更改为myboard.c。其次,要更改config.mk中TEXT_BASE的数值,其为uboot在RAM中的运行地址。注意,由于at91rm9200中是由boot.bin将uboot映象直接拷贝到RAM中了,TEXT_BASE值必须和boot.bin拷贝的地址一致。否则uboot发现运行地址和链接地址不同时会再次执行自拷贝过程,可能将自己覆盖。由于接下来,因为在at91rm9200dk用的是AMD的flash,而我的开发板上用的是Intel的 28F 128J 3A ,那么需要另外找Intel的flash.C,以减少工作量。在strong ARM构架里有xm250,它的flash是Intel的,修改的东西并不是很多。需要注意的是,xm250的flash位宽是32,而我的位宽是16,要根据这个进行相应的修改。最后,修改Makefile,主要是修改生成文件的名字。具体操作如下:
[root@dding myboard]$ mv at91rm9200dk.c myboard.c
[root@dding myboard]$ cat config.mk
TEXT_BASE = 0x 21f 80000
[root@dding myboard]$ vi config.mk
修改成:TEXT_BASE = 0x 21f 00000,然后保存退出。
[root@dding myboard]$ vi Makefile
include $(TOPDIR)/config.mk
LIB = lib$(BOARD).a
OBJS := myboard.o flash.o
SOBJS :=
$(LIB): $(OBJS) $(SOBJS)
$(AR) crv $@ $(OBJS) $(SOBJS)
clean:
rm -f $(SOBJS) $(OBJS)
[root@dding myboard]$ rm flash.c
[root@dding myboard]$ cp ../xm250/flash.c ./
[root@dding myboard]$ ls
config.mk flash.c Makefile myboard.c u-boot.lds
[root@dding myboard]$ vi flash.c
34 #undef FLASH_PORT_WIDTH32 /*不定义位宽32*/
35 #define FLASH_PORT_WIDTH16 /*定义位宽16*/
216 switch (value) {
217
218 case (FPW) INTEL_ID_ 28F 128J 3A : /*就是这个芯片*/
219 info->flash_id += FLASH_ 28F 128J 3A ;
220 info->sector_count = 128;
221 info->size = 0x01000000;
222 break; /* => 16 MB */
223
224 case (FPW) INTEL_ID_ 28F 640J 3A :
225 info->flash_id += FLASH_ 28F 640J 3A ;
226 info->sector_count = 64;
227 info->size = 0x00800000;
228 break; /* => 8 MB */
[root@dding myboard]$ cd ../..
[root@dding u-boot- 1.1.1 ]$ vi Makefile
#########################################################################
## AT91RM9200 Systems
#########################################################################
at91rm9200dk_config : unconfig
@./mkconfig $(@:_config=) arm at91rm9200 at91rm9200dk
myboard_config : unconfig
@./mkconfig $(@:_config=) arm at91rm9200 myboard
#########################################################################
在这里,可以在命令模式下输入“/at91rm 9200” 快速查找at91rm9200dk,仿照它的例子,写出自己板子的配置。注意的是,第二行开头要用TAB键,不是空格,否则报错。选项arm表示目标板架构,at91rm9200表示CPU中对应的目录,myboard是你自己的开发板名字,对应board下的目录。
(三)修改主要的配置文件。配置选项比较多,主要是配置cpu,波特率,flash和sdram的类型大小,环境变量的偏移量等等,容易出错。应该首先了解硬件情况,仔细对应芯片资料进行修改。见上面的《AT91RM9200开发板的存储器情况》
[root@dding u-boot- 1.1.1 ]$ cd include/configs
[root@dding configs]$ cp at91rm9200dk.h myboard.h
[root@dding configs]$ vi myboard.h
#define CONFIG_ myboard 1 /* on an myboard Board */
#undef CONFIG_USE_IRQ /* we don't need IRQ/FIQ stuff */
#define CONFIG_CMDLINE_TAG 1 /* enable passing of ATAGs */
#define CONFIG_SETUP_MEMORY_TAGS 1
#define CONFIG_INITRD_TAG 1
#define CFG_MALLOC_LEN (CFG_ENV_SIZE + 128*1024)
#define CONFIG_BAUDRATE 115200
#define CONFIG_BOOTDELAY 3 // u-boot延时等待时间
/* #define CONFIG_ENV_OVERWRITE 1 */
#define CONFIG_COMMANDS /
((CONFIG_CMD_DFL | /
CFG_CMD_DHCP ) & /
~(CFG_CMD_BDI | /
CFG_CMD_IMI | /
CFG_CMD_AUTOSCRIPT | /
CFG_CMD_FPGA | /
CFG_CMD_MISC | /
CFG_CMD_LOADS ))
/* this must be included AFTER the definition of CONFIG_COMMANDS (if any) */
#include <cmd_confdefs.h>
#define CONFIG_NR_DRAM_BANKS 1 // sdram banks,我的是一个,通常都是一个
#define PHYS_SDRAM 0x20000000 // sdram起始地址,at91rm9200统一为0x20000000
#define PHYS_SDRAM_SIZE 0x2000000 /* 32 M */
// sdram容量32MB,需要根据实际情况修改,芯片为两片三星的16位× 16M K4S 281632F
#define CFG_MEMTEST_START PHYS_SDRAM
#define CFG_MEMTEST_END CFG_MEMTEST_START + PHYS_SDRAM_SIZE – 0x10 0000
SDRAM的高端部分此时运行着U-boot,测试时不能对自身进行
#define CONFIG_DRIVER_ETHER 支持以太网驱动
#define CONFIG_NET_RETRY_COUNT 20
// flash为intel的 16M 28F 128J 3A in 128 Sectors
#define PHYS_FLASH_1 0x10000000 //起始地址,at91rm9200统一为0x10000000
#define PHYS_FLASH_SIZE 0x100 0000 /* 16M main flash */
#define CFG_FLASH_BASE PHYS_FLASH_1 // PHYS_FLASH_1 flash起始地址别名
#define CFG_MAX_FLASH_BANKS 1 // flash最大banks数
#define CFG_MAX_FLASH_SECT 128 //扇区总数
#define CFG_FLASH_ERASE_TOUT (2*CFG_HZ) /* Timeout for Flash Erase */
#define CFG_FLASH_WRITE_TOUT (2*CFG_HZ) /* Timeout for Flash Write */
PHYS_FLASH_SIZE和CFG_MAX_FLASH_SECT通常都未用,因此上述错误没有体现出来
#define CFG_ENV_IS_IN_FLASH 1 // 环境变量保存在flash中
#define CFG_ENV_ADDR (PHYS_FLASH_1 + 0x20000×127) // 环境变量在flash中的地址
#define CFG_ENV_SIZE 0x20000 // 环境变量的大小,一个sector
#define CFG_LOAD_ADDR 0x21000000 /* default load address */
// 内核印象默认的加载地址,需要与自启动的参数匹配下
// 关于U-boot的启动代码等大小和地址对任何CPU都无需改动,但是实际往flash中存储时需要按照此地址来进行
//boot.bin 0x1000 0000
//u-boot.gz 0x1001 0000
#define CFG_BOOT_SIZE 0x6000 /* 24 KBytes */ // boot.bin的大小
#define CFG_U_BOOT_BASE (PHYS_FLASH_1 + 0x10000) // u-boot.gz的存放位置,此位置不能随意更改,必须和boot.bin中的地址一致
#define CFG_U_BOOT_SIZE 0x10000 /* 64 KBytes */ // u-boot.gz占据的flash空间,半个sector
#define CFG_BAUDRATE_TABLE {115200 , 19200, 38400, 57600, 9600 }
#define CFG_PROMPT "Uboot> " /* Monitor Command Prompt */ // U-boot的提示符,可随意更改
#define CFG_CBSIZE 256 /* Console I/O Buffer Size */
#define CFG_MAXARGS 16 /* max number of command args */
#define CFG_PBSIZE (CFG_CBSIZE+sizeof(CFG_PROMPT)+16) /* Print Buffer Size */
四、编译u-boot
[root@dding configs]$ cd ../..
[root@dding u-boot- 1.1.1 ]$ make myboard_config
Configuring for myboard board...
[root@dding u-boot- 1.1.1 ]$ make CROSS_COMPILE=arm-linux-
生成三个文件:u-boot.bin, u-boot, u-boot.srec
u-boot.bin is a raw binary image
u-boot is an image in ELF binary format
u-boot.srec is in Motorola S-Record format (objcopy -O srec -R.note -R.comment -S [inputfile] [outfile]
u-boot ELF格式的文件,可以被大多数Debug程序识别;
u-boot.bin—二进制bin文件,纯粹的U-BOOT二进制执行代码,不保存ELF格式和调试信息。这个文件一般用于烧录到用户开发板中;
u-boot.srec— Motorola S-Record格式,可以通过串行口下载到开发板中。
然后把生成的u-boot.bin保存,并且压缩一下得到u-boot.bin.gz。
一种方式是通过JTAG口将u-boot.bin烧写到Flash的零地址,复位后就可以启动系统了。此时无需boot.bin。
但是对于at91rm9200,我们是通过boot.bin来过渡的,烧写的是u-boot.bin.gz。以上工作完成我们可以通过串口将u-boot.bin下载到主板的SDRAM中,它会自动执行, 并出现uboot>
这里我们可以通过串口把boot.bin, u-boot.bin.gz下载到主板,再用u-boot的提供的写flash功能分别把boot.bin, u-boot.bin.gz写入到flash中,完成以上工作后,对主板跳线选择片外启动,板子复位后会自动启动u-boot。其首先运行boot.bin,其将u-boot.bin.gz解压缩到RAM中为u-boot.bin,并跳转至u-boot.bin开始执行。