基于Ok6410开发板u-boot的移植

我这里是参考江西理工大学09级-朱兆祺同学,以及以下博客的资料,经过几天的痛苦修改后最终移植成功的笔记,在这里感谢他们

参考博客:
http://www.linuxidc.com/Linux/2012-09/69918.htm
http://blog.csdn.net/wletv/article/details/7196206

http://www.360doc.com/content/12/0720/20/7832126_225499671.shtml 

http://blog.163.com/tianjunqiang666@126/blog/static/87259119201243034639891/

前提环境:Win7+VirsualBox+ok6410+u-boot-2010.03

 

一,下载u-boot-2010.03源码

ftp://ftp.denx.de/pub/u-boot

解压,我这里为了避免麻烦,更改了所有文件的权限

tar jxvf u-boot-2010.03.tar.bz2
sudo chmod -R 777 u-boot-2010.03/*

 

 

二,修改源码

为了方便修改,查找代码,你看到u-boot下包含了支持众多CPU和不同架构的代码,这里我根据Ok6410开发板的自身情况,将u-boot下代码进行精简:

1,进入u-boot-2010.03/board,把除samsung以外的文件夹删除

2,进入u-boot-2010.03/cpu,把除arm1176以外的文件夹删除

3,进入u-boot-2010.03/include,把asm-*(注意,仅仅是asm-开头的文件夹)中的,除了asm-arm和asm-generic以外的文件夹删除。

4,进入u-boot-2010.03/include/configs,只要留下smdk6400.h,其他的东西删除

5,进入u-boot-2010.03,把lib_*开头的文件夹(注意,仅仅是lib-开头的文件夹),除了lib_arm和lib_generic以外的文件夹删除

6,进入u-boot-2010.03/nand_spl/board,除了samsung以外的文件夹删除

进行这六步操作后:尝试一下编译,仅仅是尝试。

make smdk6400_config
make

 7,进入u-boot-2010.03/board/samsung,除了smdk6400的文件夹都删除,建立一个新目录smdk6410,并将smdk6400里面的文件给smdk6410拷贝一份过去。

mkdir smdk6410
cp -R smdk6400/* smdk6410/

8,进入u-boot-2010.03/board/samsung/smdk6410文件夹将smdk6400.c更名为smdk6410.c

a)将smdk6410.c里面的6400全部改为6410。

b)将lowlevel_init.S,将里面的6400改为6410。

c)将Makfile,将里面的6400改为6410。

 

9,进入u-boot-2010.03\include\asm-arm , 把除了arch-s3c64xx 和proc-armv 之外的文件夹删除。进入arch-s3c64xx,建立s3c6410.h,

将s3c6400.h 内容复制到s3c6410.h。

cp s3c6400.h s3c6410.h

 将s3c6410.h,将里面的6400改为6410。

 

10,进入到 include/configs/ 复制smdk6400.h,并将副本改为smdk6410.h。

cp smdk6400.h smdk6410.h

 将s3c6410.h,将里面的6400改为6410。

 

11,进入u-boot-2010.03/nand_spl/board/samsung/,建立一个新目录smdk6410,并将smdk6400里面的文件给smdk6410拷贝一份过去。

mkdir smdk6410
cp -R smdk6400/* smdk6410/

a)将Makefile,里面的6400改为6410。

 

12,进入u-boot-2010.03/cpu/arm1176内所有文件以及u-boot-2010.03/cpu/arm1176/s3c64xx/内所有文件中的6400改为6410。

 

13,进入根目录下的Makefile,将CROSS_COMPILE ?=改成为CROSS_COMPILE ?=arm-linux-

然后搜索6400找到smdk6400的配置代码:

#########################################################################
## 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

 将上面蓝色标注的6400,改成6410

 

 14,进入u-boot-2010.03/cpu/arm1176打开start.S,修改第一处代码:

 

//#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

 

 

蓝色部分进行了注释操作。

 

15,继续。还是u-boot-2010.03/cpu/arm1176/start.S文件,修改第二处代码:搜索找到 bl lowlevel_init这行代码:

 

/**********************************
     如果是从nandflash 中启动,那么PC 的值一定在4K 之内。那么执 行完bic r1, pc, r0 之后,r1 为0。_TEXT_BASE 要么等于0x57e0 0000, 
要么等于0xC7e0
0000.那么执行完bic r2, r2, r0 之后,r2 为0x00e0 0000,那么不相等,则不跳转,下面应该就是copy_from_nand。    如果是从ram 中启动,那么PC 的值为0x x7e0 0000。那么执行完 bic r1, pc, r0 之后,r1 为0x00e0 0000。_TEXT_BASE 要么等于0x57e0 0000,要么等于0xC7e0 0000.那么执行完bic r2, r2, r0 之后,r2 为 0x00e0 0000,那么相等,跳转到after_copy,也就是不需要copy。 承接上面分析,如果没有完成copy,则接下来就是copy_from_nand。 那么在beq after_copy 后面添加:       #ifdef CONFIG_BOOT_NAND       mov r0, #0x1000       bl copy_from_nand       #endif 如果完成则会跳过这段代码,直接进入after_copy。 **********************************/ /* * Go setup Memory and board specific bits prior to relocation. */ bl lowlevel_init /* go setup pll,mux,memory */ ldr r0,=0xff000fff bic r1,pc,r0 ldr r2,_TEXT_BASE bic r2,r2,r0 cmp r1,r2 beq after_copy #ifdef CONFIG_BOOT_NAND mov r0,#0x1000 bl copy_from_nand #endif

 

 

 

什么意思暂时没弄清楚,不过参考的文章上说是:判断是从nandflash启动还是从ram启动。

 

16,继续start.S文件,修改第三处代码:在

#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

 

 

17,u-boot-2010.03/cpu/arm1176/下新建nand_cp.c文件,代码如下:

#include <common.h>
#ifdef CONFIG_S3C64XX
#include <asm/io.h>
#include <linux/mtd/nand.h>
#include <asm/arch/s3c6410.h>
static int nandll_read_page (uchar *buf, ulong addr, int large_block)
{
int i;
int page_size = 512;
/* 2K */
if (large_block==1)
page_size = 2048;
/* 4K */
if (large_block==2)
page_size = 4096;
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;
/*
#define NFCMD_REG
__REG(ELFIN_NAND_BASE + NFCMMD_OFFSET)
#define ELFIN_NAND_BASE 0x70200000
#define NFCMMD_OFFSET 0x08
NFCMD_REG = ( *( (volatile u32 *) (0x70200008) ) )
NFCMMD 0x70200008 NAND Flash ÃüÁîÉèÖÌĎæÆ÷0
#define NAND_CMD_READSTART 0x30
*/
if (large_block)
NFCMD_REG = NAND_CMD_READSTART;
/*
define NF_TRANSRnB()
do { while( !( NFSTAT_REG & (1 << 0) ) ); } while(0)
#define NFSTAT_REG
__REG(ELFIN_NAND_BASE + NFSTAT_OFFSET)
NFSTAT_REG = ( *( (volatile u32 *) (0x70200028) ) )
NFSTAT 0x70200028 NAND Flash ²Ù×÷׎̬ŒÄŽæÆ÷
*/
NF_TRANSRnB();
/* for compatibility(2460). u32 cannot be used. by scsuh */
for(i=0; i < page_size; i++)
{
*buf++ = NFDATA8_REG;
}
/*
#define NAND_DISABLE_CE() (NFCONT_REG |= (1 << 1))
#define NFCONT_REG
__REG(ELFIN_NAND_BASE + NFCONT_OFFSET)
#define __REG(x) (*((volatile u32 *)(x)))
#define ELFIN_NAND_BASE 0x70200000
#define NFCONT_OFFSET 0x04
*/
NAND_DISABLE_CE();
return 0;
}
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==1)
page_shift = 11;
/* Read pages */
if(large_block==2)
page_shift = 12;
if(large_block == 2)
{
/* Read pages */
for (i = 0; i < 4; i++, buf+=(1<<(page_shift-1)))
{
nandll_read_page(buf, i, large_block);
}
/* Read pages */
/* 0x3c000 = 11 1100 0000 0000 0000 */
for (i = 4; i < (0x3c000>>page_shift); i++, buf+=(1<<page_shift))
{
nandll_read_page(buf, i, large_block);
}
}
else
{
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;
/*
#define NAND_ENABLE_CE() (NFCONT_REG &= ~(1 << 1))
#define NFCONT_REG
__REG(ELFIN_NAND_BASE + NFCONT_OFFSET)
#define __REG(x) (*((volatile u32 *)(x)))
#define ELFIN_NAND_BASE 0x70200000
#define NFCONT_OFFSET 0x04
NFCONT_REG = ( *( (volatile u32 *) (0x70200004) ) )
NFCONT 0x70200004 ¶Á/ÐŽNAND Flash ¿ØÖƌĎæÆ÷
[0]1£ºNAND Flash ¿ØÖÆÆ÷ʹÄÜ
*/
NAND_ENABLE_CE();
/*
#define NFCMD_REG
__REG(ELFIN_NAND_BASE + NFCMMD_OFFSET)
#define ELFIN_NAND_BASE 0x70200000
#define NFCMMD_OFFSET 0x08
NFCMD_REG = ( *( (volatile u32 *) (0x70200008) ) )
NFCMMD 0x70200008 NAND Flash ÃüÁîÉèÖÌĎæÆ÷0
#define NAND_CMD_READID 0x90
*/
NFCMD_REG = NAND_CMD_READID;
/*
#define NFADDR_REG
__REG(ELFIN_NAND_BASE + NFADDR_OFFSET)
#define ELFIN_NAND_BASE 0x70200000
#define NFADDR_OFFSET 0x0C
NFADDR_REG = ( *( (volatile u32 *) (0x7020000C) ) )
NFADDR 0x7020000C NAND Flash µØÖ·ÉèÖÌĎæÆ÷
*/
NFADDR_REG = 0x00;
/*
#define NFDATA8_REG
__REGb(ELFIN_NAND_BASE + NFDATA_OFFSET)
#define __REGb(x) (*(vu_char *)(x))
NFDATA8_REG = ( *( (vu_char *) (0x70200010) ) )
NFDATA 0x70200010 ¶Á/ÐŽNAND Flash ÊýŸÝŒÄŽæÆ÷
NAND Flash ¶Á/ÉÕÐŽÊýŸÝÖµÓÃÓÚI/O
*/
/* wait for a while */
for (i=0; i<200; i++);
id = NFDATA8_REG;
id = NFDATA8_REG;
if (id > 0x80)
large_block = 1;
if(id == 0xd5)
large_block = 2;
/* read NAND Block.
* 128KB ->240KB because of U-Boot size increase. by scsuh
* So, read 0x3c000 bytes not 0x20000(128KB).
*/
/*
#define CONFIG_SYS_PHY_UBOOT_BASE
(CONFIG_SYS_SDRAM_BASE + 0x07e00000)
#define CONFIG_SYS_SDRAM_BASE 0x50000000
CONFIG_SYS_PHY_UBOOT_BASE = 0x57e0 0000
0x3 c000 = 1M
*/
return nandll_read_blocks(CONFIG_SYS_PHY_UBOOT_BASE, 0x3c000, large_block);
}
#endif
View Code

 

 18,u-boot-2010.03/cpu/arm1176/Makefile文件:

COBJS    =cpu.o nand_cp.o

如上加入nand_cp.o

 

 19,u-boot-2010.03/include/configs/smdk6410.h文件:

加上这个定义:

#define virt_to_phys(x) virt_to_phy_smdk6410(x)

 

 20:继续smdk6410.h文件,找到/* NAND configuration */

/* NAND configuration */
#define CONFIG_SYS_MAX_NAND_DEVICE    1
#define CONFIG_SYS_NAND_BASE        0x70200010
#define CONFIG_SYS_S3C_NAND_HWECC
/* 加上下面三个定义 */ #define NAND_DISABLE_CE()(NFCONT_REG|=(1<<1)) #define NAND_ENABLE_CE()(NFCONT_REG&=~(1<<1)) #define NF_TRANSRnB() do{while(!(NFSTAT_REG&(1<<0)));}while(0)

 

21:继续smdk6410.h文件,我的ok6410,内存为256MB,则需要修改下面(NandFlash每个块的大小)

//#define PHYS_SDRAM_1_SIZE    0x08000000    /* 128MB in Bank #1    */
#define PHYS_SDRAM_1_SIZE    0x10000000    /* 256 MB in Bank #1    */

 

22:继续smdk6410.h文件,分配smdk6410的ID号:

//#define MACH_TYPE        1270
#define MACH_TYPE        1626

 

23,继续smdk6410.h文件,更改内存的分配大小:

//#define CONFIG_SYS_MALLOC_LEN        (CONFIG_ENV_SIZE + 1024 * 1024)
#define CONFIG_SYS_MALLOC_LEN        (CONFIG_ENV_SIZE + 512 * 1024)
#define CONFIG_SYS_GBL_DATA_SIZE    128    /* size in bytes for initial data */

24,继续smdk6410.h文件,更改bootdelay时间:

//#define CONFIG_BOOTDELAY    3
#define CONFIG_BOOTDELAY    10

 

25,继续smdk6410.h文件,更改SDROM大小:

#define CONFIG_SYS_MEMTEST_START    CONFIG_SYS_SDRAM_BASE    /* memtest works on          */
//#define CONFIG_SYS_MEMTEST_END        (CONFIG_SYS_SDRAM_BASE + 0x7e00000) /* 126MB in DRAM */
#define CONFIG_SYS_MEMTEST_END        (CONFIG_SYS_SDRAM_BASE + 0x9e00000) /* 256MB in DRAM */

 

 

26,继续smdk6410.h文件,修改时间:

//#define CONFIG_SYS_HZ            1000
#define CONFIG_SYS_HZ            1562500

 

27,继续smdk6410.h文件,修改堆栈大小:

//#define CONFIG_STACKSIZE    0x40000        /* regular stack 256KB */
#define CONFIG_STACKSIZE    0x80000        /* regular stack 512KB */

 

 

28,继续smdk6410.h文件,修改:

//#define CONFIG_ENV_SIZE        0x4000    /* Total Size of Environment Sector */
#define CONFIG_ENV_SIZE        0x80000    /* Total Size of Environment Sector */

 

29,继续smdk6410.h文件,修改CONFIG_BOOTCOMMAND:

//#define CONFIG_BOOTCOMMAND    "nand read 0xc0018000 0x60000 0x1c0000;" \
                "bootm 0xc0018000"
#define CONFIG_BOOTCOMMAND    "nand read 0x50018000 0x100000 0x500000;" \
                "bootm 0x50018000"

 

30,继续smdk6410.h文件,修改:

//#define CONFIG_ENV_OFFSET        0x0040000
#define CONFIG_ENV_OFFSET        0x0080000

 

31,继续smdk6410.h文件,修改NandFlash每一页的大小:

//#define CONFIG_SYS_NAND_PAGE_SIZE    2048
#define CONFIG_SYS_NAND_PAGE_SIZE    4096

 

32,继续smdk6410.h文件,修改NandFlash每一块的大小:

//#define CONFIG_SYS_NAND_BLOCK_SIZE    (128 * 1024)
#define CONFIG_SYS_NAND_BLOCK_SIZE    (512 * 1024)

 

33,继续/smdk6410.h文件,修改校验位:

//#define CONFIG_SYS_NAND_PAGE_COUNT    64
#define CONFIG_SYS_NAND_PAGE_COUNT    128

 

34,修改u-boot-2010.03/board/samsung/smdk6410下u-boot-nand.lds,添加蓝色部分:

SECTIONS
{
    . = 0x00000000;

    . = ALIGN(4);
    .text      :
    {
      cpu/arm1176/start.o    (.text)
      cpu/arm1176/s3c64xx/cpu_init.o    (.text)
      board/samsung/smdk6410/lowlevel_init.o    (.text)
      cpu/arm1176/nand_cp.o    (.text)
      lib_arm/board.o    (.text)
      *(.text)
    }

    ....
}

 

35,修改u-boot-2010.03/cpu/arm1176下u-boot.lds,添加蓝色部分:

SECTIONS
{
    . = 0x00000000;

    . = ALIGN(4);
    .text :
    {
        cpu/arm1176/start.o    (.text)
        board/samsung/smdk6410/lowlevel_init.o (.text)
        cpu/arm1176/s3c64xx/cpu_init.o (.text)
        cpu/arm1176/nand_cp.o (.text) 
        *(.text)
    }

    ....
}

 

36,进入u-boot-2010.03/nand_spl/board/samsung/smdk6410/,修改Makefile文件:

1,在$(obj)cpu_init.S:
    @rm -f $@
    @ln -s $(TOPDIR)/cpu/arm1176/s3c64xx/cpu_init.S $@

之后添加:

$(obj)nand_cp.c:
    @rm -f $@
    @ln -s $(TOPDIR)/cpu/arm1176/nand_cp.c $@

 

2,在COBJS后面加上 nand_cp.o

SOBJS    = start.o cpu_init.o lowlevel_init.o
COBJS    = nand_boot.o nand_ecc.o s3c64xx.o nand_cp.o

 


如上加入nand_cp.o

三,编译

编译之后,可以在开发板上运行成功,后面有补充,会及时更新。

make smdk6410_config
make

 

 

 

 

 

 

 

 

posted on 2014-01-19 15:02  lucky_tom  阅读(1107)  评论(0编辑  收藏  举报