开发环境:主机: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. 配置和初步编译中介绍了如何配置和裁减u-boot-2.011.03,并通过了初步编译。在此基础上,本文通过修改reille2440.h文件、分析u-boot入口、修改start.S初始化代码段,利用tftp把编译出来的u-boot-2011.03镜像下载到SDRAM中,使其跑起来,可看到熟悉的u-boot启动信息。

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

» 文章出处: reille博客—http://velep.com , 如果没有特别声明,文章均为reille博客原创作品
» 郑重声明: 原创作品未经允许不得转载,如需转载请联系reille#qq.com(#换成@)
分享到:
推荐阅读相关文章:

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

  1. 虽然没有看懂,但是觉得好厉害的样子啊。

 Leave a Reply

(必须)

(我会替您保密的)(必须)

*

   
© 2012 velep.com | reille blog | 管理| 粤ICP备12094833号-2| 谷歌地图| 百度地图| Suffusion theme|Sayontan Sinha

无觅相关文章插件,快速提升流量