【摘要】本节介绍了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 = AT91C_ROM_BOOT_ADDRESS;
/* Xmodem Initialization */
--> pAT91->OpenSBuffer
--> pAT91->OpenSvcXmodem
/* System Timer initialization */
---> AT91F_AIC_ConfigureIt
/* Enable ST interrupt */
AT91F_AIC_EnableIt
AT91F_DBGU_Printk("XMODEM: Download U-BOOT ");
Jump.S
// Jump to Uboot BaseAddr exec
Jump((unsigned int)AT91C_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()!=AT91C_XMODEM_SOH)
{
if (0xFFFF==++n )
{
SendChar(AT91C_XMODEM_CRCCHR);
n=0;
}
}
握手解决了,后面的处理都没什么问 题。
写SDRAM
unsigned char *pSdram = (unsigned char *) AT91C_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)AT91C_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 下 载到板子上 ,以后还会被烧 写到 片外 Flas h 中,以便在 片外启动时用它来引导并解压 u-boot.gz ,并跳转到解压后的u-boot 来执行。
boot/entry.S
b main --> crt0.S --> copydata --> clearbss --> b boot
T91F_DBGU_Printk(" ");
AT91F_DBGU_Printk("************************************** ");
AT91F_DBGU_Printk("** Welcome to at91rm9200 ** ");
AT91F_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 0x21f00000 (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 ---> AT91F_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 集成 了高速, 1 6-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 是 K4S281632F ,其容量为4banks×2Mbits×16 ,即128Mbits = 16Mbytes 。SDRAM 共有两片 K4S281632F ,数据总线位宽16 ,两片组成32 位位宽,所以SDRAM 容量为32MB 。
现在所用的Flash 芯片为Intel 的 28F 128J3A ,容量为 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 = 0x21f00000 (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 128J3A ,那么需要 另外找 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 = 0x21f80000
[root@dding myboard]$ vi config.mk
修改成: TEXT_BASE = 0x21f00000 ,然后保存退出。
[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_28F128J3A: /* 就是这个芯片 */
219 info->flash_id += FLASH_28F128J3A;
220 info->sector_count = 128;
221 info->size = 0x01000000;
222 break; /* => 16 MB */
223
224 case (FPW) INTEL_ID_28F640J3A :
225 info->flash_id += FLASH_28F640J3A;
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
#########################################################################
在这里,可以在命令模式下输入“/at91rm9200” 快速查找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 K4S281632F
#define CFG_MEM TEST _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 28F128J3A 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 开始执行。
本文来自CSDN博客,转载请标明出处:http://blog.csdn.net/sailor_8318/archive/2008/08/04/2768049.aspx