uboot2009基本移植

(参考文章)

http://www.linuxidc.com/Linux/2011-05/35982.htm

移植环境

  1. 主机环境:VMareRHLE6 1G内存
  2. 编译编译环境:arm-linux-gcc v4.3.2
  3. 开发板:FL24404M nor flash: JS28F320J3D256M nand flash(k9f2g08)
  4. u-boot版本:u-boot-2009.08

目录结构

启动流程

移植步骤

  1. 建立fl2440开发板文件并编译测试

  2. 定位到board/samsung,将目录smdk2410复制并粘贴到board目录下,将其重命名为fl2440。
  3. 打开fl2440目录,将smdk2410.c重命名为fl2440.c
  4. 用vim打开当前目录下的Makefile,定位到28行,修改后代码如下所示(修改部分用灰色背景颜色标出):

    include $(TOPDIR)/config.mk
    LIB = $(obj)lib$(BOARD).a
    COBJS := fl2440.o flash.o 
    SOBJS := lowlevel_init.o
    然后保存。

  5. 在根目录下定位到include/configs,将smdk2410.h复制并粘贴到当前目录下,将其重命名成fl2440.h。
  6. 用vim打开根目录下的Makefile文件,然后搜索smdk2410,定位到2997行,找到下列语句

smdk2410_config : unconfig
 @$(MKCONFIG) $(@:_config=) arm arm920t fl2440 samsung s3c24x0

然后将其复制并粘贴到其下面,并修改成如下语句

fl2440_config : unconfig
 @$(MKCONFIG) $(@:_config=) arm arm920t fl2440 NULL s3c24x0

然后保存。
*说明

   arm    :CPU的架构(ARCH)
   arm920t:CPU的类型
   fl2440 :对应在board目录下建立新的开发板项目的目录
  NULL:新开发板项目目录的上级目录,如直接在board下建立新的开发板项目的目录,
则这里就为NULL
   s3c24x0:CPU型号
*注意:编译选项格式的第二行要用Tab键开始,否则编译会出错。

  1. 编译测试

打开终端,进入到u-boot-2009.08根目录下执行

[root@localhost u-boot-2009.08]# make distclean
[root@localhost u-boot-2009.08]# make fl2440_config
Configuring for fl2440 board...
[root@localhost u-boot-2009.08]# make

打开cpu/arm920t/start.S,搜索"coloured_LED_init"定位到117行,找到如下代码:

 bl coloured_LED_init
 bl red_LED_on

将其注释掉

//这两行是AT91RM9200DK开发板的LED初始化,注释掉

//bl coloured_LED_init
 //bl red_LED_on

然后执行清除、编译命令

[root@localhost u-boot-2009.08]# make clean

[root@localhost u-boot-2009.08]# make

... ...

arm-linux-objcopy -O srec u-boot u-boot.srec
arm-linux-objcopy --gap-fill=0xff -O binary u-boot u-boot.bin
[root@localhost u-boot-2009.08]# 
编译通过。

  1. 加入调试选项,启用DEBUG宏,有两种办法办法

<1>参考文章Makefile,如何传递宏定义DEBUG和Debug版和Release版的程序

在编译时,直接在make 后面传入参数 -d ,表示Debug模式,输出有关文件和检测时间的详细信息,如

make -d

可以输出源程序中定义的DEBUG宏定义的调试信息

<2>用vim打开根目录下的config.mk文件,然后搜索"DDEBUG",找到如下语句

DBGFLAGS= -g # -DDEBUG

将注释掉的DDEBUG选项打开,修改后下面语句

DBGFLAGS= -g  -DDEBUG

但是此种办法需要在调试完成时需要在将其注释掉。

  1. 根据启动流程修改或添加基本的u-boot源码,使其能够在内存中启动

    1. 增加对S3C2440一些寄存器的支持,添加中断禁止部分和时钟设置部分

用vim打开cpu/arm920t/start.S,定位到134行附近,如下代码

#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)
 /* turn off the watchdog */

由于2410和2440的寄存器及地址大部分是一致的,所以这里就直接在2410的基础上再加上对2440的支持即可,修改后代码如下:

#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
 /* turn off the watchdog */

 ... ...

# if defined(CONFIG_S3C2410)

ldr r1, =0x3ff

ldr r0, =INTSUBMSK

str r1, [r0]

# endif

# if defined(CONFIG_S3C2440)//添加s3c2440的中断禁止部分

ldr r1, =0x7fff //根据2440芯片手册,INTSUBMSK寄存器有15位可用

ldr r0, =INTSUBMSK

str r1, [r0]

# endif

# if defined(CONFIG_S3C2440) //添加s3c2440的时钟部分

#define MPLLCON 0x4C000004 //系统主频配置寄存器基地址

#define UPLLCON 0x4C000008 //USB时钟频率配置寄存器基地址

ldr r0, =CLKDIVN //设置分频系数FCLK:HCLK:PCLK = 1:4:8

mov r1, #5

str r1, [r0]

ldr r0, =MPLLCON //设置系统主频为405MHz

ldr r1, =0x7F021 //这个值参考芯片手册"PLL VALUE SELECTION TABLE"部分

str r1, [r0]

ldr r0, =UPLLCON //设置USB时钟频率为48MHz

ldr r1, =0x38022 //这个值参考芯片手册"PLL VALUE SELECTION TABLE"部分

str r1, [r0]

# else //其他开发板的时钟部分

/* FCLK:HCLK:PCLK = 1:2:4 */

/* default FCLK is 202.8 MHz ! */

ldr r0, =CLKDIVN

mov r1, #3

str r1, [r0]

ldr r0, =MPLLCON //设置系统主频为202.8MHz

ldr r1, =0xa1031 //这个值参考芯片手册"PLL VALUE SELECTION TABLE"部分

str r1, [r0]

#endif

#endif /* CONFIG_S3C2400 || CONFIG_S3C2410 || CONFIG_S3C2440 */

  1. S3C2440的时钟部分除了在start.S中添加外,还要在board /fl2440/fl2440.c和cpu/arm920t/s3c24x0/speed.c中修改或添加部分代码

  1. 用vim打开board/fl2440/fl2440.c,定位到33行,修改或添加如下内容:

//设置主频和USB时钟频率参数与start.S中的一致

#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 /* Fout = 405MHz */

#define M_MDIV 0x7F //这三个值根据S3C2440芯片手册"PLL VALUE SELECTION TABLE"部分进行设置

#define M_PDIV 0x2

#define M_SDIV 0x1

#endif

 

#define USB_CLOCK 2 //设置默认等于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 //这三个值根据S3C2440芯片手册"PLL VALUE SELECTION TABLE"部分进行设置

#define U_M_PDIV 0x2

#define U_M_SDIV 0x2

#endif

  1. 用vim打开cpu/arm920t/s3c24x0/speed.c,定位到69行加入如下代码

  m = ((r & 0xFF000) >> 12) + 8;

p = ((r & 0x003F0) >> 4) + 2;

s = r & 0x3;

//根据设置的分频系数FCLK:HCLK:PCLK = 1:4:8修改获取时钟频率的函数

#if defined(CONFIG_S3C2440)

if(pllreg == MPLL)//参考S3C2440芯片手册上的公式:PLL=(2 * m * Fin)/(p * 2s)

return((CONFIG_SYS_CLK_FREQ * m * 2) / (p << s));

//else if (pllreg == UPLL) //warning: control reaches end of non-void function

#endif

return((CONFIG_SYS_CLK_FREQ * m) / (p << s));

 

为什么要再返回时加一个判断呢?因为在2440中MPLL的时钟为UPLL时钟的2倍,在s3c2440的数据手册里的227页这样写到MPLL和UPLL的计算方法

MPLL Control Register

Mpll = (2 * m * Fin) / (p * 2s)

m = (MDIV + 8), p = (PDIV + 2), s = SDIV

UPLL Control Register

Upll = (m * Fin) / (p * 2s)

m = (MDIV + 8), p = (PDIV + 2), s = SDIV

这个就是修改此函数的缘由。

由于S3C2410和S3C2440的设置方法也不一样,所以get_HCLK函数也需要修改:

/* return HCLK frequency */
ulong get_HCLK(void)

{

S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();

#if defined(CONFIG_S3C2440)

if (clk_power->CLKDIVN & 0x6)

{

if ((clk_power->CLKDIVN & 0x6)==2) return(get_FCLK()/2);

if ((clk_power->CLKDIVN & 0x6)==6) return((clk_power->CAMDIVN & 0x100) ? get_FCLK()/6 : get_FCLK()/3);

if ((clk_power->CLKDIVN & 0x6)==4) return((clk_power->CAMDIVN & 0x200) ? get_FCLK()/8 : get_FCLK()/4);

return(get_FCLK());

}

else return(get_FCLK());

#else

return((clk_power->CLKDIVN & 0x2) ? get_FCLK()/2 : get_FCLK());

#endif

}

这里用到了将在include/s3c24x0.h文件里所添加的CAMDIVN 项,因为这一项的值决定了我们的时钟配置。这样修改的原因是在s3c2440的数据手册的231页有这样一段话:

我们到底应该返回FCLK的几分之一在这里就有秒数,其中必须根据HDIVN 的值与CAMDIVN的值来判断。

2.3.对于S3C2440,很多代码是借用S3C2410 的,所以要在所有条件编译中有CONFIG_S3C2410 的地方添CONFIG_S3C2440,这样这些代码才会编译进来。一个简单的方法就是在代码中搜索出所有的CONFIG_S3C2410,并根据实际情况修改。但要注意不是所有的2410的寄存器都和2440兼容,还必须根据两个芯片的不同来分布做出修改,比如PLL的操作代码和NAND Flash Controller的操作代码。现分别修改如下:

  1. 打开include/common.h,定位到496行,修改结果如下

#ifdef CONFIG_4xx
ulong get_OPB_freq (void);
ulong get_PCI_freq (void);
#endif
#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) ||  defined(CONFIG_S3C2440) || \
 defined(CONFIG_LH7A40X) || defined(CONFIG_S3C6400)
ulong get_FCLK (void);
ulong get_HCLK (void);

  1. 打开include/s3c24x0.h文件,分别定位到85、95、99、110、148、404行,将"#ifdef CONFIG_S3C2410"改为

#if defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440) 

然后在下面结构中加入2440 的NAND FLASH 的数据结构成员CAMDIVN定义(第128行附近):

/* CLOCK & POWER MANAGEMENT (see S3C2400 manual chapter 6) */
/* (see S3C2410 manual chapter 7) */
typedef struct {
 S3C24X0_REG32 LOCKTIME;
 S3C24X0_REG32 MPLLCON;
 S3C24X0_REG32 UPLLCON;
 S3C24X0_REG32 CLKCON;
 S3C24X0_REG32 CLKSLOW;
 S3C24X0_REG32 CLKDIVN;
#if defined (CONFIG_S3C2440)
  S3C24X0_REG32 CAMDIVN;
#endif

} /*__attribute__((__packed__))*/ S3C24X0_CLOCK_POWER;

这个结构是用来封装时钟寄存器的,我们要在其中增加一项CAMDIVN寄存器是2410所没有的,而2440在配置时钟的时候又必须用到,看名字我们就知道是用来配置CAMERA时钟的,也就是配置摄像头的时钟的。

加入Nand flash寄存器定义(第160行附近):
#if defined(CONFIG_S3C2410)
/* NAND FLASH (see S3C2410 manual chapter 6) */
typedef struct {
 S3C24X0_REG32 NFCONF;
 S3C24X0_REG32 NFCMD;
 S3C24X0_REG32 NFADDR;
 S3C24X0_REG32 NFDATA;
 S3C24X0_REG32 NFSTAT;
 S3C24X0_REG32 NFECC;
} /*__attribute__((__packed__))*/ S3C2410_NAND;
#endif
#if defined (CONFIG_S3C2440)
/* NAND FLASH (see S3C2440 manual chapter 6) */
typedef struct {
        S3C24X0_REG32   NFCONF;
        S3C24X0_REG32   NFCONT;
        S3C24X0_REG32   NFCMD;
        S3C24X0_REG32   NFADDR;
        S3C24X0_REG32   NFDATA;
        S3C24X0_REG32   NFMECCD0;
        S3C24X0_REG32   NFMECCD1;
        S3C24X0_REG32   NFSECCD;
        S3C24X0_REG32   NFSTAT;
        S3C24X0_REG32   NFESTAT0;
        S3C24X0_REG32   NFESTAT1;
        S3C24X0_REG32   NFMECC0;
        S3C24X0_REG32   NFMECC1;
        S3C24X0_REG32   NFSECC;
        S3C24X0_REG32   NFSBLK;
        S3C24X0_REG32   NFEBLK;
} /*__attribute__((__packed__))*/ S3C2410_NAND;
#endif

  1. 打开cpu/arm920t/s3c24x0/interrupts.c文件,定位到第36行作如下修改:
    #if defined(CONFIG_S3C2400)
    #include <s3c2400.h>
    #elif defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440)
    #include <s3c2410.h>
    #endif
  2. 打开cpu/arm920t/s3c24x0/timer.c文件分别定位到33行和37行,修改如下:
    #include <common.h>
    #if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) || defined(CONFIG_TRAB)
    #if defined(CONFIG_S3C2400)
    #include <s3c2400.h>
    #elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
    #include <s3c2410.h>
    #endif
    在180行添加:
    #if defined(CONFIG_SMDK2400) || defined(CONFIG_TRAB)
     tbclk = timer_load_val * 100;
    #elif defined(CONFIG_SBC2410X) || \
          defined(CONFIG_SMDK2410) || \
          defined(CONFIG_FL2440) || \
         
    defined(CONFIG_VCMA9)
     
    tbclk = CONFIG_SYS_HZ;

    #else

    # error "tbclk not configured"

    #endif
  3. 打开cpu/arm920t/s3c24x0/speed.c,分别定位到33行和37行,修改如下:
    #include <common.h>
    #if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440) || defined(CONFIG_TRAB)
    #if defined(CONFIG_S3C2400)
    #include <s3c2400.h>
    #elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
    #include <s3c2410.h>
    #endif
  4. 打开/cpu/arm920t/s3c24x0/usb.c文件,定位到第27、31行:
    #if defined(CONFIG_USB_OHCI_NEW) && defined(CONFIG_SYS_USB_OHCI_CPU_INIT)
    # if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
    #if defined(CONFIG_S3C2400)
    # include <s3c2400.h>
    #elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
    # include <s3c2410.h>
    #endif
  5. 打开drivers/serial/serial_s3c24x0.c,定位到24行,修改如下:
    #include <common.h>
    #if defined(CONFIG_S3C2400) || defined(CONFIG_TRAB)
    #include <s3c2400.h>
    #elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
    #include <s3c2410.h>
    #endif
  6. 打开drivers/rtc/s3c24x0_rtc.c文件,定位到第35行:
    #if defined(CONFIG_S3C2400)
    #include <s3c2400.h>
    #elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
    #include <s3c2410.h>
    #endif
  7. 打开/drivers/i2c/s3c24x0_i2c.c文件,定位到32行:
    #include <common.h>
    #if defined(CONFIG_S3C2400)
    #include <s3c2400.h>
    #elif defined(CONFIG_S3C2410) || defined(CONFIG_S3C2440)
    #include <s3c2410.h>
    #endif
    #include <i2c.h>

    分别定位到第63、82、139、147、171行:
    #if defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440) //#ifdef CONFIG_S3C2410
     return (gpio->GPEDAT & 0x8000) >> 15;
    #endif
    ... ...
    #if defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440) //#ifdef CONFIG_S3C2410
     gpio->GPEDAT = (gpio->GPEDAT & ~0x4000) | (x&1) << 14;
    #endif
    ... ...
    #if defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440) //#ifdef CONFIG_S3C2410
      /* set I2CSDA and I2CSCL (GPE15, GPE14) to GPIO */
      gpio->GPECON = (gpio->GPECON & ~0xF0000000) | 0x10000000;
    #endif
    ... ...
      /* restore pin functions */
    #if defined(CONFIG_S3C2410) || defined (CONFIG_S3C2440) //#ifdef CONFIG_S3C2410
      gpio->GPECON = old_gpecon;
    #endif

2.4. 在fl2440.h头文件中加入宏定义

用vim打开include/configs/fl2440.h头文件,在其中添加CONFIG_S3C2440宏,修改后代码如下所示

#define CONFIG_ARM920T  1 /* This is an ARM920T Core */
#define CONFIG_S3C2440  1 /* in a SAMSUNG S3C2440 SoC     */
#define CONFIG_FL2440  1 /* on a FL2440 Board  */
#define CONFIG_FL2440_LED 1  /* fl2440 led on/off */

/* input clock of PLL */
#define CONFIG_SYS_CLK_FREQ 12000000/* the SMDK2410 has 12MHz input clock */

  1. 为了能够让u-boot.bin下载到内存中运行,需要注释掉CPU和DRAM初始化部分

vim打开cpu/arm920t/start.S,定位到如下代码

#ifndef CONFIG_SKIP_LOWLEVEL_INIT
 bl cpu_init_crit
#endif

将其注释掉,屏蔽u-boot对CPU、RAM的初始化

//#ifndef CONFIG_SKIP_LOWLEVEL_INIT
 //bl cpu_init_crit
//#endif

  1. 重新编译,运行测试

[root@localhost u-boot-2009.08]# make clean
Generating include/autoconf.mk
[root@localhost u-boot-2009.08]# make

... ...
编译完成之后,利用fl2440自带的supervivi将根目录u-boot-2009.08下的u-boot.bin文件下载到DRAM中运行测试。确认开发板与主机之间的网线和串口线已经正确连接,给开发板上电,在suppervivi启动完成后,在与开发板相连的终端中执行如下命令

+------------------------------------------------------------+

| Select Menu |

+------------------------------------------------------------+

| [0] Download & Run      |

| [1] Download to flash          |

| [2] Download From UART      |

| [3] Boot My Application          |

| [4] Boot Linux      |

| [5] Boot Wince |

| [6] Erase Flash Partition |

| [7] Config parameters |

+------------------------------------------------------------+

Enter your selection: 0
Clear the free memory
USB host is connected. Waiting a download.

Now, Downloading [ADDRESS:31000000h,TOTAL:99806]
RECEIVED FILE SIZE:   99806 (97KB/S, 1S)
Downloaded file at 0x30000000, size = 99796 bytes


U-Boot 2009.08 ( 5鏈?04 2011 - 17:04:11)

DRAM:  64 MB
Flash: 512 kB
*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
SMDK2410 #

到此可以看到u-boot的版本和编译时间-Boot 2009.08 (2011 - 17:04:11),以及还未修改的提示符SMDK2410 #。同时还可以看到开发板上的第一个LED灯是亮的,其它三个是灭的。有关Warning ...相关的告警信息,将在下一节解决。

接下来将进入u-boot的第二阶段,为u-boot-2009.08增加norflash支持。

posted on 2012-11-23 13:39  WithYouTh  阅读(363)  评论(0编辑  收藏  举报