您的位置:首页 > 其它

u-boot-1.1.6支持从nand flash启动

2011-11-03 13:04 239 查看
转自 http://zqwt.012.blog.163.com/blog/static/120446842010471163568/
编译支持nand flash启动u-boot

1、 从Nand Flash启动U-BOOT的基本原理

l 前4K的问题

如果S3C2410被配置成从Nand Flash启动, S3C2410的Nand Flash控制器有一个特殊的功能:

在S3C2410上电后,Nand Flash控制器会自动的把Nand Flash上的前4K数据搬移到4K内部RAM中,并把0x00000000设置内部RAM的起始地址,CPU从内部RAM的0x00000000位置开始启动。这个过程不需要程序干涉。

更准确的解释为:NAND Flash不对应任何BANK(根据S3C2410x数据手册),它是通过几组寄存器来访问的,在上电后,NAND Flash开始的4k数据被自动地复制到芯片内部一个被称为“Steppingstone”的RAM上。Steppingstone被映射为地址0,上面的4k程序完成必要的初始化;

由于设置SDRAM需要访问13个寄存器(根据S3C2410x数据手册),只要我们设置好了这13个寄存器,SDRAM的使用就很简单了。最终,我们还是要把程序本身从Steppingstone复制到SDRAM的u-boot

镜像存储起始地址处(_TEXT_BASE=0x33f80000),然后跳到SDRAM中执行。

我们目前需要完成的工作,是把最核心的启动程序放在Nand Flash的前4K中。

l 启动程序的安排

由于Nand Flash控制器从Nand Flash中搬移到内部RAM的代码是有限的,所以在启动代码的前4K里,我们必须完成S3C2410的核心配置以及把启动代码(U-BOOT)剩余部分搬到RAM中运行。

2、具体实现

u-boot源码不支持从nand flash启动,可是s3c2410支持从nand flash启动,开发板加电后s3c2410将nand flash的前4k(保存有u-boot的部分功能--拷贝功能--把nand
flash中的内容拷贝到SDRAM)拷贝到sram(s3c2410芯片内的sram,称为Steppingstone)。这就需要修改u-boot源码,增加u-boot的功能:
使u-boot在得到执行权后能够将其自身拷贝到开发板上SDRAM中,以便处理器能够执行u-boot。

# cd u-boot-1.1.6

在board/diamond2410加入NAND Flash读函数,建立nand_read.c,加入如下内容(copy from vivi):

# vi board/diamond2410/nand_read.c

#include <config.h>

#define __REGb(x) (*(volatile unsigned char *)(x))

#define __REGi(x) (*(volatile unsigned int *)(x))

#define NF_BASE 0x4e000000

#define NFCONF __REGi(NF_BASE + 0x0)

#define NFCMD __REGb(NF_BASE + 0x4)

#define NFADDR __REGb(NF_BASE + 0x8)

#define NFDATA __REGb(NF_BASE + 0xc)

#define NFSTAT __REGb(NF_BASE + 0x10)

#define BUSY 1

inline void wait_idle(void) {

int i;

while(!(NFSTAT & BUSY))

for(i=0; i<10; i++);

}

#define NAND_SECTOR_SIZE 512

#define NAND_BLOCK_MASK (NAND_SECTOR_SIZE - 1)

/* low level nand read function */

int nand_read_ll(unsigned char *buf,

unsigned long start_addr,

int size)

{

int i, j;

if ((start_addr & NAND_BLOCK_MASK) || (size & NAND_BLOCK_MASK)) {

return -1; /* invalid alignment */

}

/* chip Enable */

NFCONF &= ~0x800;

for(i=0; i<10; i++);

for(i=start_addr; i < (start_addr + size);) {

/* READ0 */

NFCMD = 0;

/* Write Address */

NFADDR = i & 0xff;

NFADDR = (i >> 9) & 0xff;

NFADDR = (i >> 17) & 0xff;

NFADDR = (i >> 25) & 0xff;

wait_idle();

for(j=0; j < NAND_SECTOR_SIZE; j++, i++) {

*buf = (NFDATA & 0xff);

buf++;

}

}

/* chip Disable */

NFCONF |= 0x800; /* chip disable */

return 0;

}


# vi board/diamond2410/Makefile

COBJS := sbc2410x.o flash.o ==>

COBJS := sbc2410x.o flash.o nand_read.o

# vi cpu/arm920t/start.S

-----------------------------------------------

从Nand Flash中把数据拷贝到RAM,是由copy_myself程序段完成

(1) 在"ldr pc, _start_armboot"之前加入(223行):

#ifdef CONFIG_S3C2410_NAND_BOOT

bl copy_myself

@ jump to ram

ldr r1, =on_the_ram

add pc, r1, #0

nop

nop

1: b 1b @ infinite loop

on_the_ram:

#endif


(2) 在"_start_armboot: .word start_armboot"之后加入:

#ifdef CONFIG_S3C2410_NAND_BOOT

copy_myself:

mov r10, lr

@ reset NAND

mov r1, #NAND_CTL_BASE

ldr r2, =0xf830 @ initial value

str r2, [r1, #oNFCONF]

ldr r2, [r1, #oNFCONF]

bic r2, r2, #0x800 @ enable chip

str r2, [r1, #oNFCONF]

mov r2, #0xff @ RESET command

strb r2, [r1, #oNFCMD]

mov r3, #0 @ wait

1:add r3, r3, #0x1

cmp r3, #0xa

blt 1b

2:ldr r2, [r1, #oNFSTAT] @ wait ready

tst r2, #0x1

beq 2b

ldr r2, [r1, #oNFCONF]

orr r2, r2, #0x800 @ disable chip

str r2, [r1, #oNFCONF]

@ get read to call C functions (for nand_read())

ldr sp, DW_STACK_START @ setup stack pointer

mov fp, #0 @ no previous frame, so fp=0

@ copy vivi to RAM

ldr r0, =UBOOT_RAM_BASE

mov r1, #0x0

mov r2, #0x20000

bl nand_read_ll

tst r0, #0x0

beq ok_nand_read

#ifdef CONFIG_DEBUG_LL

bad_nand_read:

ldr r0, STR_FAIL

ldr r1, SerBase

bl PrintWord

1:b 1b @ infinite loop

#endif

ok_nand_read:

#ifdef CONFIG_DEBUG_LL

ldr r0, STR_OK

ldr r1, SerBase

bl PrintWord

#endif

@ verify

mov r0, #0

ldr r1, =UBOOT_RAM_BASE

mov r2, #0x400 @ 4 bytes * 1024 = 4K-bytes

go_next:

ldr r3, [r0], #4

ldr r4, [r1], #4

teq r3, r4

bne notmatch

subs r2, r2, #4

beq done_nand_read

bne go_next

notmatch:

#ifdef CONFIG_DEBUG_LL

sub r0, r0, #4

ldr r1, SerBase

bl PrintHexWord

ldr r0, STR_FAIL

ldr r1, SerBase

bl PrintWord

#endif

1:b 1b @ infinite loop

done_nand_read:

#ifdef CONFIG_DEBUG_LL

ldr r0, STR_OK

ldr r1, SerBase

bl PrintWord

#endif

mov pc, r10

@ clear memory

@ r0: start address

@ r1: length

mem_clear:

mov r2, #0

mov r3, r2

mov r4, r2

mov r5, r2

mov r6, r2

mov r7, r2

mov r8, r2

mov r9, r2

clear_loop:

stmia r0!, {r2-r9}

subs r1, r1, #(8 * 4)

bne clear_loop

mov pc, lr

#endif @ CONFIG_S3C2410_NAND_BOOT


(3) 在文件的最后加入:

.align 2

DW_STACK_START:

.word STACK_BASE+STACK_SIZE-4


# vi include/configs/diamond2410.h

-----------------------------------------------

(1) 将CONFIG_SERVERIP设置为主机IP

这样以后在通过网络下载内核映像时,就不用就该IP地址了。(这一项修改与nand flash没有关系)

#define CONFIG_SERVERIP 202.194.124.56

(2) 在文件末尾添加如下内容

/*

* Nandflash Boot

*/

#define CONFIG_S3C2410_NAND_BOOT 1

#define STACK_BASE 0x33f00000

#define STACK_SIZE 0x8000

#define UBOOT_RAM_BASE 0x33f80000

/* NAND Flash Controller */

#define NAND_CTL_BASE 0x4E000000

#define bINT_CTL(Nb) __REG(INT_CTL_BASE + (Nb))

/* Offset */

#define oNFCONF 0x00

#define oNFCMD 0x04

#define oNFADDR 0x08

#define oNFDATA 0x0c

#define oNFSTAT 0x10

#define oNFECC 0x14
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: 
相关文章推荐