u-boot-2009-11移植之stage1(支持从nand启动)

目标板:FL2440

硬件资源:64M SDRAM/256M nandflash(k9f2g08u0a)/4M nor flash(JS28F320)

开发环境:fedora 14

源码:u-boot-2009.11

交叉编译工具链:cross-3.3.2.tar.bz2

参考资料:http://linchunai1212.blog.163.com/blog/static/3511214320106169413757/?fromdm&fromSearch&isFromSearchEngine=yes

天嵌TQ2440 uboot-1.16源码(主要参考256M nand flash 代码重定位部分程序)

关于uboot的源码结构这里就不多说了,网上很这方面的资料。注意,此文章不支持nor flash启动。

一、建立开发板项目,并尝试编译

1、下面的操作都是基于目录[root@fzliu u-boot-2009.11]#

2、指定交叉编译器

[root@fzliu u-boot-2009.11]# vim Makefile,

修改163行为CROSS_COMPILE ?=arm-linux-
3、在board/samsung/下建立自己的开发板项目

[root@fzliu u-boot-2009.11]# mkdir board/samsung/rocko2440

(取名rocko是因为喜欢Sylvester Stallone主演的励志电影《洛奇》,

4、注意,uboot的移植是基于源码包的smdk2410开发板,因为2410和2440资源并不多。将smdk2410下所有文件复制到rocko2440.
[root@fzliu u-boot-2009.11]# cp -rf board/samsung/smdk2410/* board/samsung/rocko2440/

[root@fzliu u-boot-2009.11]# mv board/samsung/smdk2410/smdk2410.c board/samsung/rocko2440/rocko2440.c

[root@fzliu u-boot-2009.11]# cp include/configs/smdk2410.h include/configs/rocko2440.h( 建立2440头文件)

[root@fzliu u-boot-2009.11]# vim  board/samsung/rocko2440/Makefile

28行改为: 

COBJS    := rocko2440.o flash.o  //因在 rocko2440 下我们将 smdk2410.c 改名为rocko2440.c

5、参考smdk2410_config建立rocko2440_configs选项

[root@fzliu u-boot-2009.11]# vim Makefile

在3050行添加:

rocko2440_config    :   unconfig
    @$(MKCONFIG) $(@:_config=) arm arm920t rocko2440 samsung s3c24x0
*说明:arm    :CPU 的架构(ARCH)
       arm920t:CPU 的类型 
       rocko2440:对应在 board 目录下建立新的开发板项目的目录
       samsung:新开发板项目目录的上级目录,如直接在 board 下建立新的开发板项
目的目录,则这里就为 NULL
       s3c24x0:CPU 型号
*注意:编译选项格式的第二行要用 Tab 键开始,否则编译会出错

6、测试编译新建的 rocko2440 开发板项目

[root@fzliu u-boot-2009.11]# make rocko2440_config

Configuring for rocko2440 board...(此信息表明设置正确)

7、尝试编译

[root@fzliu u-boot-2009.11]# make  

此时有可能会出现编译错误,

linux/3.3.2/libgcc.a(_modsi3.oS) uses hardware FP, whereas u-boot uses software FP

解决方法:

[root@fzliu u-boot-2009.11]# vim cpu/arm920t/config.mk

 24行改为:

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

[root@fzliu u-boot-2009.11]# make

编译后在目录下生成u-boot.bin文件,移植的第一步完成。别急哦,真正的工作还没开始呢

二、分析uboot启动流程之stage1,并修改源码使之能在FL2440开发板上运行。

一般在嵌入式系统软件开发中,在所有源码文件编译完成之后,链接器要读取一个链接分配文件,在该文件中定义了程序的入口点,代码段、数据段等分配情况等。对于rocko2440开发板来说,这个链接文件就是: cpu/arm920t/u-boot.lds,从该文件知程序入口点为_start(在cpu/arm920t/start.S文件中)

OUTPUT_FORMAT("elf32-littlearm", "elf32-littlearm", "elf32-littlearm")
OUTPUT_ARCH(arm)
ENTRY(_start)//指定程序入口点为_start
SECTIONS
{
    . = 0x00000000;
    . = ALIGN(4);
    .text :
    {
        cpu/arm920t/start.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);
    __bss_start = .;
    .bss (NOLOAD) : { *(.bss) . = ALIGN(4); }
    _end = .;
}

1、知道了程序的入口点是_start,那么我们就从这个文件入手,一步步剖析uboot stage1之启动流程

[root@fzliu u-boot-2009.11]# cpu/arm920t/start.S

这里只分析start.S的启动流程

(1)首先,跳转到start_code执行,设置cpu工作模式为SVC模式,关闭看门狗,屏蔽中断,设置时钟分频比

(2)b1 cpu_init_crit

这部分代码将进行清flush 清caches,关闭MMU功能,调用lowlevel_init函数配置SDRAM(在 board/samsung/rocko2440/目录下),下面修改SDRAM的刷新频率:

[root@fzliu u-boot-2009.11]#vim  board/samsung/rocko2440/lowlevel_init.c

将REFCNT改为:

#define REFCNT   0x4f4 (refresh_count)

S3C2440手册知,计算公式:Refresh period = (2^11-refresh_count+1)/HCLK

SDRAM手册知:Refresh period =8192/64ms

下面start.S设置FCLK为405MHZ,分频系数 FCLK:HCLK:PCLK = 1:4:8 ,HCLK=100MHZ

(3)设置堆栈,因为下面的代码重定位程序将使用C函数。注意一定要在调用C前设置堆栈。

(4)代码重定位,这里会有两种情况。如果系统是从norflash启动或者直接下到SDRAM中运行,则不需要进行代码搬移,直接跳到清bss段代码,最后进入uboot的stage2阶段入口_start_armboot;如果从nandflash启动,则调用C函数进行代码搬移,然后跳到清bss段代码,最后进入uboot的stage2阶段入口_start_armboot。

start_code:
	/*
	 * set the cpu to SVC32 mode
	 */
	mrs	r0, cpsr
	bic	r0, r0, #0x1f
	orr	r0, r0, #0xd3
	msr	cpsr, r0	//bl	coloured_LED_init#if defined(CONFIG_S3C2440)   //区别与其他开发板 
#define GPBCON 0x56000010     //fl2440开发板的GPB5 6 8 10 控制四个LED灯
#define GPBDAT 0x56000014
#define GPBUP  0x56000018
ldr         r0,=GPBUP
ldr         r1,=0x00
str         r1,[r0]
ldr         r0,=GPBCON
ldr         r1,=0xddd7fc
str         r1,[r0]
ldr         r0,=GPBDAT
ldr         r1,=0xffc0     //GPB5亮,其它灭
str         r1,[r0]
#endif
#if	defined(CONFIG_AT91RM9200DK) || defined(CONFIG_AT91RM9200EK)
	/*
	 * relocate exception table
	 */
	ldr	r0, =_start
	ldr	r1, =0x0
	mov	r2, #16
copyex:
	subs	r2, r2, #1
	ldr	r3, [r0], #4
	str	r3, [r1], #4
	bne	copyex
#endif
#if defined(CONFIG_S3C2400) || defined(CONFIG_S3C2410)|| defined(CONFIG_S3C2440)
	/* turn off the watchdog */ # if defined(CONFIG_S3C2400)
#  define pWTCON	0x15300000
#  define INTMSK	0x14400008	/* Interupt-Controller base addresses */
#  define CLKDIVN	0x14800014	/* clock divisor register */#else //下面 2410 和 2440 的寄存器地址是一致的 
#  define pWTCON	0x53000000
#  define INTMSK	0x4A000008	/* Interupt-Controller base addresses */
#  define INTSUBMSK	0x4A00001C
#  define CLKDIVN	0x4C000014	/* clock divisor register */
# endif
	ldr	r0, =pWTCON
	mov	r1, #0x0
	str	r1, [r0]

	/*
	 * mask all IRQs by setting all bits in the INTMR - default
	 */
	mov	r1, #0xffffffff
	ldr	r0, =INTMSK
	str	r1, [r0]#
 if defined(CONFIG_S3C2410)
	ldr	r1, =0x3ff
	ldr	r0, =INTSUBMSK
	str	r1, [r0]
# endif
# if defined(CONFIG_S3C2440)//添加 s3c2440 的中断禁止部分 
    ldr   r1, =0x7fff        //根据 2440 芯片手册,INTSUBMSK 寄存器有 15位可用    
    ldr   r0, =INTSUBMSK 
    str   r1, [r0] 
# endif 
# if defined(CONFIG_S3C2440)   //添加 s3c2440 的时钟部分 
#define MPLLCON   0x4C000004   //系统主频配置寄存器基地址 
#define UPLLCON   0x4C000008   //USB 时钟频率配置寄存器基地址  
    ldr  r0, =CLKDIVN          //设置分频系数 FCLK:HCLK:PCLK = 1:4:8 
    mov  r1, #5 
    str  r1, [r0] 
    ldr  r0, =MPLLCON  //设置系统主频为 405MHz  
    ldr  r1, =0x7F021  //这个值参考芯片手册“PLL VALUE SELECTION TABLE”部分
    str  r1, [r0] 
  
    ldr  r0, =UPLLCON  //设置 USB 时钟频率为 48MHz  
    ldr  r1, =0x38022  //这个值参考芯片手册“PLL VALUE SELECTION TABLE”部分
    str  r1, [r0]   
  
# else //其他开发板的时钟部分,这里就不用管了,我们现在是做 2440 的 
	/* FCLK:HCLK:PCLK = 1:2:4 */
	/* default FCLK is 120 MHz ! */
	ldr	r0, =CLKDIVN
	mov	r1, #3
	str	r1, [r0]
#endif
 #endif	/* CONFIG_S3C2400 || CONFIG_S3C2410|| CONFIG_S3C2440 */ 	/*
	 * we do sys-critical inits only at reboot,
	 * not when booting from ram!
	 */#ifndef CONFIG_SKIP_LOWLEVEL_INIT
	bl	cpu_init_crit
#endif	/* Set up the stack						    */stack_setup: 
	ldr	r0, _TEXT_BASE		/* upper 128 KiB: relocated uboot   */
	sub	r0, r0, #CONFIG_SYS_MALLOC_LEN	/* malloc area              */
	sub	r0, r0, #CONFIG_SYS_GBL_DATA_SIZE /* bdinfo                 */
#ifdef CONFIG_USE_IRQ
	sub	r0, r0, #(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
#endif
	sub	sp, r0, #12		/* leave 3 words for abort-stack    */ #ifndef CONFIG_SKIP_RELOCATE_UBOOT relocate:				/* relocate U-Boot to RAM	    */
	adr	r0, _start		/* r0 <- current position of code   */
	ldr	r1, _TEXT_BASE		/* test if we run from flash or RAM */
	cmp	r0, r1			/* don't reloc during debug         */
	beq	clear_bss

	ldr	r2, _armboot_start
	ldr	r3, _bss_start
	sub	r2, r3, r2		/* r2 <- size of armboot            */
#if 1
    bl CopyCode2Ram     //此处调用 C 代码中读 Nand 的函数,现在还没有要自己编写实现			 
#else
    add	r2, r0, r2		/* r2 <- source end address         */
copy_loop:
	ldmia	r0!, {r3-r10}		/* copy from source address [r0]    */
	stmia	r1!, {r3-r10}		/* copy to   target address [r1]    */
	cmp	r0, r2			/* until source end addreee [r2]    */
	ble	copy_loop
#endif
#endif	/* CONFIG_SKIP_RELOCATE_UBOOT */ clear_bss:
	ldr	r0, _bss_start		/* find start of bss segment        */
	ldr	r1, _bss_end		/* stop here                        */
	mov	r2, #0x00000000		/* clear                            */

clbss_l:str	r2, [r0]		/* clear loop...                    */
	add	r0, r0, #4
	cmp	r0, r1
	ble	clbss_l	
/*进入stage2 入口函数_start_armboot*/
	ldr	pc, _start_armboot
_start_armboot:	.word start_armboot/*
 *************************************************************************
 *
 * CPU_init_critical registers
 *
 * setup important registers
 * setup memory timing
 *
 *************************************************************************
 */
#ifndef CONFIG_SKIP_LOWLEVEL_INITcpu_init_crit:	/*
	 * 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

	/*
	 * before relocating, we have to setup RAM timing
	 * because memory timing is board-dependend, you will
	 * find a lowlevel_init.S in your board directory.
	 */
	mov	ip, lr

	bl	lowlevel_init
	mov	lr, ip
	mov	pc, lr
#endif /* CONFIG_SKIP_LOWLEVEL_INIT */

2、完成了start.S修改后,在include/configs/rocko2440.h下添加CONFIG_S3C2440 配置选项,

[root@fzliu u-boot-2009.11]# vim include/configs/rocko2440.h

#define CONFIG_ARM920T        1    /* This is an ARM920T Core     */
#define CONFIG_S3C2410        1    /* in a SAMSUNG S3C2410 SoC     */
#define CONFIG_SMDK2410       1    /* on a SAMSUNG SMDK2410 Board */
#define CONFIG_S3C2440        1    /* in a SAMSUNG S3C2440 SoC    */

 3、S3C2440 的时钟部分除了在 start.S 中添加外,还要分别在 board/samsung/rocko2440/rocko2440.c 和
cpu/arm920t/s3c24x0/speed.c 中修改或添加部分代码,如下:

 [root@fzliu u-boot-2009.11]# vim board/samsung/rocko2440/rocko2440.c

黑体部分有效

#define FCLK_SPEED 2
 #if FCLK_SPEED==0		/* Fout = 203MHz, Fin = 12MHz for Audio */
#define M_MDIV	0xC3
#define M_PDIV	0x4
#define M_SDIV	0x1
#elif FCLK_SPEED==1		/* Fout = 202.8MHz */
#define M_MDIV	0xA1
#define M_PDIV	0x3
#define M_SDIV	0x1
#elif FCLK_SPEED==2        /* Fout = 405MHz */ 
#define M_MDIV    0x7F     //这三个值根据 S3C2440 芯片手册“PLL VALUE SELECTION TABLE”部分进行设置 
#define M_PDIV    0x2 
#define M_SDIV    0x1  
#endif
#define USB_CLOCK 2 #if USB_CLOCK==0
#define U_M_MDIV	0xA1
#define U_M_PDIV	0x3
#define U_M_SDIV	0x1
#elif USB_CLOCK==1
#define U_M_MDIV	0x48
#define U_M_PDIV	0x3
#define U_M_SDIV	0x2
#elif USB_CLOCK==2         /* Fout = 48MHz */ 
#define U_M_MDIV    0x38   //这三个值根据 S3C2440 芯片手册“PLL VALUESELECTIONTABLE”部分进行设置 
#define U_M_PDIV    0x2 
#define U_M_SDIV    0x2 
 #endif

 [root@fzliu u-boot-2009.11]# vim cpu/arm920t/s3c24x0/speed.c

static ulong get_PLLCLK(int pllreg)
{
	struct s3c24x0_clock_power *clk_power =  s3c24x0_get_base_clock_power();
	ulong r, m, p, s;

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

	m = ((r & 0xFF000) >> 12) + 8;
	p = ((r & 0x003F0) >> 4) + 2;
	s = r & 0x3;
#if defined(CONFIG_S3C2440) 
    if(pllreg == MPLL)
    {   //参考S3C2440 芯片手册上的公式:PLL=(2 * m * Fin)/(p * 2 s ) 
        return((CONFIG_SYS_CLK_FREQ * m * 2) / (p << s)); 
    } 
#endif 
    return (CONFIG_SYS_CLK_FREQ * m) / (p << s);
}

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

/* return HCLK frequency */
ulong get_HCLK(void)
{
	struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();
#if defined(CONFIG_S3C2440) 
    return(get_FCLK()/4); 
#endif	
return (readl(&clk_power->CLKDIVN) & 2) ? get_FCLK() / 2 : get_FCLK();
}

/* return PCLK frequency */
ulong get_PCLK(void)
{
	struct s3c24x0_clock_power *clk_power = s3c24x0_get_base_clock_power();

	return (readl(&clk_power->CLKDIVN) & 1) ? get_HCLK() / 2 : get_HCLK();
}

/* return UCLK frequency */
ulong get_UCLK(void)
{
	return get_PLLCLK(UPLL);
}

#endif

 

4、到此,uboot是否就支持了nandflash 启动了呢,还记得我们在start.S文件中添加的用于将uboot从nandflash搬到SDRAM中的函数CopyCode2Ram 吗?现在我们就去实现这个函数,在board/samsung/rocko2440/下新建一个nand_read.c

[root@fzliu u-boot-2009.11]# vim board/samsung/rocko2440/nand_read.c(这部分参考TQ2440 uboot1.1.6)

#include  <config.h>
#define  NF_BASE     0x4E000000   //Nand  Flash 配置寄存器基地址
#define  __REGb(x)  (*(volatile  unsigned  char  *)(x))
#define  __REGi(x)  (*(volatile  unsigned  int   *)(x))
#define  NFCONF  __REGi(NF_BASE  +  0x0  )   
#define  NFCONT  __REGi(NF_BASE  +  0x4  )   
#define  NFCMD   __REGb(NF_BASE  +  0x8  )   
#define  NFADDR  __REGb(NF_BASE  +  0xC  )  
#define  NFDATA  __REGb(NF_BASE  +  0x10)  
#define  NFSTAT  __REGb(NF_BASE  +  0x20)   
#define  NAND_SECTOR_SIZE  512
#define  NAND_BLOCK_MASK  (NAND_SECTOR_SIZE  -  1)
#define NAND_SECTOR_SIZE_LP	2048
#define NAND_BLOCK_MASK_LP	(NAND_SECTOR_SIZE_LP - 1)
#define BUSY            1
#if defined(CONFIG_S3C2440)
#define GPBCON (*(volatile unsigned long *)0x56000010)
#define GPBDAT (*(volatile unsigned long *)0x56000014)
#define GPBUP   (*(volatile unsigned long *)0x56000018)
#endif
/*  low  level  nand  read  function  */

ldr  r0,  =TEXT_BASE//传递给 C 代码的第一个参数:u-boot 在 RAM 中的起始地址
mov  r1,  #0x0 //传递给 C 代码的第二个参数:Nand  Flash 的起始地址
	ldr	r2, _armboot_start
	ldr	r3, _bss_start
	sub	r2, r3, r2	//r2 <- size of armboot 传递给 C 代码的第三个参数:u-boot 的长度大小(128k)

static void s3c2440_wait_idle(void)
{
        int i;	
        while(!(NFSTAT & BUSY))
        for(i=0; i<10; i++);
}


static void s3c2440_nand_select_chip(void)
{
	int i;	
	NFCONT &= ~(1<<1);
	for(i=0; i<10; i++);   
}
static void s3c2440_nand_deselect_chip(void)
{
	NFCONT |= (1<<1);
}

static void s3c2440_write_cmd(int cmd)
{
	NFCMD = cmd;
}
static void s3c2440_nand_reset(void)
{
	s3c2440_nand_select_chip();
	s3c2440_write_cmd(0xff);  //reset
	s3c2440_wait_idle();
	s3c2440_nand_deselect_chip();//disable chip select 
}
static void s3c2440_write_addr_lp(unsigned int addr)
{
	int i;	
	int col, page;
	col = addr & NAND_BLOCK_MASK_LP;//取NAND_BLOCK_MASK_LP的整数倍得到col
	page = addr / NAND_SECTOR_SIZE_LP;//取NAND_BLOCK_MASK_LP的余数得到row
	
	NFADDR = col & 0xff;			/* Column Address A0~A7 */
	for(i=0; i<10; i++);		
	NFADDR = (col >> 8) & 0x0f;		/* Column Address A8~A11 */
	for(i=0; i<10; i++);
	NFADDR = page & 0xff;			/* Row Address A12~A19 */
	for(i=0; i<10; i++);
	NFADDR = (page >> 8) & 0xff;	/* Row Address A20~A27 */
	for(i=0; i<10; i++);
//if (b128MB == 0)
	NFADDR = (page >> 16) & 0x03;	/* Row Address A28~A29 or 0x01? */
	for(i=0; i<10; i++);
}
static unsigned char s3c2440_read_data(void)
{
	return NFDATA;
}

int nand_read_ll_lp(unsigned char *buf, unsigned long start_addr, int size)
{
	int i, j;
	char dat;	
	if ((start_addr & NAND_BLOCK_MASK_LP) || (size & NAND_BLOCK_MASK_LP))
	{
		return -1;   
	}

	
	s3c2440_nand_select_chip();

	for(i=start_addr; i < (start_addr + size);)
	{
/* Check Bad Block */
if(0){
		int col, page;
		col = i & NAND_BLOCK_MASK_LP;
		page = i / NAND_SECTOR_SIZE_LP;		
		s3c2440_write_cmd(0x00);
		NFADDR = 5;
		for(j=0; j<10; j++);
		NFADDR = 8;
		for(j=0; j<10; j++);
		NFADDR = page & 0xff;		/* Row Address A12~A19 */
		for(j=0; j<10; j++);
		NFADDR = (page >> 8) & 0xff;		/* Row Address A20~A27 */
		for(j=0; j<10; j++);
//if (b128MB == 0)//big page
		NFADDR = (page >> 16) & 0x03;		/* Row Address A28~A29 */
		for(j=0; j<10; j++);
		s3c2440_write_cmd(0x30);
		s3c2440_wait_idle();
		dat = s3c2440_read_data();		
		/*slect chip  */
		s3c2440_nand_deselect_chip();
		if(dat != 0xff)
			i += 131072;		// 1 Block = 2048*64= 131072
/* Read Page */
		/* slect chip */
		s3c2440_nand_select_chip();
}///*end of Check Bad Block */

		/* send read0 cmd */
		s3c2440_write_cmd(0);
		/* Write Address */
		s3c2440_write_addr_lp(i);
		s3c2440_write_cmd(0x30);
		s3c2440_wait_idle();
//NAND_SECTOR_SIZE_LP=2048bytes
		for(j=0; j < NAND_SECTOR_SIZE_LP; j++, i++)
		{
			*buf = s3c2440_read_data();
			buf++;
		}
	}

	/* disable chip select */
	s3c2440_nand_deselect_chip();
 	return 0;
}
/* nor boot return 1*/
int bBootFrmNORFlash(void)
{
	volatile unsigned int *pdw = (volatile unsigned int *)0;
	unsigned int dwVal;
	dwVal = *pdw;      
	*pdw = 0x12345678;
	if (*pdw != 0x12345678)
	{
		return 1;
	}
	else
	{
		*pdw = dwVal;
		return 0;
	}
}
void nand_init_ll(void)
{	
	#define TACLS   0
	#define TWRPH0  3
	#define TWRPH1  0	
	NFCONF = (TACLS<<12)|(TWRPH0<<8)|(TWRPH1<<4);	
	NFCONT = (1<<4)|(1<<1)|(1<<0);	
	s3c2440_nand_reset();
}
int CopyCode2Ram(unsigned long start_addr, unsigned char *buf, int size)
{
	unsigned int *pdwDest;
	unsigned int *pdwSrc;
	int i;	
	if (bBootFrmNORFlash())
	{
		pdwDest = (unsigned int *)buf;
		pdwSrc  = (unsigned int *)start_addr;
		/* boot form NOR Flash*/
		for (i = 0; i < size / 4; i++)
		{
			pdwDest[i] = pdwSrc[i];
		}
		return 0;
	}
	else
	{
		/* init NAND Flash */
		nand_init_ll();		
		nand_read_ll_lp(buf, start_addr, (size + NAND_BLOCK_MASK_LP)&~(NAND_BLOCK_MASK_LP));
         }
    return 0;
}

 5、修改链接文件,,在 cpu/arm920t/u-boot.lds 中,这个 u-boot 启动连接脚本文件决定了 u-boot 运行的入口地址,以及各个段的存储位置,这也是链接定位的作用。添加下面两行代码的主要目的是防止编译器把我们自己添加的用于 nandboot 的子函数放到 4K 之后,否则是无法启动的。如下:

.text :
{
cpu/arm920t/start.o (.text)
board/samsung/rocko2440/lowlevel_init.o (.text)
board/samsung/rocko2440/nand_read.o (.text)
*(.text)

6、到此完成了对从nandflash启动的支持,下面修改uboot启动时命令行前的名字。

[root@fzliu u-boot-2009.11]# vim include/configs/rocko2440.h //修改命令行前的名字

#define CONFIG_SYS_PROMPT   "[rocko2440]#"  //将命令行前的名字改成[rocko2440]

7、[root@fzliu u-boot-2009.11]# make 将生成的u-boot.bin 下载到nandflash中,从nandflash启动,将会看到如下信息:

U-Boot 2009.11 (Oct 24 2011 - 18:12:47)

DRAM:  64 MB
## Unknown FLASH on Bank 0: ID 0xffff, Size = 0x00000000 = 0 MB
Flash:  0 kB
*** Warning - bad CRC, using default environment

In:    serial
Out:   serial
Err:   serial
Net:   CS8900-0
[rocko2440]#

8、现在的 Nand 还不能做任何事情,而且也没有显示有关 Nand 的任何信息,所以只能说明上面的这些步骤只是完成了 Nand 移植的 Stage1 部分。关于stage2的nandflash驱动移植将在后面补上。

 

你可能感兴趣的:(u-boot-2009-11移植之stage1(支持从nand启动))