u-boot-2014.10移植重定位,支持NAND启动

Posted hulig7

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了u-boot-2014.10移植重定位,支持NAND启动相关的知识,希望对你有一定的参考价值。

前面链接地址都是0x0,可以从nor正常启动内核和文件系统。
现在把链接地址改成0x33f00000
一旦更改了链接地址, u-boot从nor flash加载时,串口没有任何输出
 
添加文件boot_init.c
#define NFCONF (*((volatile unsigned long *)0x4E000000))
#define NFCONT (*((volatile unsigned long *)0x4E000004))
#define NFCMMD (*((volatile unsigned char *)0x4E000008))
#define NFADDR (*((volatile unsigned char *)0x4E00000C))
#define NFDATA (*((volatile unsigned char *)0x4E000010))
#define NFSTAT (*((volatile unsigned char *)0x4E000020))
        
static void nand_select(void)
{
    NFCONT &= ~(1<<1);    
}

static void nand_deselect(void)
{
    NFCONT |= (1<<1);    
}
    
        
static void nand_cmd(unsigned char cmd)
{
    volatile int i;
    NFCMMD = cmd;
    for (i = 0; i < 10; i++);
}
        
static void nand_addr(unsigned int addr)
{
    unsigned int col  = addr % 2048;
    unsigned int page = addr / 2048;
    volatile int i;

    NFADDR = col & 0xff;
    for (i = 0; i < 10; i++);
    NFADDR = (col >> 8) & 0xff;
    for (i = 0; i < 10; i++);
    
    NFADDR  = page & 0xff;
    for (i = 0; i < 10; i++);
    NFADDR  = (page >> 8) & 0xff;
    for (i = 0; i < 10; i++);
    NFADDR  = (page >> 16) & 0xff;
    for (i = 0; i < 10; i++);    
}
    
static void nand_wait_ready(void)
{
    while (!(NFSTAT & 1));
}
    
static unsigned char nand_data(void)
{
    return NFDATA;
}
        
        
static void nand_read_ll(unsigned int addr, unsigned char *buf, unsigned int len)
{
    int col = addr % 2048;
    int i = 0;

    nand_select();
    while (i < len)
    {
        nand_cmd(0x00);

        nand_addr(addr);

        nand_cmd(0x30);
        
        nand_wait_ready();
        
        for (; (col < 2048) && (i < len); col++)
        {
            buf[i] = nand_data();
            i++;
            addr++;
        }
                
        col = 0;
    }
            
    nand_deselect();
}
        
static void nand_init(void)
{
#define TACLS   0
#define TWRPH0  1
#define TWRPH1  0
        
    NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);
    NFCONT = (1<<4)|(1<<1)|(1<<0);    
}
        
        
/* 1: from nor 0: from nand */
static int isBootFromNorFlash(void)
{
    volatile int *p = (volatile int *)0;
    int val;

    val = *p;
    *p = 0x12345678;
    if (*p == 0x12345678)
    {
        *p = val;
        return 0;
    }
    else
    {
        // nor
        return 1;
    }
}
        
void copy_code_to_sdram(unsigned char *src, unsigned char *dest, unsigned int len)
{
    int i = 0;
    if (isBootFromNorFlash())
    {
        while (i < len)
        {
            dest[i] = src[i];
            i++;
        }
    }
      else     // from nand
      {
        nand_init();
        nand_read_ll((unsigned int)src, dest, len);
    }
}
        
void clear_bss(void)
{
    extern int __bss_start, __bss_end;
    int *p = &__bss_start;
        
    for (; p < &__bss_end; p++)
        *p = 0;
}    

修改对应目录Makefile

obj-y   := smdk2440.o boot_init.o

把smdk2440/目录下内容放最前面,满足4K内

vim arch/arm/cpu/u-boot.lds

board/samsung/smdk2440/built-in.o (.text*)

修改重定位代码:

#if defined(CONFIG_SYS_MALLOC_F_LEN) && !defined(CONFIG_SPL_BUILD)
        sub     sp, sp, #CONFIG_SYS_MALLOC_F_LEN
        str     sp, [r9, #GD_MALLOC_BASE]
        #endif
        
    #if defined(CONFIG_S3C2440)
        mov r0, #0
        ldr r1, = CONFIG_SYS_TEXT_BASE
        ldr r2, = CONFIG_SYS_TEXT_BASE
        ldr r3, =__bss_end
        sub r2, r3, r2
        bl copy_code_to_sdram

        bl clear_bss
        ldr pc, =call_board_init_f
        
call_board_init_f:
        mov     r0, #0
        bl      board_init_f
        
        ldr     sp, [r9, #GD_START_ADDR_SP]     /* sp = gd->start_addr_sp */
        bic     sp, sp, #7                      /* 8-byte alignment for ABI compliance */
        ldr     r9, [r9, #GD_BD]                /* r9 = gd->bd */
        sub     r9, r9, #GD_SIZE                /* new GD is below bd */
        
        mov r0, r9
        ldr r1, = CONFIG_SYS_TEXT_BASE
        bl  board_init_r
#else
        /* mov r0, #0 not needed due to above code */
        bl      board_init_f

        ...
#endif

去掉pie选项vim arch/arm/config.mk

#LDFLAGS_u-boot += -pie
#ALL-y += checkarmreloc

 

此外board.c里面还应修改

board_init_f
    //addr -= gd->mon_len;
        //addr &= ~(4096 - 1);
        addr = CONFIG_SYS_TEXT_BASE ; 

烧写u-boot到nand

bootloader:
    tftp 30000000 u-boot.bin
    nand erase.part bootloader
    nand write.jffs2 30000000 bootloader

烧写u-boot到nor

tftp 30000000 u-boot.bin
    protect off all
    erase 0 3ffff   (256K)
    cp.b 30000000 0 40000

 

 

以上是关于u-boot-2014.10移植重定位,支持NAND启动的主要内容,如果未能解决你的问题,请参考以下文章

u-boot-2014.10移植

u-boot-2014.10移植识别dm9000

u-boot-2014.10移植设置时钟/SDRAM

u-boot-2014.10移植修改环境变量的存储位置

u-boot-2014.10移植添加mtdparts命令和分区

移植kernel-3.10.79