<2012 12 06> FL2440开发板的U-boot-2010.09版本移植(九)NAND Flash启动支持的一种新型方法,利用U-Boot自带nand_spl/nand_boot.c

本文所介绍的方法不同于网络上所能检索到的绝大多数基于vivi的nandflash启动方法(正像第七节说明的那样),它不需要写任何关于代码复制的内容(不需要修改start.S),而是利用u-boot自带的程序(nand_spl/nand_boot.c)。因此可以说,该方法更能保持u-boot的一致性和完成性。

由于价格的原因,相对于norflash,nandflash对于存储大容量的数据来说更具有优势。但是程序不能直接在nandflash上运行,因此s3c2440提供了一个机制,即系统会自动把nandflash中前4k的内容复制到名为“Steppingstone”的内部SRAM中,利用这段SRAM,程序员需要再把程序复制到其余的SRAM中,然后运行刚刚复制到SRAM中的程序。

本文就介绍如何使u-boot在nandflash中启动,该工作原理类似于u-boot-2011.06自带的smdk6400开发板的nandflash启动过程,即最终生成的烧写文件为u-boot-nand.bin,它是由两个文件组成的:

nand_spl/ u-boot-spl-16k.bin+ u-boot.bin = u-boot-nand.bin

u-boot-spl-16k.bin文件的大小正好为4k,系统启动后,这4k的内容自动复制到Steppingstone中u-boot-spl-16k.bin在完成必要的硬件初始化后,复制u-boot.bin文件到指定的内存中,然后运行已经复制到内存中的u-boot.bin文件。

 

下面就具体讲解移植的过程:

1、boards.cfg

在该文件内去掉下面语句:

zhaocj2440        arm    arm920t     -         samsung        s3c24x0

2、Makefile

在该文件内的第1050行左右添加下面语句:

#########################################################################

## ARM920T Systems

#########################################################################

zhaocj2440_config :      unconfig

       @mkdir-p $(obj)include $(obj)board/samsung/zhaocj2440

       @mkdir-p $(obj)nand_spl/board/samsung/zhaocj2440

       @echo"#define CONFIG_NAND_U_BOOT" > $(obj)include/config.h

       @echo"CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk

       @echo"RAM_TEXT = 0x33000000" >>$(obj)board/samsung/zhaocj2440/config.tmp

       @$(MKCONFIG)zhaocj2440 arm arm920t - samsung s3c24x0

       @echo"CONFIG_NAND_U_BOOT = y" >> $(obj)include/config.mk

3、board/samsung/zhaocj2440/

在该目录下创建config.mk文件,内容为:

sinclude$(OBJTREE)/board/$(BOARDDIR)/config.tmp

ifndef CONFIG_NAND_SPL

CONFIG_SYS_TEXT_BASE =$(RAM_TEXT)

else

CONFIG_SYS_TEXT_BASE = 0

endif

4、nand_spl/board/Samsung/

在该目录下创建zhaocj2440目录,并在zhaocj2440目录下再创建config.mk,Makefile,和u-boot.lds这三个文件,内容分别为:

 

config.mk文件:

 



include$(TOPDIR)/board/$(BOARDDIR)/config.mk



 



# PAD_TO used to generate a 4kByte binaryneeded for the combined image



# -> PAD_TO = CONFIG_SYS_TEXT_BASE +4096



PAD_TO :=$(shell expr $$[$(CONFIG_SYS_TEXT_BASE) + 4096])



 



ifeq ($(debug),1)



PLATFORM_CPPFLAGS += -DDEBUG



endif



 

Makefile文件:

 



CONFIG_NAND_SPL   = y
include $(TOPDIR)/config.mk include$(TOPDIR)/nand_spl/board/$(BOARDDIR)/config.mk nandobj :=$(OBJTREE)/nand_spl/ LDSCRIPT=$(TOPDIR)/nand_spl/board/$(BOARDDIR)/u-boot.lds LDFLAGS := -T $(nandobj)u-boot.lds -Ttext$(CONFIG_SYS_TEXT_BASE) $(LDFLAGS) \ $(LDFLAGS_FINAL) AFLAGS +=-DCONFIG_NAND_SPL CFLAGS +=-DCONFIG_NAND_SPL SOBJS =start.o lowlevel_init.o COBJS =nand_boot.o s3c2440_nand.o SRCS :=$(addprefix $(obj),$(SOBJS:.o=.S) $(COBJS:.o=.c)) OBJS :=$(addprefix $(obj),$(SOBJS) $(COBJS)) __OBJS :=$(SOBJS) $(COBJS) LNDIR :=$(nandobj)board/$(BOARDDIR) ALL =$(nandobj)u-boot-spl $(nandobj)u-boot-spl.bin $(nandobj)u-boot-spl-16k.bin all: $(obj).depend$(ALL) $(nandobj)u-boot-spl-16k.bin:$(nandobj)u-boot-spl $(OBJCOPY)${OBJCFLAGS} --pad-to=$(PAD_TO) -O binary $< $@ $(nandobj)u-boot-spl.bin: $(nandobj)u-boot-spl $(OBJCOPY)${OBJCFLAGS} -O binary $< $@ $(nandobj)u-boot-spl: $(OBJS) $(nandobj)u-boot.lds cd$(LNDIR) && $(LD) $(LDFLAGS) $(__OBJS) \ -Map$(nandobj)u-boot-spl.map \ -o$(nandobj)u-boot-spl $(nandobj)u-boot.lds: $(LDSCRIPT) $(CPP)$(CPPFLAGS) $(LDPPFLAGS) -ansi -D__ASSEMBLY__ -P - <$^ >$@ # create symbolic links for common files # from cpu directory $(obj)start.S: @rm-f $@ @ln-s $(TOPDIR)/arch/arm/cpu/arm920t/start.S $@ # from board directory $(obj)lowlevel_init.S: @rm-f $@ @ln-s $(TOPDIR)/board/samsung/zhaocj2440/lowlevel_init.S $@ # from nand_spl directory $(obj)nand_boot.c: @rm-f $@ @ln-s $(TOPDIR)/nand_spl/nand_boot.c $@ $(obj)s3c2440_nand.c: @rm-f $@ @ln-s $(TOPDIR)/drivers/mtd/nand/s3c2440_nand.c$@ ######################################################################### $(obj)%.o: $(obj)%.S $(CC)$(AFLAGS) -c -o $@ $< $(obj)%.o: $(obj)%.c $(CC)$(CFLAGS) -c -o $@ $< # defines $(obj).depend target include $(SRCTREE)/rules.mk sinclude $(obj).depend #########################################################################

 

u-boot.lds文件:

 

OUTPUT_FORMAT("elf32-littlearm","elf32-littlearm", "elf32-littlearm")



OUTPUT_ARCH(arm)



ENTRY(_start)



SECTIONS



{



       .= 0x00000000;



 



       .= ALIGN(4);



       .text      :



       {



         start.o  (.text)



         nand_boot.o       (.text)



        



         *(.text)



       }



 



       .= ALIGN(4);



       .rodata: { *(SORT_BY_ALIGNMENT(SORT_BY_NAME(.rodata*))) }



 



       .= ALIGN(4);



       .data: { *(.data) }



 



       .= ALIGN(4);



       .got: { *(.got) }



 



       __u_boot_cmd_start= .;



       .u_boot_cmd: { *(.u_boot_cmd) }



       __u_boot_cmd_end= .;



 



       .= ALIGN(4);



 



       .rel.dyn: {



       __rel_dyn_start= .;



       *(.rel*)



       __rel_dyn_end= .;



       }



 



       .dynsym: {



       __dynsym_start= .;



       *(.dynsym)



       }



 



       _end= .;



 



       .bss__rel_dyn_start (OVERLAY) : {



       __bss_start= .;



       *(.bss)



       .= ALIGN(4);



       __bss_end__= .;



       }



}



 

 

5、arch/arm/cpu/arm920t/start.s

在该文件内修改下列内容,其中红色标记的代码为需要修改的部分(仅是增加了CONFIG_NAND_SPL这个配置开关)

 

.globl _start



_start:     b     start_code



#ifndef CONFIG_NAND_SPL            // by zhaocj



       ldr   pc, _undefined_instruction



       ldr   pc, _software_interrupt



       ldr   pc, _prefetch_abort



       ldr   pc, _data_abort



       ldr   pc, _not_used



       ldr   pc, _irq



       ldr   pc, _fiq



 



_undefined_instruction:  .word undefined_instruction



_software_interrupt:      .word software_interrupt



_prefetch_abort:     .word prefetch_abort



_data_abort:           .word data_abort



_not_used:             .wordnot_used



_irq:                     .wordirq



_fiq:                     .wordfiq



_pad:                    .word 0x12345678 //by zhaocj   start



#else



       . = _start + 64



#endif            //by zhaocj   end



 



       .balignl16,0xdeadbeef



 



…………



 



/* Set stackpointer in internal RAM to callboard_init_f */



#ifndef CONFIG_NAND_SPL            //by zhaocj



call_board_init_f:



       ldr   sp, =(CONFIG_SYS_INIT_SP_ADDR)



       bic   sp, sp, #7 /* 8-byte alignment for ABIcompliance */



       ldr   r0,=0x00000000



       bl    board_init_f



 



…………



 



       blcoloured_LED_init



       blred_LED_on



#endif



 



#endif // by zhaocj



 



/*



 * We are done. Do notreturn, instead branch to second part of board



 * initialization, nowrunning from RAM.



 */



#ifdef CONFIG_NAND_SPL



       ldr   sp,=0x33200000  //by zhaocj



       ldr     r0, _nand_boot_ofs



       mov pc, r0



 



_nand_boot_ofs:



       .wordnand_boot



 



…………



 



       mov lr, ip



       mov pc, lr



#endif /* CONFIG_SKIP_LOWLEVEL_INIT */



 



#ifndef CONFIG_NAND_SPL                   //by zhaocj



/*



 *************************************************************************



 *



 * Interrupt handling



 *



 *************************************************************************



 */



 



@



@ IRQ stack frame.



@



#define S_FRAME_SIZE      72



 



…………



 



fiq:



       get_bad_stack



       bad_save_user_regs



       bl    do_fiq



 



#endif



 



#endif            //by zhaocj

6、include/configs/zhaocj2440.h

在该文件内修改下列内容:

 

注释掉下面语句: 

#define CONFIG_SYS_TEXT_BASE  0x0

 

添加下面语句:

#ifndef CONFIG_NAND_SPL       

#define CONFIG_SKIP_LOWLEVEL_INIT

#endif

 

注释掉下面语句:

#define CONFIG_ENV_ADDR                  (CONFIG_SYS_FLASH_BASE +0x080000)

#define CONFIG_ENV_IS_IN_FLASH

#define CONFIG_ENV_SIZE                    0x10000

 

添加下面语句:

#define CONFIG_SYS_NAND_U_BOOT_DST  0x33000000    /*NUB load-addr      */

#define CONFIG_SYS_NAND_U_BOOT_START     CONFIG_SYS_NAND_U_BOOT_DST       /* NUB start-addr     */

 

#define CONFIG_SYS_NAND_U_BOOT_OFFS       (4 * 1024)      /* Offset to RAM U-Boot image */

#define CONFIG_SYS_NAND_U_BOOT_SIZE 0x80000  /*Size of RAM U-Boot image   */

 

/* NAND chip page size        */

#define CONFIG_SYS_NAND_PAGE_SIZE      2048

/* NAND chip block size             */

#define CONFIG_SYS_NAND_BLOCK_SIZE   (128 * 1024)

/* NAND chip page per block count  */

#define CONFIG_SYS_NAND_PAGE_COUNT 64

/* Location of the bad-block label */

#define CONFIG_SYS_NAND_BAD_BLOCK_POS  0

/* Extra address cycle for > 128MiB */

#define CONFIG_SYS_NAND_5_ADDR_CYCLE

 

/* Size of the block protected by one OOB(Spare Area in Samsung terminology) */

#define CONFIG_SYS_NAND_ECCSIZE   CONFIG_SYS_NAND_PAGE_SIZE

/* Number of ECC bytes per OOB - S3C6400 calculates 4 bytes ECC in 1-bitmode */

#define CONFIG_SYS_NAND_ECCBYTES      4

/* Number of ECC-blocks per NAND page */

#define CONFIG_SYS_NAND_ECCSTEPS       (CONFIG_SYS_NAND_PAGE_SIZE  / CONFIG_SYS_NAND_ECCSIZE)

/* Size of a single OOB region */

#define CONFIG_SYS_NAND_OOBSIZE  64

/* Number of ECC bytes per page */

#define CONFIG_SYS_NAND_ECCTOTAL      (CONFIG_SYS_NAND_ECCBYTES *CONFIG_SYS_NAND_ECCSTEPS)

/* ECC byte positions */

#define CONFIG_SYS_NAND_ECCPOS           {40, 41, 42, 43, 44, 45, 46, 47, \

                             48, 49, 50, 51, 52, 53, 54, 55, \

                             56, 57, 58, 59, 60, 61, 62, 63}

 

/* Put environment copies after the end ofU-Boot owned RAM */

#define CONFIG_NAND_ENV_DST   (0x33000000 + 0x80000)

#define CONFIG_ENV_OFFSET        0x80000

#define CONFIG_ENV_IS_IN_NAND

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

 

7、drivers/mtd/cfi_flash.c

在该文件的第2156行(flash_init函数内)把size变量改为:

unsigned long size = 0x200000;

之所以要修改这里,是因为如果nandflash启动,那么系统是无法识别norflash的。为了能够让系统正常运行,修改这个变量是一个简单的办法。

 

 

通过以上7个步骤的修改,就完成了nandflash启动的移植,把编译好的u-boot-nand.bin烧写到nandflash中即可运行了。下面再简单描述一下它的工作原理:u-boot-nand.bin文件是由u-boot-spl-16k.bin文件和u-boot.bin文件组成,后两个文件是两个独立的文件,由编译器一次编译完成。之所以能生成两个独立的文件,依靠的是CONFIG_NAND_SPL这个变量。当定义了CONFIG_NAND_SPL时,编译的是u-boot-spl-16k.bin文件;没有定义CONFIG_NAND_SPL时,编译的是u-boot.bin文件。在u-boot-spl-16k.bin文件内,运行了nand_spl/nand_boot.c这个文件,它负责把u-boot.bin文件从nandflash中复制到以0x33000000为起始地址的一段内存中,复制完后,再让系统从0x33000000处开始运行,即运行u-boot.bin的内容。

source http://blog.csdn.net/zhaocj/article/details/7754083

你可能感兴趣的:(Flash)