移植u-boot-2011.03到S3C2440(utu2440)的方法与步骤###2. 让u-boot-2011.03跑起来

来源:互联网 发布:淘宝玩具枪 编辑:程序博客网 时间:2024/05/22 02:04

作者:reille

本博客网址:http://blog.csdn.net/reille/

开发环境:主机:Window XP SP2;linux:VMware7.01+ubuntu9.10;目标板:扬创utu2440-F开发板

交叉编译器:arm-linux-gcc4.3.2(一开始用的是编译内核的版本arm-linux-gcc3.4.1,但出现了软浮点问题,于是换成了现在用的版本,当然本人编译内核的时候还是用3.4.1版本)

详细描述了本人移植u-boot-2011.03到S3C2440(utu2440)的方法与步骤,同时把移植过程中遇到的问题及其解决方法记录了下来,以供参考步骤

——————————————————————————————————————————————————————————————————

1. 编辑include/configs/reille2440.h文件

把reille2440.h文件中的line38、39两行屏蔽掉,同时添加如下信息:

//#define CONFIG_S3C2410    1          /* specifically a SAMSUNG S3C2410 SoC  需要屏蔽该宏定义  */
//#define CONFIG_SMDK2410    1    /* on a SAMSUNG SMDK2410 Board   需要屏蔽该宏定义 */
#define CONFIG_S3C2440     1           /* specifically a SAMSUNG S3C2440 SoC */
#define CONFIG_REILLE2440            /* on a SAMSUNG reille2440 Board  */
#define CONFIG_SKIP_LOWLEVEL_INIT

注意:

1) 打红色为添加信息(或者修改信息,以下同)

2) CONFIG_SKIP_LOWLEVEL_INIT是跳过底层一些初始化代码的宏开关,定义则跳过。如果编译的u-boot.bin用tftp下到SDRAM中运行,则需要定义该宏,特别注意!

3) 如果S3C2440的晶振用的不是12MHz的,则还需要修改CONFIG_SYS_CLK_FREQ的值!

2. uboot入口分析:

一般在嵌入式系统软件开发中,在所有源码文件编译完成之后,链接器要读取一个链接分配文件,在该文件中定义了程序的入口点、代码段、数据段等分配情况。对于2440开发板,u-boot的这个链接文件就是cpu/arm920t/u-boot.lds,打开该文件部分代码如下:

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm) //定义生成文件的目标平台是arm
ENTRY(_start) //定义程序的入口点是_start
SECTIONS
{
        //其他一些代码段、数据段等分配
       . = 0x00000000;
       . = ALIGN(4);
       .text :
       {
               cpu/arm920t/start.o    (.text)
         *(.text)
      }
      ..................
      ..................
}

知道了程序的入口点是_start,那么我们就打开2440开发板u-boot第一个要运行的程序cpu/arm920t/start.S,查找到_start的位置如下:

.globl _start
_start: b       start_code    //将程序的执行跳转到start_code处

从这个汇编代码可以看到程序又跳转到start_code处开始执行,那么再查找到start_code处的代码如下:

/*
* the actual start code
*/
start_code:
/*
     * set the cpu to SVC32 mode
     */
    mrs    r0,cpsr
    bic    r0,r0,#0x1f
    orr    r0,r0,#0xd3
    msr    cpsr,r0
    bl coloured_LED_init  //此处两行是对AT91RM9200DK开发板上的LED进行初始化的
    bl red_LED_on

由此可以看到,start_code处才是u-boot启动代码的真正开始处。

3. 在arch/arm/cpu/arm920t/start.S文件中修改相关初始化代码:S3C2440一些寄存器的支持、添加中断禁止部分和时钟设置部分

在start.S文件的164行至175行,用下面代码替换

# if defined(CONFIG_S3C2410)
    ldr    r1, =0x3ff
    ldr    r0, =INTSUBMSK
    str    r1, [r0]
# endif

# if defined(CONFIG_S3C2440)
# define LOCKTIME 0x4C000000
# define MPLLCON 0x4C000004
# define UPLLCON 0x4C000008

# define CLKDIV_VAL 5
# define M_MDIV 0x7f /* XTal=12.0MHz MPLL=405MHz */
# define M_PDIV 2
# define M_SDIV 1
# define U_MDIV 0x38 /* XTal=12.0MHz UPLL=48MHz */
# define U_PDIV 2
# define U_SDIV 2

    // 添加s3c2440的中断禁止部分
    ldr r1, =0x7fff
    ldr r0, =INTSUBMSK
    str r1, [r0]

    ldr r0,=LOCKTIME /* 设置U_LTIME和M_LTIME */
    ldr r1,=0x0fff0fff
    str r1,[r0]

    ldr r0, =CLKDIVN /* Fclk:Hclk:Pclk = 1:4:8 */
    ldr r1, =CLKDIV_VAL
    str r1, [r0]

    mrc p15, 0, r0, c1, c0, 0 /* 总线模式设为异步模式 */
    orr r0, r0, #0xc0000000
    mcr p15, 0, r0, c1, c0, 0

    ldr r0,=UPLLCON /* 配置UPLL */
    ldr r1,=((U_MDIV<<12) + (U_PDIV<<4) + U_SDIV)
    str r1,[r0]
    nop /* 为确保硬件完成操作,至少需7个时钟周期 */
    nop
    nop
    nop
    nop
    nop
    nop

    ldr r0,=MPLLCON /* 配置MPLL */
    ldr r1,=((M_MDIV<<12) + (M_PDIV<<4) + M_SDIV)
    str r1,[r0]
#else
    /* FCLK:HCLK:PCLK = 1:2:4 */
    /* default FCLK is 120 MHz ! */
    ldr    r0, =CLKDIVN
    mov    r1, #3
    str    r1, [r0]
#endif /* CONFIG_S3C2440 */

#endif    /* CONFIG_S3C24X0 */

S3C2440的时钟部分除了在start.S中添加外,还要在board/samsung/reille2440/reille2440.c修改或添加部分代码,如下:

#define FCLK_SPEED 2    //设置默认等于2

#if FCLK_SPEED==0 /* Fout = 203MHz, Fin = 12MHz for Audio */
#define M_MDIV 0xC3
#define M_PDIV 0x4
#define M_SDIV 0x1
#elif FCLK_SPEED==1 /* Fout = 202.8MHz */
#define M_MDIV 0xA1
#define M_PDIV 0x3
#define M_SDIV 0x1
#elif FCLK_SPEED==2 /* 设置默认等于2  Fout = 405MHz */
#define M_MDIV 0x7F
#define M_PDIV 0x2
#define M_SDIV 0x1
#endif

#define USB_CLOCK 2

#if USB_CLOCK==0
#define U_M_MDIV 0xA1
#define U_M_PDIV 0x3
#define U_M_SDIV 0x1
#elif USB_CLOCK==1
#define U_M_MDIV 0x48
#define U_M_PDIV 0x3
#define U_M_SDIV 0x2
#elif USB_CLOCK==2 /* Fout = 48MHz */
#define U_M_MDIV 0x38
#define U_M_PDIV 0x2
#define U_M_SDIV 0x2
#endif

int board_init (void)
{
     ......
     gd->bd->bi_arch_number = MACH_TYPE_REILLE2440;

     ......
}

int dram_init (void)
{
    gd->bd->bi_dram[0].start = PHYS_SDRAM_1;
    gd->bd->bi_dram[0].size = PHYS_SDRAM_1_SIZE;

    // 此处非常重要,否则uboot启动不起来
   gd->ram_size = PHYS_SDRAM_1_SIZE;

    return 0;
}

MACH_TYPE_REILLE2440为linux内核机器码值,在include/asm/mach-types中添加定义如下:

#define MACH_TYPE_REILLE2440             5244

4. 编译并用tftp下载到SDRAM中运行

按上述修改完后,如果想编译后的u-boot.bin能下载到SDRAM中运行,则还需要修改一个地方!

修改board/samsung/reille2440/config.mk

CONFIG_SYS_TEXT_BASE = 0x33000000/*0x3f800000改为0x33000000 以便内存中调试*/

这是因为,在板运行的uboot已经占用了0x3f800000及其以上的地址,如果用tftp仍下载到SDRAM的这个地址,则在板运行的uboot则会死掉,你移植的uboot则下载不进SDRAM了!

修改完毕后,重新编译出u-boot.bin,然后用tftp下载到SDRAM中运行:

tftp 0x33000000 u-boot.bin

go 0x33000000

本人在移植的时候,由于在dram_init ()函数中忘记添加gd->ram_size = PHYS_SDRAM_1_SIZE; 导致uboot启动不起来,运行到下面的提示就不动了!

U-Boot 2011.03 (Jun 12 2011 - 18:58:57)

DRAM:  254.5 MiB

在dram_init()函数中添加gd->ram_size初始化后,就能正常启动了,如下所示:

utu-bootloader=>>>go 33000000

## Starting application at 0x33000000 ...

U-Boot 2011.03 (Jun 12 2011 - 22:30:16)

DRAM:  64 MiB

Flash: 512 KiB

*** Warning - bad CRC, using default environment

In:    serial

Out:   serial

Err:   serial

Net:   raise: Signal # 8 caught

CS8900-0

[reille2440]#

至此,uboot移植工作至少完成了一部分工作了!如果有其他问题可以在include/configs/reille2440.h头文件中添加DEBUG宏用于调试。

5. 参考资料:

http://www.linuxidc.com/Linux/2011-02/32772p2.htm

原创粉丝点击