HardBirch

U-BOOT全线移植分析系列之三 U-BOOT在AT91RM9200上的移植

时间:09-09-25 栏目:系统技术篇 作者:鲁智森也有文化 评论:0 点击: 2,181 次

 

装载自: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 上的移植

3.1 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 ,也就是实际的启动映象。

 

3.2 loader.bin, boot.bin, 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 解压到特定的位置并开始执行内核代码。

 

3.3 AT91RM9200 开发板的存储器情况
第一级地址译码由存储控制器执行,即由具有附加功能的高级系统总线 (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
 

 

各种文件的内存分布图

3.4 U-BOOT 在 at91rm9200 上 移植修改的文件
为了使 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 是自已主板对应的目录。

 

3.5 移植的具体步骤
关于 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 开始执行。

U-BOOT全线移植分析系列之三 U-BOOT在AT91RM9200上的移植:等您坐沙发呢!

发表评论


QQ群互动

Linux系统与内核学习群:194051772

WP建站技术学习交流群:194062106

魔豆之路QR

魔豆的Linux内核之路

魔豆的Linux内核之路

优秀工程师当看优秀书籍

优秀程序员,要看优秀书!

赞助商广告

友荐云推荐