开发环境:

开发板 FriendlyARM Tiny6410

主机 CentOS release 6.4 Final

参考:

http://www.cnblogs.com/plinx/archive/2013/03/15/2960925.html

http://www.cnblogs.com/plinx/archive/2013/04/11/2963823.html

http://www.cnblogs.com/plinx/archive/2013/04/13/3015851.html

http://wenku.baidu.com/view/a4d3f5320b4c2e3f572763d5.html

u-boot2010.03版本最接近三星定制的s3c-u-boot-1.1.6版本,所以选此版本尝试移植。对于arm11架构的芯片,u-boot-2010.03仅支持6400,我们可以复制并修改6400的相关文件,使u-boot支持6410

1.获得源码

http://ftp.denx.de/pub/u-boot/下载u-boot-2010.03.tar.bz2,解压。

2.首次编译

u-boot根目录配置并编译

 

make smdk6400_config 
make

 

编译成功,在u-boot根目录下生成的u-boot.bin即为u-boot镜像。

3.文件添加

 

make clean

 

3.1board目录

 

cd board/samsung/
mkdir smdk6410
cp smdk6400/* smdk6410/
cd smdk6410
mv smdk6400.c smdk6410.c

 

将目录下所有文件中的。

查找board/samsung/smdk6410目录下含有“6400”的文件,将这些文件中的“6400”替换成“6410”vim下的替换命令是“:%s/6400/6410/g”

 

[root@tanghuimin smdk6410]# find . -name "*" | xargs grep "6400"
./Makefile:COBJS-y    := smdk6400.o
./lowlevel_init.S:#include <asm/arch/s3c6400.h>
./lowlevel_init.S:    /* r1 = physical address of s3c6400_cpu_resume function */
./lowlevel_init.S:    /* Jump to kernel (sleep-s3c6400.S) */
./lowlevel_init.S:     * seem to make much sense on S3C6400.
./lowlevel_init.S:#ifndef CONFIG_S3C6400
./lowlevel_init.S:#elif !defined(CONFIG_S3C6400)
./lowlevel_init.S:    /* According to 661558um_S3C6400X_rev10.pdf 0x20 is reserved */
./lowlevel_init.S: * NAND Interface init for SMDK6400
./lowlevel_init.S: * MMU Table for SMDK6400
./config.mk:# SAMSUNG SMDK6400 board with mDirac3 (ARM1176) cpu
./config.mk:# On SMDK6400 we use the 64 MB SDRAM bank at
./smdk6410.c:#include <asm/arch/s3c6400.h>
./smdk6410.c:    printf("Board:   SMDK6400\n");
./smdk6410.c:ulong virt_to_phy_smdk6400(ulong addr)
[root@tanghuimin smdk6410]# 

 

3.2)cpu目录

查找cpu/arm1176目录下含有“6400”的文件,将这些文件中的“6400”替换成“6410”vim下的替换命令是“:%s/6400/6410/g”

 

[root@tanghuimin arm1176]# pwd
/home/thm/u-boot/u-boot-2010.03/cpu/arm1176
[root@tanghuimin arm1176]# 
[root@tanghuimin arm1176]# find . -name "*" | xargs grep "6400"
./s3c64xx/Makefile:COBJS-$(CONFIG_S3C6400)    += cpu_init.o speed.o
./s3c64xx/timer.c:#include <asm/arch/s3c6400.h>
./s3c64xx/speed.c:#include <asm/arch/s3c6400.h>
./s3c64xx/speed.c:     * Bit 7 exists on s3c6410, and not on s3c6400, it is reserved on
./s3c64xx/speed.c:     * s3c6400 and is always 0, and it is indeed running in ASYNC mode
./s3c64xx/speed.c:    printf("\nCPU:     S3C6400@%luMHz\n", get_ARMCLK() / 1000000);
./s3c64xx/reset.S:#include <asm/arch/s3c6400.h>
./s3c64xx/cpu_init.S: * Originates from Samsung's u-boot 1.1.6 port to S3C6400 / SMDK6400
./s3c64xx/cpu_init.S:#include <asm/arch/s3c6400.h>
./.depend: /home/thm/u-boot/u-boot-2010.03/include/configs/smdk6400.h \
./.depend: /home/thm/u-boot/u-boot-2010.03/include/asm/arch/s3c6400.h \
./.depend: /home/thm/u-boot/u-boot-2010.03/include/configs/smdk6400.h \
./.depend: /home/thm/u-boot/u-boot-2010.03/include/asm/arch/s3c6400.h \
./start.S: *  armboot - Startup Code for S3C6400/ARM1176 CPU-core
./start.S:#include <asm/arch/s3c6400.h>
./cpu.c:#include <asm/arch/s3c6400.h>

 

3.3)nand_spl目录

 

cd nand_spl/board/samsung/
mkdir smdk6410
cp smdk6400/* smdk6410/
cd smdk6410

 

查找nand_spl/board/samsung/smdk6410目录下含有“6400”的文件,将这些文件中的“6400”替换成“6410”vim下的替换命令是“:%s/6400/6410/g”

 

[root@tanghuimin smdk6410]# pwd
/home/thm/u-boot/u-boot-2010.03/nand_spl/board/samsung/smdk6410
[root@tanghuimin smdk6410]# 
[root@tanghuimin smdk6410]# find . -name "*"| xargs grep "6400"
./Makefile:    @ln -s $(TOPDIR)/board/samsung/smdk6400/lowlevel_init.S $@
./lowlevel_init.S:#include <asm/arch/s3c6400.h>
./lowlevel_init.S:    /* r1 = physical address of s3c6400_cpu_resume function */
./lowlevel_init.S:    /* Jump to kernel (sleep-s3c6400.S) */
./lowlevel_init.S:     * seem to make much sense on S3C6400.
./lowlevel_init.S:#ifndef CONFIG_S3C6400
./lowlevel_init.S:#elif !defined(CONFIG_S3C6400)
./lowlevel_init.S:    /* According to 661558um_S3C6400X_rev10.pdf 0x20 is reserved */
./lowlevel_init.S: * NAND Interface init for SMDK6400
./lowlevel_init.S: * MMU Table for SMDK6400
./s3c64xx.c:#include <asm/arch/s3c6400.h>
./config.mk:# Samsung S3C64xx Reference Platform (smdk6400) board
[root@tanghuimin smdk6410]# 

 

3.4)添加头文件smdk6410.h

cd include/configs
cp smdk6400.h smdk6410.h
vim smdk6410.h
:%s/6400/6410/g

3.5)添加头文件s3c6410.h

cd include/asm-arm/arch-s3c64xx/
cp s3c6400.h s3c6410.h
vim s3c6410.h
:%s/6400/6410/g

并且修改

 

#include "s3c64x0.h"

 

#include "./asm/arch/s3c64x0.h"

3.6)修改根目录下mkconfig

if [ "$2" = "arm" ] ; then
    rm -f asm-$2/proc
    ln -s ${LNPREFIX}proc-armv asm-$2/proc
fi

if [ "$1" = "smdk6410" ]; then
    rm -f regs.h
    ln -s asm-$2/arch/s3c6410.h regs.h
fi

3.7)修改根目录下Makefile

搜索6400可以看到smdk6400的配置项,复制smdk6400的配置项并把6400改为6410

 

#########################################################################
## ARM1176 Systems
#########################################################################
smdk6400_noUSB_config    \
smdk6400_config    :    unconfig
    @mkdir -p $(obj)include $(obj)board/samsung/smdk6400
    @mkdir -p $(obj)nand_spl/board/samsung/smdk6400
    @echo "#define CONFIG_NAND_U_BOOT" > $(obj)include/config.h
    @if [ -z "$(findstring smdk6400_noUSB_config,$@)" ]; then            \
        echo "RAM_TEXT = 0x57e00000" >> $(obj)board/samsung/smdk6400/config.tmp;\
        $(MKCONFIG) $(@:_config=) arm arm1176 smdk6400 samsung s3c64xx;        \
    else                                        \
        echo "RAM_TEXT = 0xc7e00000" >> $(obj)board/samsung/smdk6400/config.tmp;\
        $(MKCONFIG) $(@:_noUSB_config=) arm arm1176 smdk6400 samsung s3c64xx;    \
    fi
    @echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk

smdk6410_noUSB_config    \
smdk6410_config    :    unconfig
    @mkdir -p $(obj)include $(obj)board/samsung/smdk6410
    @mkdir -p $(obj)nand_spl/board/samsung/smdk6410
    @echo "#define CONFIG_NAND_U_BOOT" > $(obj)include/config.h
    @if [ -z "$(findstring smdk6410_noUSB_config,$@)" ]; then            \
        echo "RAM_TEXT = 0x57e00000" >> $(obj)board/samsung/smdk6410/config.tmp;\
        $(MKCONFIG) $(@:_config=) arm arm1176 smdk6410 samsung s3c64xx;        \
    else                                        \
        echo "RAM_TEXT = 0xc7e00000" >> $(obj)board/samsung/smdk6410/config.tmp;\
        $(MKCONFIG) $(@:_noUSB_config=) arm arm1176 smdk6410 samsung s3c64xx;    \
    fi
    @echo "CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk

 

3.8)配置编译

 

make smdk6410_config
make

 

可以编译成功。

4.文件修改

4.1)cpu/arm1176/start.S

4.1.1)将如下红色代码段注释掉,添加“mcr p15,0,r0,c1,c0,0”

 

#ifndef CONFIG_NAND_SPL 
        /* 
         * flush v4 I/D caches 
         */ 
        mov     r0, #0 
        mcr     p15, 0, r0, c7, c7, 0   /* flush v3/v4 cache */ 
        mcr     p15, 0, r0, c8, c7, 0   /* flush v4 TLB */ 

        /* 
         * disable MMU stuff and caches 
         */ 
        mrc     p15, 0, r0, c1, c0, 0 
        bic     r0, r0, #0x00002300     @ clear bits 13, 9:8 (--V- --RS) 
        bic     r0, r0, #0x00000087     @ clear bits 7, 2:0 (B--- -CAM) 
        orr     r0, r0, #0x00000002     @ set bit 2 (A) Align 
        orr     r0, r0, #0x00001000     @ set bit 12 (I) I-Cache 

        /* Prepare to disable the MMU */ 
        adr     r1, mmu_disable_phys 

        /* We presume we're within the first 1024 bytes */ 
        and     r1, r1, #0x3fc 
        ldr     r2, _TEXT_PHY_BASE 
        ldr     r3, =0xfff00000 
        and     r2, r2, r3 
        orr     r2, r2, r1 
        b       mmu_disable 

        .align 5 

        /* Run in a single cache-line */ 

mmu_disable: 
        mcr     p15, 0, r0, c1, c0, 0 
        nop 
        nop 
        mov     pc, r2 

#endif 

 

修改后的代码如下:

 

#ifndef CONFIG_NAND_SPL 
        /* 
         * flush v4 I/D caches 
         */ 
        mov     r0, #0 
        mcr     p15, 0, r0, c7, c7, 0   /* flush v3/v4 cache */ 
        mcr     p15, 0, r0, c8, c7, 0   /* flush v4 TLB */ 

        /* 
         * disable MMU stuff and caches 
         */ 
        mrc     p15, 0, r0, c1, c0, 0 
        bic     r0, r0, #0x00002300     @ clear bits 13, 9:8 (--V- --RS) 
        bic     r0, r0, #0x00000087     @ clear bits 7, 2:0 (B--- -CAM) 
        orr     r0, r0, #0x00000002     @ set bit 2 (A) Align 
        orr     r0, r0, #0x00001000     @ set bit 12 (I) I-Cache 

        mcr     p15, 0, r0, c1, c0, 0 
#if 0 
        /* Prepare to disable the MMU */ 
        adr     r1, mmu_disable_phys 

        /* We presume we're within the first 1024 bytes */ 
        and     r1, r1, #0x3fc 
        ldr     r2, _TEXT_PHY_BASE 
        ldr     r3, =0xfff00000 
        and     r2, r2, r3 
        orr     r2, r2, r1 
        b       mmu_disable 

        .align 5 

        /* Run in a single cache-line */ 

mmu_disable: 
        mcr     p15, 0, r0, c1, c0, 0 
        nop 
        nop 
        mov     pc, r2 
#endif 

#endif 

 

4.1.2)查找“lowlevel_init”,在其下添加

 

 /* when we already run in ram, we don't need to relocate U-Boot. 
         * and actually, memory controller must be configured before U-Boot 
         * is running in ram. 
         */ 
        ldr     r0, =0xff000fff 
        bic     r1, pc, r0              /* r0 <- current base addr of code */ 
        ldr     r2, _TEXT_PHY_BASE      /* r1 <- original base addr in ram */ 
        bic     r2, r2, r0              /* r0 <- current base addr of code */ 
        cmp     r1, r2                  /* compare r0, r1                  */ 
        beq     after_copy 

#ifdef CONFIG_BOOT_NAND 
        mov     r0, #0x1000 
        bl      copy_from_nand 
#endif

 

4.1.3)查找

 

#ifdef CONFIG_ENABLE_MMU 
_mmu_table_base: 
        .word mmu_table 
#endif

 

在其下添加

 

/* 
 * copy U-Boot to SDRAM and jump to ram (from NAND or OneNAND) 
 * r0: size to be compared 
 * Load 1'st 2blocks to RAM because U-boot's size is larger than 1block(128k) size 
 */ 
        .globl copy_from_nand 
copy_from_nand: 
        mov     r10, lr         /* save return address */ 

        mov     r9, r0 
        /* get ready to call C functions */ 
        ldr     sp, _TEXT_PHY_BASE      /* setup temp stack pointer */ 
        sub     sp, sp, #12 
        mov     fp, #0                  /* no previous frame, so fp=0 */ 
        mov     r9, #0x1000 
        bl      copy_uboot_to_ram 

3:      tst     r0, #0x0 
        bne     copy_failed 

        ldr     r0, =0x0c000000 
        ldr     r1, _TEXT_PHY_BASE 
1:      ldr     r3, [r0], #4 
        ldr     r4, [r1], #4 
        teq     r3, r4 
        bne     compare_failed  /* not matched */ 
        subs    r9, r9, #4 
        bne     1b 

4:      mov     lr, r10         /* all is OK */ 
        mov     pc, lr 

copy_failed: 
        nop                     /* copy from nand failed */ 
        b       copy_failed 

compare_failed: 
        nop                     /* compare failed */ 
        b       compare_failed

 

4.2)在cpu/arm1176下添加nand_cp.c

/*
 * $Id: nand_cp.c,v 1.4 2008/04/08 00:41:40 jsgood Exp $
 *
 * (C) Copyright 2006 Samsung Electronics
 *
 * See file CREDITS for list of people who contributed to this
 * project.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

/*
 * You must make sure that all functions in this file are designed
 * to load only U-Boot image.
 *
 * So, DO NOT USE in common read.
 *
 * By scsuh.
 */


#include <common.h>
#include <asm/io.h>
#include <linux/mtd/nand.h>
#include <regs.h>

#define NF8_ReadPage(a,b,c)    (((int(*)(uint, uint, uchar *))(*((uint *)(0x0c004000))))(a,b,c))
#define NF8_ReadPage_Adv(a,b,c)    (((int(*)(uint, uint, uchar *))(*((uint *)(0x0c004004))))(a,b,c))

void nand_bl2_copy(void)
{
    int block, page;
    volatile uint *base = (uint *) 0x57e00000;

    for (block = 0; block < 16; block++) {
        for (page = 0; page < 32; page++) {
            NF8_ReadPage(block, page, (uchar *)base);
            base += (512 / (sizeof(uint)));
        }
    }
}

void nand_bl2_copy_adv(void)
{
    int block, page;
    volatile uint *base = (uint *) 0x57e00000;

    for (block = 0; block < 2; block++) {
        for (page = 0; page < 128; page++) {
            NF8_ReadPage_Adv(block, page, (uchar *) base);
            base += (2048 / (sizeof(uint)));
        }
    }
}

/*
 * address format
 *              17 16         9 8            0
 * --------------------------------------------
 * | block(12bit) | page(5bit) | offset(9bit) |
 * --------------------------------------------
 */

static int nandll_read_page (uchar *buf, ulong addr, int large_block)
{
        int i;
    int page_size = 512;

    if (large_block)
        page_size = 2048;

        NAND_ENABLE_CE();

        NFCMD_REG = NAND_CMD_READ0;

        /* Write Address */
        NFADDR_REG = 0;

    if (large_block)
            NFADDR_REG = 0;

    NFADDR_REG = (addr) & 0xff;
    NFADDR_REG = (addr >> 8) & 0xff;
    NFADDR_REG = (addr >> 16) & 0xff;

    if (large_block)
        NFCMD_REG = NAND_CMD_READSTART;

        NF_TRANSRnB();

    /* for compatibility(2460). u32 cannot be used. by scsuh */
    for(i=0; i < page_size; i++) {
                *buf++ = NFDATA8_REG;
        }

        NAND_DISABLE_CE();
        return 0;
}

/*
 * Read data from NAND.
 */
static int nandll_read_blocks (ulong dst_addr, ulong size, int large_block)
{
        uchar *buf = (uchar *)dst_addr;
        int i;
    uint page_shift = 9;

    if (large_block)
        page_shift = 11;

        /* Read pages */
        for (i = 0; i < (0x3c000>>page_shift); i++, buf+=(1<<page_shift)) {
                nandll_read_page(buf, i, large_block);
        }

        return 0;
}

int copy_uboot_to_ram (void)
{
    int large_block = 0;
    int i;
    vu_char id;
    
        NAND_ENABLE_CE();
        NFCMD_REG = NAND_CMD_READID;
        NFADDR_REG =  0x00;

    /* wait for a while */
        for (i=0; i<200; i++);
    id = NFDATA8_REG;
    id = NFDATA8_REG;

    if (id > 0x80)
        large_block = 1;

    /* read NAND Block.
     * 128KB ->240KB because of U-Boot size increase. by scsuh
     * So, read 0x3c000 bytes not 0x20000(128KB).
     */
    return nandll_read_blocks(CFG_PHY_UBOOT_BASE, 0x3c000, large_block);
}
View Code

相关文章:

  • 2022-12-23
  • 2022-12-23
  • 2022-12-23
  • 2021-12-19
  • 2021-12-04
  • 2021-05-31
  • 2021-08-15
  • 2022-02-22
猜你喜欢
  • 2022-12-23
  • 2021-07-28
  • 2022-12-23
  • 2022-12-23
  • 2022-02-13
  • 2021-10-25
  • 2022-12-23
相关资源
相似解决方案