1 UBOOT移植实验.docx
《1 UBOOT移植实验.docx》由会员分享,可在线阅读,更多相关《1 UBOOT移植实验.docx(22页珍藏版)》请在冰点文库上搜索。
1UBOOT移植实验
U-BOOT移植实验
u-boot简介
u-boot是德国DENX小组的开发用于多种嵌入式CPU的bootloader程序,u-boot不仅仅支持嵌入式Linux系统的引导,当前,它还支持NetBSD,VxWorks,QNX,RTEMS,ARTOS,LynxOS嵌入式操作系统。
u-boot除了支持PowerPC系列的处理器外,还能支持MIPS、x86、ARM、NIOS、XScale等诸多常用系列的处理器。
u-boot源码目录介绍
目录
内容
board
和一些已有开发板有关的文件.每一个开发板都以一个子目录出现在当前目录中,比如说:
SMDK2410,子目录中存放与开发板相关的配置文件.
common
实现uboot命令行下支持的命令,每一条命令都对应一个文件。
例如go命令对应就是
cmd_boot.c
cpu
与特定CPU架构相关目录,每一款uboot下支持的CPU在该目录下对应一个子目录,比如有子目录arm920t等。
disk
对磁盘的支持
doc
文档目录。
uboot有非常完善的文档,推荐大家参考阅读。
drivers
uboot支持的设备驱动程序都放在该目录,比如各种网卡、支持CFI的Flash、串口和USB等。
fs
支持的文件系统,uboot现在支持cramfs、fat、fdos、jffs2和registerfs。
include
uboot使用的头文件,还有对各种硬件平台支持的汇编文件,系统的配置文件和对文件系统支持的文件。
该目录下configs目录有与开发板相关的配置头文件,如smdk2410.h。
该目录下的asm目录有与CPU体系结构相关的头文件,asm对应的是asmarm.
lib_xxxx
与体系结构相关的库文件。
如与ARM相关的库放在lib_arm中。
net
与网络协议栈相关的代码,BOOTP协议、TFTP协议、RARP协议和NFS文件系统的实现。
tools
uboot的工具,如:
mkimage,crc等等。
u-boot的启动过程
1启动流程
我们一般把bootloader都分为阶段1(stage1)和阶段2(stage2)两大部分,依赖于CPU体系结构的代码(如CPU初始化代码等)通常都放在阶段1中且通常用汇编语言实现,而阶段2则通常用C语言来实现,这样可以实现复杂的功能,而且有更好的可读性和移植性。
1阶段1,汇编代码,对于s3c2410是cpu/arm920t/start.s文件。
主要流程如下:
设置CPU的模式为SVC模式
关闭看门狗
禁掉所有中断
设置以CPU的频率
把自己拷贝到RAM
配置内存区控制寄存器
配置的栈空间
进入C代码部分
2阶段2是C语言代码,在lib_arm/board.c中的start_armboot是C语言开始的函数,也是整个启动代码中C语言的主函数。
这个函数调用一系列的初始化函数,然后进入主UBOOT命令行,进入命令循环(即整个boot的工作循环),接受用户从串口输入的命令,然后进行相应的工作。
当用户输入启动linux的命令的时候,u-boot会将kernel映像(zImage)和从nandflash上读到RAM空间中,为内核设置启动参数,调用内核,从而启动linux。
u-boot移植要点:
我们可以总结出bootloader的两大功能:
1是下载功能,既通过网口、串口或者USB口下载文件到RAM中。
2是对flash芯片的读写功能。
u-boot对S3C2410已经有了很好的支持,我们在移植过程中主要是完善u-boot对nandflash的读写功能。
u-boot移植前的准备工作:
1下载源码,建立工作目录
Uboot的源码可以从以下网址下载:
我们这里下载的是u-boot-1.1.4.tar.bz2
建立工作目录:
mkdir/root/build_uboot
cd/root/build_uboot
把下载的源码拷贝到该目录,解压;
tarjxvfu-boot-1.1.4.tar.bz2
mvu-boot-1.1.4u-boot
2确定分区:
user
rootfs
kernel
参数
u-boot
0x04000000-------
0x02000000-------
0x00200000-------
0x00040000-------
0x00030000-------
0x00000000_______
我们可以根据以上的一个分区信息来配置我们的系统.
u-boot移植的具体步骤:
一建立适合的board平台
参照board/smdk2410目录,我们在源码的board下建立自己的自己的平台gec2410,步骤如下.
1修改顶层Makefile
cd/root/build_uboot/u-boot
viMakefile
找到:
smdk2410_config:
unconfig
@./mkconfig$(@:
_config=)armarm920tsmdk2410NULLs3c24x0
在其后面添加:
gec2410_config:
unconfig
@./mkconfig$(@:
_config=)armarm920tgec2410NULLs3c24x0
各项的意思如下:
arm:
CPU的架构(ARCH)
arm920t:
CPU的类型(CPU),其对应于cpu/arm920t子目录。
gec2410:
开发板的型号(BOARD),对应于board/gec2410目录。
NULL:
开发者/或经销商(vender)。
s3c24x0:
片上系统(SOC)。
我把我的板子起名叫gec2410,可以依自己的喜好修改
2建立board/gec2410目录,拷贝board/smdk2410下的文件到board/gec2410目录,将smdk2410.c更名为gec2410.c
cp-rboard/smdk2410board/gec2410
3修改board/gec2410/Makefile
将:
OBJS:
=smdk2410.oflash.o
改为:
OBJS:
=gec2410.oflash.o
4cpinclude/configs/smdk2410.hinclude/configs/gec2410.h
5修改cpu/arm920t/config.mk文件
将:
PLATFORM_CPPFLAGS+=$(callcc-option,-mapcs-32,-mabi=apcs-gnu)
改为:
PLATFORM_CPPFLAGS+=$(callcc-option,-mapcs-32,$(callcc-option,-mabi=apcs-gnu),)
6设置交叉编译环境变量
exportPATH=/usr/local/arm/2.95.3/bin:
$PATH
7测试编译能否成功:
makegec2410_config
makeallARCH=arm
生成u-boot.bin就OK了
二支持网络和nandflash操作命令
1添加网络命令
在include/configs/gec2410.h
只要在
#defineCONFIG_COMMANDS
添加定义
CFG_CMD_NET
CFG_CMD_PING
就可以了
说明:
include/configs/gec2410.h文件是与开发板相关的配置头文件。
2支持nandflash启动和读写
(1)支持从nandflash启动
a添加nandflash寄存器的定义
修改include/configs/gec2410.h文件,添加如下内容:
***********************************************************************************************
/*
*NandflashBoot
*/
#defineCONFIG_S3C2410_NAND_BOOT1
#defineSTACK_BASE0x33f00000
#defineSTACK_SIZE0x8000
#defineUBOOT_RAM_BASE0x33f80000
/*NANDFlashController*/
#defineNAND_CTL_BASE0x4E000000
#definebINT_CTL(Nb)__REG(INT_CTL_BASE+(Nb))
/*Offset*/
#defineoNFCONF0x00
#defineoNFCMD0x04
#defineoNFADDR0x08
#defineoNFDATA0x0c
#defineoNFSTAT0x10
#defineoNFECC0x14
************************************************************************************************
b在start.S加入搬运代码
修改cpu/arm920t/start.S文件
在ldrpc,_start_armboot之前加入:
************************************************************************************************
#ifdefCONFIG_S3C2410_NAND_BOOT
blcopy_myself
@jumptoram
ldrr1,=on_the_ram
addpc,r1,#0
nop
nop
1:
b1b@infiniteloop
on_the_ram:
#endif
************************************************************************************************
在_start_armboot:
.wordstart_armboot之后加入:
************************************************************************************************
#ifdefCONFIG_S3C2410_NAND_BOOT
copy_myself:
movr10,lr
@resetNAND
movr1,#NAND_CTL_BASE
ldrr2,=0xf830@initialvalue
strr2,[r1,#oNFCONF]
ldrr2,[r1,#oNFCONF]
bicr2,r2,#0x800@enablechip
strr2,[r1,#oNFCONF]
movr2,#0xff@RESETcommand
strbr2,[r1,#oNFCMD]
movr3,#0@wait
1:
addr3,r3,#0x1
cmpr3,#0xa
blt1b
2:
ldrr2,[r1,#oNFSTAT]@waitready
tstr2,#0x1
beq2b
ldrr2,[r1,#oNFCONF]
orrr2,r2,#0x800@disablechip
strr2,[r1,#oNFCONF]
@getreadtocallCfunctions(fornand_read())
ldrsp,DW_STACK_START@setupstackpointer
movfp,#0@nopreviousframe,sofp=0
@copyvivitoRAM
ldrr0,=UBOOT_RAM_BASE
movr1,#0x0
movr2,#0x20000
blnand_read_ll
tstr0,#0x0
beqok_nand_read
#ifdefCONFIG_DEBUG_LL
bad_nand_read:
ldrr0,STR_FAIL
ldrr1,SerBase
blPrintWord
1:
b1b@infiniteloop
#endif
ok_nand_read:
#ifdefCONFIG_DEBUG_LL
ldrr0,STR_OK
ldrr1,SerBase
blPrintWord
#endif
@verify
movr0,#0
ldrr1,=UBOOT_RAM_BASE
movr2,#0x400@4bytes*1024=4K-bytes
go_next:
ldrr3,[r0],#4
ldrr4,[r1],#4
teqr3,r4
bnenotmatch
subsr2,r2,#4
beqdone_nand_read
bnego_next
notmatch:
#ifdefCONFIG_DEBUG_LL
subr0,r0,#4
ldrr1,SerBase
blPrintHexWord
ldrr0,STR_FAIL
ldrr1,SerBase
blPrintWord
#endif
1:
b1b
done_nand_read:
#ifdefCONFIG_DEBUG_LL
ldrr0,STR_OK
ldrr1,SerBase
blPrintWord
#endif
movpc,r10
@clearmemory
@r0:
startaddress
@r1:
length
mem_clear:
movr2,#0
movr3,r2
movr4,r2
movr5,r2
movr6,r2
movr7,r2
movr8,r2
movr9,r2
clear_loop:
stmiar0!
{r2-r9}
subsr1,r1,#(8*4)
bneclear_loop
movpc,lr
#endif@CONFIG_S3C2410_NAND_BOOT
*************************************************************************************************
在文件的最后加入如下,堆栈地址:
*************************************************************************************************
.align2
DW_STACK_START:
.wordSTACK_BASE+STACK_SIZE-4
*************************************************************************************************
c添加nand_read_ll函数的实现
在board/gec2410/建立nand_read.c,加入如下内容(copyfromvivi):
*************************************************************************************************
#include
#define__REGb(x)(*(volatileunsignedchar*)(x))
#define__REGi(x)(*(volatileunsignedint*)(x))
#defineNF_BASE0x4e000000
#defineNFCONF__REGi(NF_BASE+0x0)
#defineNFCMD__REGb(NF_BASE+0x4)
#defineNFADDR__REGb(NF_BASE+0x8)
#defineNFDATA__REGb(NF_BASE+0xc)
#defineNFSTAT__REGb(NF_BASE+0x10)
#defineBUSY1
inlinevoidwait_idle(void){
inti;
while(!
(NFSTAT&BUSY))
for(i=0;i<10;i++);
}
#defineNAND_SECTOR_SIZE512
#defineNAND_BLOCK_MASK(NAND_SECTOR_SIZE-1)
/*lowlevelnandreadfunction*/
int
nand_read_ll(unsignedchar*buf,unsignedlongstart_addr,intsize)
{
inti,j;
if((start_addr&NAND_BLOCK_MASK)||(size&NAND_BLOCK_MASK)){
return-1;/*invalidalignment*/
}
/*chipEnable*/
NFCONF&=~0x800;
for(i=0;i<10;i++);
for(i=start_addr;i<(start_addr+size);){
/*READ0*/
NFCMD=0;
/*WriteAddress*/
NFADDR=i&0xff;
NFADDR=(i>>9)&0xff;
NFADDR=(i>>17)&0xff;
NFADDR=(i>>25)&0xff;
wait_idle();
for(j=0;j*buf=(NFDATA&0xff);
buf++;
}
}
/*chipDisable*/
NFCONF|=0x800;/*chipdisable*/
return0;
}
************************************************************************************************
修改board/gec2410/Makefile为
OBJS:
=gec2410.oflash.onand_read.o
以上步骤就可以把u-boot烧写到nandflash上了
(2)支持nandflash操作命令
a在/include/configs/gec2410.h文件中添加宏定义
#defineCONFIG_COMMANDS
添加定义
CFG_CMD_NAND
CFG_CMD_ENV
b定义环境变量宏
#defineCFG_ENV_IS_IN_FLASH1
#defineCFG_ENV_SIZE0x10000/*TotalSizeofEnvironmentSector*/
改为
#defineCFG_ENV_IS_IN_NAND1
#defineCFG_ENV_OFFSET0x030000
#defineCFG_NAND_BASE0x4E000000
#defineCMD_SAVEENV
#defineCFG_NAND_LEGACY
#defineCFG_ENV_SIZE0x10000/*TotalSizeofEnvironmentSector*/
/*setenv*/
#defineCFG_MONITOR_BASEPHYS_SDRAM_1
c修改common/cmd_nand.c文件,添加nandflash初始化函数
添加
**************************************************************************************************
#definerNFCONF(*(volatileunsigned*)0x4E000000)
#definerNFCMD(*(volatileunsigned*)0x4E000004)
#definerNFADDR(*(volatileunsigned*)0x4E000008)
#definerNFDATA(*(volatileunsigned*)0x4E00000C)
#definerNFSTAT(*(volatileunsigned*)0x4E000010)
#definerNFECC(*(volatileunsigned*)0x4E000014)
#defineCFG_NAND_BASE0x4E000000
#defineCFG_MAX_NAND_DEVICE1/*MaxnumberofNANDdevices*/
#defineSECTORSIZE512
#defineADDR_COLUMN1
#defineADDR_PAGE2
#defineADDR_COLUMN_PAGE3
#defineNAND_ChipID_UNKNOWN0x00
#defineNAND_MAX_FLOORS1
#defineNAND_MAX_CHIPS1
#defineNAND_WAIT_READY(nand){while(!
(rNFSTAT&(1<<0)));}
#defineNAND_DISABLE_CE(nand){rNFCONF|=(1<<11);}
#defineNAND_ENABLE_CE(nand){rNFCONF&=~(1<<11);}
#defineWRITE_NAND_COMMAND(d,adr){rNFCMD=d;}
#defineWRITE_NAND_ADDRESS(d,adr){rNFADDR=d;}
#define