UBOOT移植7Word文件下载.docx
《UBOOT移植7Word文件下载.docx》由会员分享,可在线阅读,更多相关《UBOOT移植7Word文件下载.docx(21页珍藏版)》请在冰点文库上搜索。
00000000位置开始启动。
这个过程不需要程序干涉。
程序员需要完成的工作,是把最核心的启动程序放在NandFlash的前4K中。
1.3.2启动程序的安排
由于NandFlash控制器从NandFlash中搬移到内部RAM的代码是有限的,所以在启动代码的前4K里,我们必须完成S3C2410的核心配置以及把启动代码(U-BOOT)剩余部分搬到RAM中运行。
u-boot源码不支持从nandflash启动,可是s3c2410支持从nandflash启动,加电后s3c2440将nandflash的前4k(保存有u-boot的部分功能–拷贝功能–把nandflash中的内容拷贝到SDRAM)拷贝到sram(s3c2440芯片内的sram)。
这就需要修改u-boot源码,增加u-boot的功能:
使u-boot在得到执行权后能够将其自身拷贝到开发板上SDRAM中,以便处理器能够执行u-boot
2.u-boot的NANDFLASH部分移植
以下的操作是经过整理的,详细过程见A.1.1所列出的网址
注意,如果u-boot要在SDRAM中调试,得把u-boot-2011.03\include\configs\reille2440.h文件中的宏定义CONFIG_SKIP_LOWLEVEL_INIT开启和关闭CONFIG_S3C2440_NAND_BOOT宏定义
2.1修改u-boot-2011.03\include\configs\reille2440.h文件
2.1.1注销如下定义:
/*delbyguoyirong2011.06.19
#define
CONFIG_ENV_IS_IN_FLASH
1
#defineCONFIG_ENV_SIZE
0×
10000
//TotalSizeofEnvironmentSector
*/
2.1.2reille2440.h文件末增加如下定义:
/**********************************************************/
/*以下为NAND启动及驱动相关addedbyguoyirong2011.06.19*/
/*
*去掉NORFLASH支持,如果不去掉,则arch/arm/lib/libarm.o被连接到了4K之外,
*4K之内没有这个程序libarm是不可能实现NAND启动的
#defineCONFIG_SYS_NO_FLASH
//#defineCONFIG_CMD_FLASH
/*flinfo,erase,protect
*/
//#defineCONFIG_CMD_IMLS
/*Listallfoundimages
#defineCONFIG_S3C2440_NAND_BOOT
#defineCONFIG_NAND_S3C2440
#defineNAND_CTL_BASE
0x4E000000
//NandFlash配置寄存器基地址,查2440手册可得知
#defineoNFCONF
00//相对Nand配置寄存器基地址的偏移量,还是配置寄存器的基地址
#defineoNFCONT
04//相对Nand配置寄存器基地址的偏移量,可得到控制寄存器的基地址(0x4E000004)
#defineoNFADDR
0x0c//相对Nand配置寄存器基地址的偏移量,可得到地址寄存器的基地址(0x4E00000c)
#defineoNFDATA
10//相对Nand配置寄存器基地址的偏移量,可得到数据寄存器的基地址(0x4E000010)
#defineoNFCMD
08//相对Nand配置寄存器基地址的偏移量,可得到指令寄存器的基地址(0x4E000008)
#defineoNFSTAT
20//相对Nand配置寄存器基地址的偏移量,可得到状态寄存器的基地址(0x4E000020)
#defineoNFECC
0x2c//相对Nand配置寄存器基地址的偏移量,可得到ECC寄存器的基地址(0x4E00002c)
#defineUBOOT_LENGTH
40000/*256K*/
#defineSTACK_BASE
0x33f00000
//定义堆栈的地址
#defineSTACK_SIZE
8000
//堆栈的长度大小
#defineCONFIG_CMD_NAND
#defineCONFIG_CMDLINE_EDITING
CONFIG_NAND_S3C2440
#ifdefCONFIG_CMDLINE_EDITING
#undefCONFIG_AUTO_COMPLETE
#else
#defineCONFIG_AUTO_COMPLETE
#endif
/*NANDflashsettings*/
#ifdefined(CONFIG_CMD_NAND)
#defineCONFIG_SYS_NAND_BASE
0x4E000000//Nand配置寄存器基地址
#defineCONFIG_SYS_MAX_NAND_DEVICE
#defineCONFIG_MTD_NAND_VERIFY_WRITE
//#defineNAND_SAMSUNG_LP_OPTIONS
1
//注意:
我们这里是64M的NandFlash,所以不用,如果是128M的大块NandFlash,则需加上
//添加环境变量保存到Nand的宏(注意:
如果你要使用从Nor启动的saveenv命令,则不要这些Nand宏定义)
#defineCONFIG_ENV_IS_IN_NAND
#defineCONFIG_ENV_OFFSET
30000//将环境变量保存到nand中的0×
30000位置
10000/*TotalSizeofEnvironmentSector*/
2.1.3注释CONFIG_SKIP_LOWLEVEL_INIT
//#defineCONFIG_SKIP_LOWLEVEL_INIT
2.2增加从NANDFLASH读取数据到内存的函数,文件名为nand_read.c,放到board\samsung\reille2440\nand_read.c下
nand_read.c文件内容如下:
*board\samsung\reille2440\nand_read.c
*
*(C)Copyright2011
*reille<
<
reille@>
*Thisprogramisfreesoftware;
youcanredistributeitand/or
*modifyitunderthetermsoftheGNUGeneralPublicLicenseas
*publishedbytheFreeSoftwareFoundation;
eitherversion2of
*theLicense,or(atyouroption)anylaterversion.
#include<
config.h>
#defineNF_BASE
//NandFlash配置寄存器基地址
#define__REGb(x)(*(volatileunsignedchar*)(x))
#define__REGi(x)(*(volatileunsignedint
*)(x))
#defineNFCONF__REGi(NF_BASE+0×
0)
//通过偏移量还是得到配置寄存器基地址
#defineNFCONT__REGi(NF_BASE+0×
4)
//通过偏移量得到控制寄存器基地址
#defineNFCMD
__REGb(NF_BASE+0×
8)
//通过偏移量得到指令寄存器基地址
#defineNFADDR__REGb(NF_BASE+0xC)
//通过偏移量得到地址寄存器基地址
#defineNFDATA__REGb(NF_BASE+0×
10)
//通过偏移量得到数据寄存器基地址
#defineNFSTAT__REGb(NF_BASE+0×
20)
//通过偏移量得到状态寄存器基地址
#defineNAND_CHIP_ENABLE
(NFCONT&
=~(1<
<
1))
//Nand片选使能
#defineNAND_CHIP_DISABLE(NFCONT|=(1<
//取消Nand片选
#defineNAND_CLEAR_RB
(NFSTAT|=(1<
2))
#defineNAND_DETECT_RB
{while(!
(NFSTAT&
(1<
2)));
}
#defineNAND_SECTOR_SIZE512
#defineNAND_BLOCK_MASK(NAND_SECTOR_SIZE–1)
#if0
#defineDEBUGN
printf
#defineDEBUGN(x,args…){}
#endif
/*lowlevelnandreadfunction*/
intnand_read_ll(unsignedchar*buf,unsignedlongstart_addr,intsize){
inti,j;
//
DEBUGN(“nand_read_ll………….\n”);
//这句不能有,否则uboot不能从NANDFLASH启动起来
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)&
17)&
25)&
NAND_DETECT_RB;
for(j=0;
j<
NAND_SECTOR_SIZE;
j++,i++){
*buf=(NFDATA&
0xFF);
buf++;
NAND_CHIP_DISABLE;
//取消片选信号
return
0;
2.3修改cmd_bootm.c文件
a)把81和82行注释掉,如下:
//abortNORFLASH
|delbyguoyirong2011.06.25
//#include<
mtd/cfi_flash.h>
//externflash_info_tflash_info[];
/*infoforFLASHchips*/
b)把函数intdo_imls(cmd_tbl_t*cmdtp,intflag,intargc,char*constargv[])整体注释掉,改为如下:
intdo_imls(cmd_tbl_t*cmdtp,intflag,intargc,char*constargv[]){return(0);
做一步是因为要去掉NORFLASH支持(如果不去掉,则arch/arm/lib/libarm.o被连接到了4K之外,4K之内没有这个程序libarm是不可能实现NAND启动的),但去掉后,在这里会出现编译错误,如下所示:
Infileincludedfromcmd_bootm.c:
80:
/home/reille/work/u-boot-2011.03/include/mtd/cfi_flash.h:
174:
error:
expected‘)’before‘*’token
cmd_bootm.c:
81:
expected‘=’,‘,’,‘;
’,‘asm’or‘__attribute__’before‘flash_info’
Infunction‘do_imls’:
1145:
‘flash_info_t’undeclared(firstuseinthisfunction)
(Eachundeclaredidentifierisreportedonlyonce
foreachfunctionitappearsin.)
‘info’undeclared(firstuseinthisfunction)
1149:
‘flash_info’undeclared(firstuseinthisfunction)
1152:
‘FLASH_UNKNOWN’undeclared(firstuseinthisfunction)
make[1]:
***[cmd_bootm.o]Error1
Leavingdirectory`/home/reille/work/u-boot-2011.03/common’
make:
***[common/libcommon.o]Error2
reille@ubuntu:
~/work/u-boot-2011.03$
注释掉后就不会出现了,按理来说在u-boot-2011.03\include\configs\reille2440.h文件中去掉了宏定义CONFIG_CMD_IMLS及加上宏定义CONFIG_SYS_NO_FLASH就不会出现编译错误了,但不知道为什么没能起作用。
2.4修改board/samsung/reille2440/makefile
#delbyguoyirong2011.06.25
#COBJS
:
=reille2440.oflash.onand_read.o
#nonorflash|addbyguoyirong2011.06.25
COBJS
=reille2440.onand_read.o
注意,不再有NORFLASH了,因此去掉flash.o
2.5drivers/mtd/nand/目录下新建s3c2440_nand.c文件实现对NANDFLASH的操作
2.5.1s3c2440_nand.c文件内容如下:
*drivers/mtd/nand/s3c2440_nand.c
*实现对nandFLASH的操作
common.h>
nand.h>
asm/arch/s3c24x0_cpu.h>
asm/io.h>
#define__REGb(x)
(*(volatileunsignedchar*)(x))
#define__REGi(x)
(*(volatileunsignedint*)(x))
0x4e000000
//Nand配置寄存器基地址
#defineNFCONF
__REGi(NF_BASE+0×
0)
//偏移后还是得到配置寄存器基地址
#defineNFCONT
4)
//偏移后得到Nand控制寄存器基地址
8)
//偏移后得到Nand指令寄存器基地址
#defineNFADDR
__REGb(NF_BASE+0xc)
//偏移后得到Nand地址寄存器基地址
#defineNFDATA
10)//偏移后得到Nand数据寄存器基地址
#defineNFMECCD0__REGi(NF_BASE+0×
14)//偏移后得到Nand主数据区域ECC0寄存器基地址
#defineNFMECCD1__REGi(NF_BASE+0×
18)//偏移后得到Nand主数据区域ECC1寄存器基地址
#defineNFSECCD
__REGi(NF_BASE+0x1C)//偏移后得到Nand空闲区域ECC寄存器基地址
#defineNFSTAT
20)//偏移后得到Nand状态寄存器基地址
#defineNFSTAT0
24)//偏移后得到NandECC0状态寄存器基地址
#defineNFSTAT1
28)//偏移后得到NandECC1状态寄存器基地址
#defineNFMECC0
__REGi(NF_BASE+0x2C)//偏移后得到Nand主数据区域ECC0状态寄存器基地址
#defineNFMECC1
30)//偏移后得到Nand主数据区域ECC1状态寄存器基地址
#defineNFSECC
34)//偏移后得到Nand空闲区域ECC状态寄存器基地址
#defineNFSBLK
38)//偏移后得到Nand块开始地址
#defineNFEBLK
__REGi(NF_BASE+0x3c)//偏移后得到Nand块结束地址
#defineS3C2440_NFCONT_nCE
(1<
1)
#defineS3C2440_ADDR_NALE
0x0c
#defineS3C2440_ADDR_NCLE
08
ulongIO_ADDR_W=NF_BASE;
staticvoids3c2440_hwcontrol(structmtd_info*mtd,intcmd,unsignedintctrl){
structnand_chip*chip=mtd->
priv;
DEBUGN(“hwcontrol():
0x%02x0x%02x\n”,cmd,ctrl);
if(ctrl&
NAND_CTRL_CHANGE){
IO_ADDR_W=NF_BASE;
if(!
(ctrl&
NAND_CLE)){
//要写的是地址
IO_ADDR_W|=S3C2440_ADDR_NALE;
NAND_ALE)){
//要写的是命令
IO_ADDR_W|=S3C2440_ADDR_NCLE;
NAND_NCE){
NFCONT&
=~S3C2440_NFCONT