U-Boot移植

基于天翔的老师的课程, 他的博客在这儿:

http://blog.csdn.net/johnmcu/article/details/6561311

注明不能转载, 就重新写一下吧:

 

1. 安装韦东山的虚拟版的ubuntu 9, 里面交叉编译啥的都弄好了, 直接用, 然后把workstation共享目录打开, 指向uboot的压缩包所在目录.

2. 在虚拟机上, 打开ssh, 通过ssh, 进/mnt/hgfs/ 把uboot压缩包解压了.

 

3. 编辑Makefile, 在smdk2400下面增加两行, 注意要好tab键

smdk2400_config    :    unconfig
    @$(MKCONFIG) $(@:_config=) arm arm920t smdk2400 NULL s3c24x0

tx2440_config :         unconfig
    @$(MKCONFIG) $(@:_config=) arm arm920t tx2440 NULL s3c24x0

修改交叉编译命令如红色部分:

ifeq ($(ARCH),arm)
CROSS_COMPILE = arm-linux-

 

4. 把board目录下的除smdk2140目录其他全删了, 然后把smdk2140改名成tx2440

进去tx2440, 修改一下smdk2140.c改成tx2440.c

然后用vi, 修改board_init, 增加时钟的有关注释, 如下:

/* S3C2440: Mpll,Upll = (2*m * Fin) / (p * 2^s)
 * m = M (the value for divider M)+ 8, p = P (the value for divider P) + 2
 */
#define S3C2440_MPLL_400MHZ     ((0x7f<<12)|(0x02<<4)|(0x01))
#define S3C2440_UPLL_48MHZ      ((0x38<<12)|(0x02<<4)|(0x02))
#define S3C2440_CLKDIV          0x05    /* FCLK:HCLK:PCLK = 1:4:8 */
 
/* S3C2410: Mpll,Upll = (m * Fin) / (p * 2^s)
 * m = M (the value for divider M)+ 8, p = P (the value for divider P) + 2
 */

#define S3C2410_MPLL_200MHZ     ((0x5c<<12)|(0x04<<4)|(0x00))
#define S3C2410_UPLL_48MHZ      ((0x28<<12)|(0x01<<4)|(0x02))
#define S3C2410_CLKDIV          0x03    /* FCLK:HCLK:PCLK = 1:2:4 */

int board_init (void)
{
    S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
    S3C24X0_GPIO * const gpio = S3C24X0_GetBase_GPIO();
    /* set up the I/O ports */
    gpio->GPACON = 0x007FFFFF;
    gpio->GPBCON = 0x00044555;
    gpio->GPBUP = 0x000007FF;
    gpio->GPCCON = 0xAAAAAAAA;
    gpio->GPCUP = 0x0000FFFF;
    gpio->GPDCON = 0xAAAAAAAA;
    gpio->GPDUP = 0x0000FFFF;
    gpio->GPECON = 0xAAAAAAAA;
    gpio->GPEUP = 0x0000FFFF;
    gpio->GPFCON = 0x000055AA;
    gpio->GPFUP = 0x000000FF;
    gpio->GPGCON = 0xFF95FFBA;
    gpio->GPGUP = 0x0000FFFF;
    gpio->GPHCON = 0x002AFAAA;
    gpio->GPHUP = 0x000007FF;

    /*support both of S3C2410 and S3C2440*/
    if ((gpio->GSTATUS1 == 0x32410000) || (gpio->GSTATUS1 == 0x32410002))
    {
       /*FCLK:HCLK:PCLK = 1:2:4*/
       clk_power->CLKDIVN = S3C2410_CLKDIV;

       /* change to asynchronous bus mod */

        __asm__(    "mrc    p15, 0, r1, c1, c0, 0/n"    /* read ctrl register   */
                    "orr    r1, r1, #0xc0000000/n"      /* Asynchronous         */
                    "mcr    p15, 0, r1, c1, c0, 0/n"    /* write ctrl register  */
                    :::"r1"
                    );

        /* to reduce PLL lock time, adjust the LOCKTIME register */
        clk_power->LOCKTIME = 0xFFFFFF;
        /* configure MPLL */
        clk_power->MPLLCON = S3C2410_MPLL_200MHZ;
        /* some delay between MPLL and UPLL */
        delay (4000);
        /* configure UPLL */
        clk_power->UPLLCON = S3C2410_UPLL_48MHZ;
        /* some delay between MPLL and UPLL */
        delay (8000);
        /* arch number of SMDK2410-Board */

        gd->bd->bi_arch_number = MACH_TYPE_SMDK2410;
    }
    else
    {
       /* FCLK:HCLK:PCLK = 1:4:8 */
        clk_power->CLKDIVN = S3C2440_CLKDIV;
        /* change to asynchronous bus mod */
        __asm__(    "mrc    p15, 0, r1, c1, c0, 0/n"    /* read ctrl register   */
                    "orr    r1, r1, #0xc0000000/n"      /* Asynchronous         */
                    "mcr    p15, 0, r1, c1, c0, 0/n"    /* write ctrl register  */
                    :::"r1"
                    );

        /* to reduce PLL lock time, adjust the LOCKTIME register */
        clk_power->LOCKTIME = 0xFFFFFF;
        /* configure MPLL */
        clk_power->MPLLCON = S3C2440_MPLL_400MHZ;
        /* some delay between MPLL and UPLL */
        delay (4000);
        /* configure UPLL */
        clk_power->UPLLCON = S3C2440_UPLL_48MHZ;
        /* some delay between MPLL and UPLL */
        delay (8000);
        /* arch number of SMDK2440-Board */
        gd->bd->bi_arch_number = MACH_TYPE_S3C2440;
    }

    /* adress of boot parameters */
    gd->bd->bi_boot_params = 0x30000100;
    icache_enable();
    dcache_enable();
    return 0;
}

 

接着修改这个board/tx2440/下面的Makefile

把原来的smdk2410.o改成下面:

COBJS   := tx2440.o flash.o

 

5. 进include/configs/, 把其他的都删掉, 只把smdk2140.h改名为tx2440.h

6. 把cpu/arm920t/config.mk里面-msoft-float注释掉

PLATFORM_RELFLAGS += -fno-strict-aliasing  -fno-common -ffixed-r8
#       -msoft-float

 

7. 用make tx2440_config看看有否:

Configuring for tx2440 board...

 

8. 增加对sdram的支持, 确定board/tx2440/lowlevel_init.s内存映射如下:

#define B1_BWSCON          (DW32)
#define B2_BWSCON          (DW16)
#define B3_BWSCON          (DW16 + WAIT + UBLB)
#define B4_BWSCON          (DW16)
#define B5_BWSCON          (DW16)
#define B6_BWSCON          (DW32)
#define B7_BWSCON          (DW32)

并修改REFCNT为0x4f4

#define REFCNT             0x4f4    /* period=15.6us, HCLK=60Mhz, (2048+1-15.6*60) */

 

9. 修改cpu/arm920t/s3c24X0/speed.c

增加一行:

DECLARE_GLOBAL_DATA_PTR;

增加红色的部分:

static ulong get_PLLCLK(int pllreg)
{
    S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
    ulong r, m, p, s;

    if (pllreg == MPLL)
    r = clk_power->MPLLCON;
    else if (pllreg == UPLL)
    r = clk_power->UPLLCON;
    else
    hang();

    m = ((r & 0xFF000) >> 12) + 8;
    p = ((r & 0x003F0) >> 4) + 2;
    s = r & 0x3;

/* support both of S3C2410 and S3C2440 */

    if (gd->bd->bi_arch_number == MACH_TYPE_SMDK2410)
        return((CONFIG_SYS_CLK_FREQ * m) / (p << s));
    else
        return((CONFIG_SYS_CLK_FREQ * m * 2) / (p << s));   /* S3C2440 */

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

/* return FCLK frequency */
ulong get_FCLK(void)
{
    return(get_PLLCLK(MPLL));
}

 

同时增加下面的:


/* for s3c2440 */
#define S3C2440_CLKDIVN_PDIVN        (1<<0)
#define S3C2440_CLKDIVN_HDIVN_MASK   (3<<1)
#define S3C2440_CLKDIVN_HDIVN_1      (0<<1)
#define S3C2440_CLKDIVN_HDIVN_2      (1<<1)
#define S3C2440_CLKDIVN_HDIVN_4_8    (2<<1)
#define S3C2440_CLKDIVN_HDIVN_3_6    (3<<1)
#define S3C2440_CLKDIVN_UCLK         (1<<3)

#define S3C2440_CAMDIVN_CAMCLK_MASK  (0xf<<0)
#define S3C2440_CAMDIVN_CAMCLK_SEL   (1<<4)
#define S3C2440_CAMDIVN_HCLK3_HALF   (1<<8)
#define S3C2440_CAMDIVN_HCLK4_HALF   (1<<9)
#define S3C2440_CAMDIVN_DVSEN        (1<<12)


/* return HCLK frequency */

ulong get_HCLK(void)
{
    S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
    unsigned long clkdiv;
    unsigned long camdiv;
    int hdiv = 1;

    /* support both of S3C2410 and S3C2440 */
    if (gd->bd->bi_arch_number == MACH_TYPE_SMDK2410)
        return((clk_power->CLKDIVN & 0x2) ? get_FCLK()/2 : get_FCLK());
    else
    {
        clkdiv = clk_power->CLKDIVN;
        camdiv = clk_power->CAMDIVN;
        /* work out clock scalings */
        switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {
        case S3C2440_CLKDIVN_HDIVN_1:
            hdiv = 1;
            break;
 
        case S3C2440_CLKDIVN_HDIVN_2:
            hdiv = 2;
            break;

        case S3C2440_CLKDIVN_HDIVN_4_8:
            hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
            break;

        case S3C2440_CLKDIVN_HDIVN_3_6:
            hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
            break;
        }

        return get_FCLK() / hdiv;
    }
}

 

/* return PCLK frequency */

ulong get_PCLK(void)
{
    S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
    unsigned long clkdiv;
    unsigned long camdiv;
    int hdiv = 1;

    /* support both of S3C2410 and S3C2440 */

    if (gd->bd->bi_arch_number == MACH_TYPE_SMDK2410)
        return((clk_power->CLKDIVN & 0x1) ? get_HCLK()/2 : get_HCLK());
    else
    {  
        clkdiv = clk_power->CLKDIVN;
        camdiv = clk_power->CAMDIVN;

        /* work out clock scalings */

        switch (clkdiv & S3C2440_CLKDIVN_HDIVN_MASK) {

        case S3C2440_CLKDIVN_HDIVN_1:
            hdiv = 1;
            break;
 
        case S3C2440_CLKDIVN_HDIVN_2:
            hdiv = 2;
            break;

        case S3C2440_CLKDIVN_HDIVN_4_8:
            hdiv = (camdiv & S3C2440_CAMDIVN_HCLK4_HALF) ? 8 : 4;
            break;

        case S3C2440_CLKDIVN_HDIVN_3_6:
            hdiv = (camdiv & S3C2440_CAMDIVN_HCLK3_HALF) ? 6 : 3;
            break;
        }
        return get_FCLK() / hdiv / ((clkdiv & S3C2440_CLKDIVN_PDIVN)? 2:1);
    }      
}

下面的两个函数ulong get_HCLK(void);ulong get_PCLK(void); 删掉或者注释掉.

#if 0
/* return HCLK frequency */
ulong get_HCLK(void)
{
    S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
    return((clk_power->CLKDIVN & 0x2) ? get_FCLK()/2 : get_FCLK());
}

/* return PCLK frequency */
ulong get_PCLK(void)
{
    S3C24X0_CLOCK_POWER * const clk_power = S3C24X0_GetBase_CLOCK_POWER();
    return((clk_power->CLKDIVN & 0x1) ? get_HCLK()/2 : get_HCLK());
}

#endif

 

10. 记得把整个目录拷贝到非共享目录下编译,不然会出现错误:

ln: creating symbolic link `asm' to `asm-arm': Operation not supported

然后make tx2440_config, 出现

Configuring for tx2440 board...
然后make all

出现这个错误:

speed.c:137: error: structure has no member named `CAMDIVN'

修改include/s3c24x0.h

在S3C24X0_CLOCK_POWER结构体内增加:

S3C24X0_REG32   CAMDIVN;    /* for s3c2440*/

 

然后就可以make了, 奇怪的是, 只在/tmp里面能make....

生成了u-boot.bin文件, 拷贝到windows下面, 用easy openJtag烧录进去吧..

--------------------------

 

增加NandFlash的支持:

修改include/configs/tx2440.h

#define CONFIG_COMMANDS \
                        (CONFIG_CMD_DFL  | \
                        CFG_CMD_CACHE    | \
                        CFG_CMD_NAND     | \
                        /*CFG_CMD_EEPROM |*/ \
                        /*CFG_CMD_I2C    |*/ \
                        /*CFG_CMD_USB    |*/ \
                        CFG_CMD_REGINFO  | \
                        CFG_CMD_DATE     | \
                        CFG_CMD_ELF)

把CFG_CMD_NAND加进去, 然后在文件尾部增加:

/*NAND flash settings*/
#define CFG_NAND_BASE        0      //无实际意义:基地址,在board_nand_init中重新定义
#define CFG_MAX_NAND_DEVICE     1   //NAND Flash设备数目为1
#define NAND_MAX_CHIPS          1   //每个NAND设备由1个NADN芯片组成

这个时候编译, 出现一个错误:

/tmp/u-boot-1.1.6/drivers/nand/nand.c:50: undefined reference to `board_nand_init'
make: *** [u-boot] Error 1
board_nand_init函数未定义

首先在include/s3c24x0.h增加结构体:

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__))*/ S3C2440_NAND;

 

在include/s3c2410.h里面增加函数声明:

static inline S3C2440_NAND * const S3C2440_GetBase_NAND(void)
{
    return (S3C2440_NAND * const)S3C2410_NAND_BASE;
}

找到linux内核包, 把/drivers/mtd/nand/s3c2410.c 文件拷贝过来, 改名叫cpu/arm920t/s3c24x0/nand_flash.c

修改cpu/arm920t/s3c24x0/Makefile, 增加nand_flash.o

COBJS   = i2c.o interrupts.o serial.o speed.o \
          usb_ohci.o nand_flash.o

再编译make all

posted @ 2016-12-29 22:47  Montauk  阅读(289)  评论(0编辑  收藏  举报