加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

u-boot的NAND Flash启动

发布时间:2020-12-15 18:11:00 所属栏目:百科 来源:网络整理
导读:? u-boot-2010.12 移植到 2440 支持 nand flash 启动 http://www.linuxidc.com/Linux/2011-02/32772p4.htm ? [ 日期: 2011-02-28] 来源: Linux 社区 ? 作者: bscbem [ 字体:大中小 ]? ? ? 在这篇中,我们将移植 nand flash 部分,支持 NAND 启动及 NAND

?

u-boot-2010.12移植到2440

支持nand flash启动

http://www.linuxidc.com/Linux/2011-02/32772p4.htm

?

[日期:2011-02-28]来源:Linux社区?作者:bscbem [字体:大中小]?

?

?

在这篇中,我们将移植nand flash部分,支持NAND启动及NAND FLASH的读写访问。

首先,我们在u-boot-2010.12includeconfigssmdk2440.h中注销如下定义。

?//#define? CONFIG_ENV_IS_IN_FLASH??? 1

//#define CONFIG_ENV_SIZE?????????? 0x10000? /* Total Size of Environment Sector */

增加如下定义:

/*以下为NAND启动及驱动相关*/

#define CONFIG_S3C2440_NAND_BOOT? 1

#define CONFIG_NAND_S3C2440

#define NAND_CTL_BASE? 0x4E000000? //Nand Flash配置寄存器基地址,查2440手册可得知

#define oNFCONF? 0x00 //相对Nand配置寄存器基地址的偏移量,还是配置寄存器的基地址

#define oNFCONT? 0x04 //相对Nand配置寄存器基地址的偏移量,可得到控制寄存器的基地址(0x4E000004)

#define oNFADDR? 0x0c //相对Nand配置寄存器基地址的偏移量,可得到地址寄存器的基地址(0x4E00000c)

#define oNFDATA? 0x10 //相对Nand配置寄存器基地址的偏移量,可得到数据寄存器的基地址(0x4E000010)

#define oNFCMD?? 0x08 //相对Nand配置寄存器基地址的偏移量,可得到指令寄存器的基地址(0x4E000008)

#define oNFSTAT? 0x20 //相对Nand配置寄存器基地址的偏移量,可得到状态寄存器的基地址(0x4E000020)

#define oNFECC ??0x2c //相对Nand配置寄存器基地址的偏移量,可得到ECC寄存器的基地址(0x4E00002c)

#define UBOOT_LENGTH? 0x40000 /*256K*/

#define STACK_BASE? 0x33f00000???? //定义堆栈的地址

#define STACK_SIZE? 0x8000???????? //堆栈的长度大小

?

?

?

#define CONFIG_CMD_NAND

?

#define CONFIG_CMDLINE_EDITING

?

#ifdef CONFIG_CMDLINE_EDITING

?

#undef CONFIG_AUTO_COMPLETE

?

#else

?

#define CONFIG_AUTO_COMPLETE

?

#endif

?

?

?

/* NAND flash settings */

#if defined(CONFIG_CMD_NAND)

#define CONFIG_SYS_NAND_BASE??????????? 0x4E000000 //Nand配置寄存器基地址

?

#define CONFIG_SYS_MAX_NAND_DEVICE????? 1

?

#define CONFIG_MTD_NAND_VERIFY_WRITE??? 1

?

//#define NAND_SAMSUNG_LP_OPTIONS?????? 1? //注意:我们这里是64MNand Flash,所以不用,如果是128M的大块Nand Flash,则需加上

?

#endif

?

?

?

//添加环境变量保存到Nand的宏(注意:如果你要使用从Nor启动的saveenv命令,则不要这些Nand宏定义)

?

#define CONFIG_ENV_IS_IN_NAND ?1

?

#define CONFIG_ENV_OFFSET????? 0x30000 //将环境变量保存到nand中的0x30000位置

?

#define CONFIG_ENV_SIZE??????? 0x10000 /* Total Size of Environment Sector */

?

archarmcpuarm920tstart.S文件中增加如下代码:

?

?

?

#ifndef CONFIG_SKIP_LOWLEVEL_INIT

?

?????? bl??? cpu_init_crit

?

#endif

?

?

?

//下面添加2440u-bootNand Flash启动

?

?

?

#ifdef CONFIG_S3C2440_NAND_BOOT

?

??? mov r1,#NAND_CTL_BASE?? //复位Nand Flash

?

??? ldr r2,=( (7<<12)|(7<<8)|(7<<4)|(0<<0) )

?

??? str r2,[r1,#oNFCONF]?? //设置配置寄存器的初始值,参考s3c2440手册

?

??? ldr r2,#oNFCONF]

?

?

?

??? ldr r2,=( (1<<4)|(0<<1)|(1<<0) )

?

??? str r2,#oNFCONT]?? //设置控制寄存器

?

??? ldr r2,#oNFCONT]

?

?

?

??? ldr r2,=(0x6)?????????? //RnB Clear

?

??? str r2,#oNFSTAT]

?

??? ldr r2,#oNFSTAT]

?

??? mov r2,#0xff??????????? //复位command

?

??? strb r2,#oNFCMD]

?

?

?

??? mov r3,#0?????????????? //等待

?

nand1:

?

??? add r3,r3,#0x1

?

??? cmp r3,#0xa

?

??? blt nand1

?

?

?

nand2:

?

??? ldr r2,#oNFSTAT]?? //等待就绪

?

??? tst r2,#0x4

?

??? beq nand2

?

?

?

??? ldr r2,#oNFCONT]

?

??? orr r2,r2,#0x2???????? //取消片选

?

??? str r2,#oNFCONT]

?

?

?

??? //get read to call C functions (for nand_read())

?

??? ldr sp,DW_STACK_START?? //C代码准备堆栈,DW_STACK_START定义在下面

?

??? mov fp,#0??????????????

?

?

?

??? //copy U-Boot to RAM

?

??? ldr r0,=CONFIG_SYS_LOAD_ADDR//传递给C代码的第一个参数:u-bootRAM中的起始地址 //暂时为这个值

?

??? mov r1,#0x0????? //传递给C代码的第二个参数:Nand Flash的起始地址

?

??? mov r2,#UBOOT_LENGTH? //传递给C代码的第三个参数:u-boot的长度大小

?

??? bl nand_read_ll?? //此处调用C代码中读Nand的函数,现在还没有要自己编写实现

?

??? tst r0,#0x0

?

??? beq ok_nand_read

?

?

?

bad_nand_read:

?

??? loop2: b loop2??? //infinite loop

?

?

?

ok_nand_read:

?

??? //检查搬移后的数据,如果前4k完全相同,表示搬移成功

?

??? mov r0,#0

?

??? ldr r1,=CONFIG_SYS_LOAD_ADDR//暂时为这个值

?

??? 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,#4

?

??? beq board_init_f

?

??? bne go_next

?

?

?

notmatch:

?

??? loop3: b loop3?????????? //infinite loop

?

#endif //CONFIG_S3C2440_NAND_BOOT

?

?

?

.align 2?? /*add by bsc 2010-2-6 13:11*/

?

DW_STACK_START: .word STACK_BASE+STACK_SIZE-4

?

?

?

增加从NAND FLASH读取数据到内存的函数,文件名为nand_read.c放到boardsamsungsmdk2440nand_read.c下。

?

#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_CHIP_ENABLE? (NFCONT &= ~(1<<1))? //Nand片选使能

?

#define NAND_CHIP_DISABLE (NFCONT |= (1<<1))?? //取消Nand片选

?

#define NAND_CLEAR_RB???? (NFSTAT |= (1<<2))

?

#define NAND_DETECT_RB??? { while(! (NFSTAT&(1<<2)) );}

?

?

?

?

?

#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; //地址或长度不对齐

?

??? }

?

?

?

??? NAND_CHIP_ENABLE; //选中Nand片选

?

?

?

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

?

??? {

?

??????? //发出READ0指令

?

?

?

??????? NAND_CLEAR_RB;

?

??????? NFCMD = 0;

?

?

?

??????? //Nand进行寻址

?

??????? NFADDR = i & 0xFF;

?

?

?

??????? NFADDR = (i >> 9) & 0xFF;

?

??????? NFADDR = (i >> 17) & 0xFF;

?

??????? NFADDR = (i >> 25) & 0xFF;

?

?

?

??????? NAND_DETECT_RB;

?

?

?

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

?

??????? {

?

??????????? *buf = (NFDATA & 0xFF);

?

??????????? buf++;

?

??????? }

?

??? }

?

?

?

??? NAND_CHIP_DISABLE; //取消片选信号

?

?

?

??? return 0;

?

}

?

?

?

修改board/samsung/smdk2440/ makefile

?

COBJS??? := smdk2440.o flash.o nand_read.o

?

?

?

drivers/mtd/nand/s3c2440_nand.c?目录下新建s3c2440_nand.c文件实现对nand FLASH的操作。

?

?

?

#include <common.h>

?

?

?

#if 0

?

#define DEBUGN??? printf

?

#else

?

#define DEBUGN(x,args ...) {}

?

#endif

?

?

?

#include <nand.h>

?

#include <asm/arch/s3c24x0_cpu.h>

?

#include <asm/io.h>

?

?

?

?

?

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

?

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

?

?

?

?

?

#define NF_BASE? 0x4e000000???????????? //Nand配置寄存器基地址

?

#define NFCONF?? __REGi(NF_BASE + 0x0)? //偏移后还是得到配置寄存器基地址

?

#define NFCONT?? __REGi(NF_BASE + 0x4)? //偏移后得到Nand控制寄存器基地址

?

#define NFCMD??? __REGb(NF_BASE + 0x8)? //偏移后得到Nand指令寄存器基地址

?

#define NFADDR?? __REGb(NF_BASE + 0xc)? //偏移后得到Nand地址寄存器基地址

?

#define NFDATA?? __REGb(NF_BASE + 0x10) //偏移后得到Nand数据寄存器基地址

?

#define NFMECCD0 __REGi(NF_BASE + 0x14) //偏移后得到Nand主数据区域ECC0寄存器基地址

?

#define NFMECCD1 __REGi(NF_BASE + 0x18) //偏移后得到Nand主数据区域ECC1寄存器基地址

?

#define NFSECCD? __REGi(NF_BASE + 0x1C) //偏移后得到Nand空闲区域ECC寄存器基地址

?

#define NFSTAT?? __REGb(NF_BASE + 0x20) //偏移后得到Nand状态寄存器基地址

?

#define NFSTAT0? __REGi(NF_BASE + 0x24) //偏移后得到Nand ECC0状态寄存器基地址

?

#define NFSTAT1? __REGi(NF_BASE + 0x28) //偏移后得到Nand ECC1状态寄存器基地址

?

#define NFMECC0? __REGi(NF_BASE + 0x2C) //偏移后得到Nand主数据区域ECC0状态寄存器基地址

?

#define NFMECC1? __REGi(NF_BASE + 0x30) //偏移后得到Nand主数据区域ECC1状态寄存器基地址

?

#define NFSECC?? __REGi(NF_BASE + 0x34) //偏移后得到Nand空闲区域ECC状态寄存器基地址

?

#define NFSBLK?? __REGi(NF_BASE + 0x38) //偏移后得到Nand块开始地址

?

#define NFEBLK?? __REGi(NF_BASE + 0x3c) //偏移后得到Nand块结束地址

?

?

?

#define S3C2440_NFCONT_nCE? (1<<1)

?

#define S3C2440_ADDR_NALE?? 0x0c

?

#define S3C2440_ADDR_NCLE?? 0x08

?

?

?

ulong IO_ADDR_W = NF_BASE;

?

?

?

static void s3c2440_hwcontrol(struct mtd_info *mtd,int cmd,unsigned int ctrl)

?

{

?

??? struct nand_chip *chip = mtd->priv;

?

?

?

??? DEBUGN("hwcontrol(): 0x%02x 0x%02xn",cmd,ctrl);

?

?

?

??? if (ctrl & NAND_CTRL_CHANGE) {

?

??????? IO_ADDR_W = NF_BASE;

?

?

?

??????? if (!(ctrl & NAND_CLE))??????????????? //要写的是地址

?

??????????? IO_ADDR_W |= S3C2440_ADDR_NALE;

?

???? ???if (!(ctrl & NAND_ALE))??????????????? //要写的是命令

?

??????????? IO_ADDR_W |= S3C2440_ADDR_NCLE;

?

?

?

??????? if (ctrl & NAND_NCE)

?

??????????? NFCONT &= ~S3C2440_NFCONT_nCE;??? //使能nand flash

?

??????? else

?

??????????? NFCONT |= S3C2440_NFCONT_nCE;???? //禁止nand flash

?

??? }

?

?

?

??? if (cmd != NAND_CMD_NONE)

?

??????? writeb(cmd,(void *)IO_ADDR_W);

?

}

?

?

?

static int s3c2440_dev_ready(struct mtd_info *mtd)

?

{

?

??? DEBUGN("dev_readyn");

?

??? return (NFSTAT & 0x01);

?

}

?

?

?

int board_nand_init(struct nand_chip *nand)

?

{

?

??? u_int32_t cfg;

?

??? u_int8_t tacls,twrph0,twrph1;

?

????????????? struct s3c24x0_clock_power * const clk_power = s3c24x0_get_base_clock_power();

?

?

?

??? DEBUGN("board_nand_init()n");

?

?

?

??? /*clk_power->CLKCON |= (1 << 4);*/

?

??? writel(readl(&clk_power->clkcon) | (1 << 4),&clk_power->clkcon);

?

?

?

??? twrph0 = 4; twrph1 = 2; tacls = 0;

?

?

?

??? cfg = (tacls<<12)|(twrph0<<8)|(twrph1<<4);

?

??? NFCONF = cfg;

?

?

?

??? cfg = (1<<6)|(1<<4)|(0<<1)|(1<<0);

?

??? NFCONT = cfg;

?

?

?

??? /* initialize nand_chip data structure */

?

??? nand->IO_ADDR_R = nand->IO_ADDR_W = (void *)0x4e000010;

?

?

?

??? /* read_buf and write_buf are default */

?

??? /* read_byte and write_byte are default */

?

?

?

??? /* hwcontrol always must be implemented */

?

??? nand->cmd_ctrl = s3c2440_hwcontrol;

?

?

?

??? nand->dev_ready = s3c2440_dev_ready;

?

?

?

??? return 0;

?

}

?

然后,在drivers/mtd/nand/Makefile文件中添加s3c2440_nand.c的编译项,如下:

?

COBJS-$(CONFIG_NAND_S3C2440) += s3c2440_nand.o

?

u-boot-2010.12includeconfigssmdk2440.h中增加宏定义:

?

# define? CONFIG_NAND_S3C2440

?

?

?

重新编译,将u-boot.bin下载到内存运行,可以运行,FLASH也正常的读写。注意,此时我们的uboot还不支持从NAND FLASH启动,前面的步骤只是为了调试方便,我们将可以看到在内存中运行的u-boot成功的将NAND FLASH中的数据拷贝到了内存中CONFIG_SYS_LOAD_ADDR的位置。接下来我们让其支持在NAND FLASH中的启动。

?

?

?

将上面的ldr r0,=CONFIG_SYS_LOAD_ADDRldr r1,=CONFIG_SYS_LOAD_ADDR替换为ldr r0,=CONFIG_SYS_TEXT_BASEldr r1,=CONFIG_SYS_TEXT_BASE

?

?

?

通过查看u-boot.map可以看到,我们的nand_read_ll()函数被连接在4K之后的位置,所以根本无法再启动时实现数据到内存的拷贝。因此我们根据网友的说法修改archarmcpuarm920tu-boot.lds如下:

?

.text :

?

?????? {

?

????????????? arch/arm/cpu/arm920t/start.o (.text)

?

????????????? board/samsung/smdk2440/lowlevel_init.o??? (.text)

?

????????????? board/samsung/smdk2440/nand_read.o (.text)

?

????????????? *(.text)

?

?????? }

?

编译发现,编译通不过,出现重定义的错误。这可能是新版本的编译和连接规则有变化导致的,具体原因还不清楚,因此我们采用其他的办法。

?

board/samsung/smdk2440/libsmdk2440.o: In function `nand_read_ll':

?

/home/bsc/samba/u-boot-2010.12/board/samsung/smdk2440/nand_read.c:30: multiple definition of `nand_read_ll'

?

board/samsung/smdk2440/nand_read.o:/home/bsc/samba/u-boot-2010.12/board/samsung/smdk2440/nand_read.c:30: first defined here

?

board/samsung/smdk2440/libsmdk2440.o: In function `lowlevel_init':

?

/home/bsc/samba/u-boot-2010.12/board/samsung/smdk2440/lowlevel_init.S:137: multiple definition of `lowlevel_init'

?

board/samsung/smdk2440/lowlevel_init.o:/home/bsc/samba/u-boot-2010.12/board/samsung/smdk2440/lowlevel_init.S:137: first defined here

?

make: *** [u-boot] 错误 1

?

这可能是新版本的编译和连接规则有变化导致的,具体原因还不清楚,因此我们采用其他的办法。修改archarmcpuarm920tu-boot.lds如下:

?

.text :

?

?????? {

?

????????????? arch/arm/cpu/arm920t/start.o (.text)

?

????????????? board/samsung/smdk2440/ libsmdk2440.o??? (.text)

?

arch/arm/lib/libarm.o???? (.text)

?

????????????? *(.text)

?

?????? }

?

编译之后发现,board_init_f函数还是超过了4K,我们只能对前面的代码进行瘦身了,我们的目标板没有NOR FLASH,所以我们取消NOR FLASH的支持。

?

u-boot-2010.12includeconfigssmdk2440.h中增加宏定义:

?

/*去掉NOR FLASH支持*/

?

#define CONFIG_SYS_NO_FLASH

?

#define CONFIG_CMD_FLASH? /* flinfo,erase,protect?? */

?

#define CONFIG_CMD_IMLS??????????? /* List all found images? */

?

修改board/samsung/smdk2440/ makefile,取消对flash的编译。

?

COBJS??? := smdk2440.o nand_read.o

?

编译后下载到内存,杯具又发生了,跑进board_init_r()函数的时候死机了。至此相当的郁闷了,没办法再修改archarmcpuarm920tu-boot.lds如下:

?

.text :

?

?????? {

?

????????????? arch/arm/cpu/arm920t/start.o (.text)

?

????????????? board/samsung/smdk2440/ libsmdk2440.o??? (.text)

?

??????? ??????*(.text)

?

?????? }

?

在编译,下载到内存运行,可以运行。但是还是相当杯具的,通过查看u-boot.map可以看到arch/arm/lib/libarm.o被连接到了4K之外,4K之内没有这个程序我们是不可能实现NAND启动的。但是天无绝人之路,我们可以让U-boot提前进入内存运行。思路是,我们提前将代码拷贝到内存中,提前跳转到内存中运行不再回来。修改archarmcpuarm920tstart.S文件如下:

?

?

?

#ifndef CONFIG_SKIP_LOWLEVEL_INIT

?

?????? bl??? cpu_init_crit

?

#endif

?

?

?

//下面添加2440u-bootNand Flash启动

?

#ifdef CONFIG_S3C2440_NAND_BOOT

?

??? mov r1,=CONFIG_SYS_TEXT_BASE//传递给C代码的第一个参数:u-bootRAM中的起始地址

?

??? mov r1,=CONFIG_SYS_TEXT_BASE

?

??? mov r2,#4

?

??? beq relocations?????? /*注意此句,直接跳转到relocate_code函数的调整部分,因为我们不打算在board_init_f()函数中再回来了*/

?

??? bne go_next

?

?

?

notmatch:

?

??? loop3: b loop3?????????? //infinite loop

?

?

?

#endif //CONFIG_S3C2440_NAND_BOOT

?

?

?

/*------------------------------------------------------------------------------*/

?

?

?

/*

?

?* void relocate_code (addr_sp,gd,addr_moni)

?

?*

?

?* This "function" does not return,instead it continues in RAM

?

?* after relocating the monitor code.

?

?*

?

?*/

?

?????? .globl????? relocate_code

?

relocate_code:

?

?????? mov r4,r0????? /* save addr_sp */

?

?????? mov r5,r1????? /* save addr of gd */

?

?????? mov r6,r2????? /* save addr of destination */

?

?

?

?????? /* Set up the stack???????????????????????????????????????? */

?

stack_setup:

?

?????? mov sp,r4

?

??????

?

?????? adr?? r0,_start

?

?????? cmp r0,r6

?

?????? beq? clear_bss??????? /* skip relocation */

?

?????? mov r1,r6??????????????????? /* r1 <- scratch for copy_loop */

?

?????? ldr?? r2,_TEXT_BASE

?

?????? ldr?? r3,_bss_start_ofs

?

?????? add? r2,r0,r3??????? /* r2 <- source end address??????? */

?

?

?

copy_loop:

?

?????? ldmia????? r0!,{r9-r10}???????? /* copy from source address [r0]??? */

?

?????? stmia?????? r1!,{r9-r10}???????? /* copy to?? target address [r1]??? */

?

?????? cmp r0,r2??????????????????? /* until source end address [r2]??? */

?

?????? blo?? copy_loop

?

??????

?

relocations:???? /*增加标号,以便跳转到这里*/

?

?????? ldr r6,=CONFIG_SYS_TEXT_BASE /*注意,R6下面被用到表示新的目标地址*/

?

?

?

#ifndef CONFIG_PRELOADER

?

?????? /*

?

??????? * fix .rel.dyn relocations

?

??????? */

?

??????

?

?????? ldr?? r0,_TEXT_BASE???????? /* r0 <- Text base */

?

?????? sub? r9,r6,r0??????? /* r9 <- relocation offset */

?

?????? ldr?? r10,_dynsym_start_ofs? /* r10 <- sym table ofs */

?

?????? add? r10,r10,r0??????????? /* r10 <- sym table in FLASH */

?

?????? ldr?? r2,_rel_dyn_start_ofs??? /* r2 <- rel dyn start ofs */

?

?????? add? r2,r0??????? /* r2 <- rel dyn start in FLASH */

?

?????? ldr?? r3,_rel_dyn_end_ofs???? /* r3 <- rel dyn end ofs */

?

?????? add? r3,r0??????? /* r3 <- rel dyn end in FLASH */

?

fixloop:

?

?????? ldr?? r0,[r2]?????????? /* r0 <- location to fix up,IN FLASH! */

?

?????? add? r0,r9??????? /* r0 <- location to fix up in RAM */

?

?????? ldr?? r1,[r2,#4]

?

?????? and? r7,r1,#0xff

?

?????? cmp r7,#23????????????????? /* relative fixup? */

?

?????? beq? fixrel

?

?????? cmp r7,#2??????????????????? /* absolute fixup? */

?

?????? beq? fixabs

?

?????? /* ignore unknown type of fixup */

?

?????? b???? fixnext

?

fixabs:

?

?????? /* absolute fix: set location to (offset) symbol value */

?

?????? mov r1,LSR #4????????????? /* r1 <- symbol index in .dynsym */

?

?????? add? r1,r1???????????? /* r1 <- address of symbol in table */

?

?????? ldr?? r1,#4]??????????? /* r1 <- symbol value */

?

?????? add? r1,r9??????? /* r1 <- relocated sym addr */

?

?????? b???? fixnext

?

fixrel:

?

?????? /* relative fix: increase location by offset */

?

?????? ldr?? r1,[r0]

?

?????? add? r1,r9

?

fixnext:

?

?????? str??? r1,[r0]

?

?????? add? r2,#8??????? /* each rel.dyn entry is 8 bytes */

?

?????? cmp r2,r3

?

?????? blo?? fixloop

?

#endif

?

?

?

clear_bss:

?

#ifndef CONFIG_PRELOADER

?

?????? ldr?? r0,_bss_start_ofs

?

?????? ldr?? r1,_bss_end_ofs

?

?????? ldr?? r3,_TEXT_BASE???????? /* Text base */

?

?????? mov r4,r6???????????? /* reloc addr */

?

?????? add? r0,r3???? /*注意此句修改*/

?

?

?????? add? r1,r3??? /*注意此句修改*/

?

?????? mov r2,#0x00000000?????????? /* clear????????????????????? */

?

?

?

clbss_l:str?????? r2,[r0]?????????? /* clear loop...????????????????? */

?

?????? add? r0,#4

?

?????? cmp r0,r1

?

?????? bne? clbss_l

?

/*

?

?????? bl coloured_LED_init

?

?????? bl red_LED_on

?

*//* by bsc 2011/2/23 13:44:29*/

?

#endif

?

?

?

/* Set stackpointer in internal RAM to call board_init_f */

?

call_board_init_f:

?

?????? ldr?? sp,=(CONFIG_SYS_INIT_SP_ADDR)

?

?????? bic?? sp,sp,#7 /* 8-byte alignment for ABI compliance */

?

?????? ldr?? r0,=0x00000000

?

?????? /*bl? board_init_f*/ /*删除此句,我们用绝对地址跳转到内存去了,不再回来了*/

?

?????? ldr pc,_board_init_f???? /*增加此句,我们用绝对地址跳转到内存去了,不再回来了*/

?

??????

?

_board_init_f:??????? /*增加此句,我们用绝对地址跳转到内存去了,不再回来了*/

?

?????? .word board_init_f

?

/*

?

?* We are done. Do not return,instead branch to second part of board

?

?* initialization,now running from RAM.

?

?*/

?

#ifdef CONFIG_NAND_SPL

?

?????? ldr???? r0,_nand_boot_ofs

?

?????? mov pc,r0

?

?

?

_nand_boot_ofs:

?

?????? .word nand_boot

?

#else

?

?????? ldr?? r0,_board_init_r_ofs

?

?????? adr?? r1,_start

?

?????? add? lr,r1

?

?????? add? lr,lr,r9

?

?????? /* setup parameters for board_init_r */

?

?????? mov r0,r5???????????? /* gd_t */

?

?????? mov r1,r6???????????? /* dest_addr */

?

?????? /* jump to it ... */

?

?????? mov pc,lr

?

?

?

_board_init_r_ofs:

?

?????? .word board_init_r - _start

?

#endif

?

?

?

_rel_dyn_start_ofs:

?

?????? .word __rel_dyn_start - _start

?

_rel_dyn_end_ofs:

?

?????? .word __rel_dyn_end - _start

?

_dynsym_start_ofs:

?

?????? .word __dynsym_start - _start

?

?

?

.align 2?? /*add by bsc 2010-2-6 13:11*/

?

DW_STACK_START: .word STACK_BASE+STACK_SIZE-4

?

修改完archarmcpuarm920tstart.S文件之后,我们会发现,有一句非常重要的代码被我们删除再也执行不到了,那就是设置堆栈指针:mov sp,r4

?

因此我们需要在board_init_f()函数中设置。

?

修改archarmlibboard.c代码如下:

?

?

?

首先将board_init_f()与board_init_r()函数的顺序调换下,因为我们要在board_init_f()中调用board_init_r()。

?

?

?

gd->mon_len = 0x700000 ; /*修改此句以保证与配置的一致性add by bsc?具体原因请查看代码中对此变量的使用即可明白,注意我们的 _TEXT_BASE=0x33f80000*/

?

?

?

函数最后:

?

__asm__ __volatile__("mov sp,%0"::"r"(addr_sp):"sp");/*add by bsc 2011/2/24 15:17:48*/

?

?????????????

?

#ifdef CONFIG_S3C2440_NAND_BOOT?? /*add by bsc 2011/2/24 15:18:04*/

?

?????? board_init_r(id,addr);

?

#else

?

?????? relocate_code (addr_sp,id,addr);

?

?????? /* NOTREACHED - relocate_code() does not return */

?

#endif

?

?????? /*relocate_code (addr_sp,addr);*//*add by bsc 2011/2/24 15:18:28*/

?

?????? /* NOTREACHED - relocate_code() does not return */

?

?

?

然后修改boardsamsungsmdk2440config.mk如下:

?

CONFIG_SYS_TEXT_BASE = 0x33f80000

?

?

?

然后修改includeconfigssmdk2440.h如下:

?

增加宏定义:

?

#define UBOOT_LENGTH? 0x40000 /*uboot大小256K*/

?

删除宏定义:

?

#define CONFIG_SKIP_LOWLEVEL_INIT /*在内存中调试时增加此宏定义 by bsc */

?

?

?

然后编译,烧写到NAND FLASH中,重启之后你会发现,终于可以运行啦。

?

测试中发现,go命令好像有问题,直接死机了,其他一切正常。

?

如果你还想看到u-boot启动时的输出版本信息等,修改archarmlibboard.c代码如下:board_init_r函数中修改

?

?? board_init();??? /* Setup chipselects */

?

#ifdef CONFIG_SERIAL_MULTI

??? serial_initialize();

#endif

?

??? debug ("Now running in RAM - U-Boot at: %08lxn",dest_addr);

??? display_banner();

??? display_dram_config();

#ifdef CONFIG_LOGBUFFER

??? logbuff_init_ptrs ();

#endif

?

好了,现在uboot已经可以支持NAND FLASH启动和读写了。

?

我们还可以在commonenv_common.c文件中的default_environment[]数组中增加

?

#if 1??? /*add by bsc */

?

?? "uu="?? "t 0x30000000 u-boot.bin;nand erase 0x0 0x30000;nand write 0x30000000 0x0 0x30000" ""

?

?? "kkn=" "t 0x30008000 zImage_nfs;bootm" ""

?

?? "kk="?? "t 0x30000000 zImage;nand erase 0x50000 0x300000;nand write 0x30000000 0x50000 0x200000" ""

?

?? "yy="?? "t 0x30000000 rootyaffs2.img;nand erase 0x250000 0x3db0000;nand write.yaffs2 0x30000000 0x250000 $(filesize)" ""

?

?? "firstboot=" "set bootcmd $(normalboot);save;nand erase 0x50000 0x3f00000;run kk;run yy" ""

?

?? "normalboot="?? "nand read 0x30008000 0x50000 0x200000;bootm 0x30008000" ""

?

#endif

?

以使用 run uurun yy这样的命令来实现一些操作。

?

本篇文章来源于 Linux公社网站(www.linuxidc.com)?原文链接:http://www.linuxidc.com/Linux/2011-02/32772p4.htm

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读