移植UBoot08到友善之臂mini2440.docx
《移植UBoot08到友善之臂mini2440.docx》由会员分享,可在线阅读,更多相关《移植UBoot08到友善之臂mini2440.docx(47页珍藏版)》请在冰点文库上搜索。
移植UBoot08到友善之臂mini2440
移植U-Boot-2009.08到友善之臂mini2440
声明
我也是学习Linux和ARM的新手,在收集资料的过程中发现了Tekkaman Ninja和 flyslightly以及另外一些高手的文章,仔细的研究了他们的移植u-boot的过程,从中受益匪浅,他们给出了详细的移植步骤和完善的源码以及补丁,衷心感谢的他们分享他们的经验和工作成果,向他们的敬业和无私奉献精神致敬!
我在3.22-4.25中一个月的时间,仔细的看了他们的移植u-boot的文章,同时也自己试试移植,在经历10来次失败之后,在上周u-boot移植有了重大突破,将2008.10和2009.08初步移植成功,不过没完全实现他们已经实现的功能,不过可以通过tftp、nfs来启动内核和文件系统!
在此再次感谢Tekkaman Ninja和 flyslightly!
我将他们两人的移植步骤综合了,形成了即将要贴出来的《移植U-Boot-2009.08到mini2440》,我已经检验过这上面的步骤内容大体没有问题,可以将2009.08移植成功,我此次贴出这个移植步骤,我只是当了一个小编辑,将他们的文章重新组合了一下,不过我也加入了我移植过程遇到的问题。
主要参考的是:
Tekkaman Ninja:
移植U-Boot.1.3.1到S3C244和S3C2410
flyslightly:
移植U-Boot-2008.10到友善之臂mini2440
移植步骤将分为几个部分贴出来!
移植U-Boot-2009.08到友善之臂mini2440
本文是针对在友善之臂公司出品的以S3C2440为核心的mini2440开发板上实现U-Boot-2009.08的移植。
其中存储介质为一片256MB的NANDFlash(K9F2G08),一片2MB的NORFlash(SST-39VF1601),两片32MB的SDRAM(HY57V561620FTP),网卡芯片为DM9000a46。
移植U-Boot.2009.08到友善之臂mini2440
(一)
一、在U-Boot中建立自己的开发板类型,并测试编译。
在U-Boot中建立自己的开发板文件(以友善之臂的sbc2410x为基础)。
开发板取名《mini2440》。
(1)在工作目录/opt下解压U-Boot-2009.08
[root@localhostopt]$tar-xjvfu-boot-2009.08.tar.bz2
(2)进入U-Boot-2009.08的根目录,修改Makefile,使用vi或gedit编辑器
[root@localhostopt]#cdu-boot-2009.08
[root@localhostu-boot-2009.08]#viMakefile
u-boot-2009.08的根目录下面的Makefile中为mini2440建立编译项,以sbc2410x为例子。
在2985行的后面加上对mini2440板子的支持!
sbc2410x_config:
unconfig
@$(MKCONFIG)$(@:
_config=)armarm920tsbc2410xNULLs3c24x0
mini2440_config:
unconfig
@$(MKCONFIG)$(@:
_config=)armarm920tmini2440NULLs3c24x0
各项的意思如下:
arm:
CPU的架构(ARCH)
arm920t:
CPU的类型(CPU),其对应于cpu/arm920t子目录。
mini2440:
开发板的型号(BOARD),对应于board/mini2440目录。
NULL:
开发者/或经销商(vender),NULL为没有。
s3c24x0:
片上系统(SOC)。
注意下面要与自己的开发系统一致,一般是默认arm-linux-!
CROSS_COMPILE=arm-linux-
特别注意:
在u-boot1.3.3及以上版本Makefile有一定的变化,使得对于24x0处理器从nand启动的遇到问题。
也就是网上有人说的:
无法运行过lowlevel_init。
其实这个问题是由于编译器将我们自己添加的用于nandboot的子函数nand_read_ll放到了4K之后造成的(到这不理解的话,请仔细看看24x0处理器nandboot原理)。
运行失败后,利用mini2440的4个LED调试发现u-boot根本没有完成自我拷贝,然后看uboot根目录下的System.map文件可知道原因。
解决办法其实很简单,将下面这个语句:
在uboot根目录下的Makefile中。
在289行
__LIBS:
=$(subst$(obj),,$(LIBS))$(subst$(obj),,$(LIBBOARD))
改为:
__LIBS:
=$(subst$(obj),,$(LIBBOARD))$(subst$(obj),,$(LIBS))
2在/board子目录中建立自己的开发板mini2440目录
由于在上一步板子的开发者/或经销商(vender)中填了NULL,所以开发板mini2440目录一定要建在/board目录下,目录结构为board/mini2440。
如果开发者/经销商(vender)不为NULL,则目录结构为board/verder_name/mini2440,否则编译会出错。
[root@localhostu-boot-2009.08]$cdboard
[root@localhostboard]$mkdirmini2440
[root@localhostboard]$cp-arfsbc2410x/*mini2440/
[root@localhostboard]$cdmini2440/
[root@localhostmini2440]$mvsbc2410x.cmini2440.c
还要记得修改自己的开发板mini2440目录下的Makefile文件28行,不然编译时会出错:
[root@localhostmini2440]$viMakefile
修改Makefile的依赖文件
COBJS:
=sbc2410x.oflash.o
COBJS:
=mini2440.oflash.o
3在include/configs/中建立开发板的配置头文件
[root@localhostmini2440]$cd../../..(回到u-boot-2009.08的根目录下)
[root@localhostu-boot-2009.08]$cpinclude/configs/sbc2410x.hinclude/configs/mini2440.h(添加mini2440的配置头文件)
4测试编译能否成功
回到U-Boot主目录,(若之前有编译过,最好执行一下makeclean) makemini2440_config,再make,编译生成u-boot.bin成功。
1、配置
[root@localhostu-boot-2009.08]$makemini2440_config
Configuringformini2440board...
可能出现的问题:
(1)如果出现:
$makemini2440_config
Makefile:
1927:
***遗漏分隔符。
停止。
请在U-boot的根目录下的Makefile的
@$(MKCONFIG)$(@:
_config=)armarm920tmini2440NULLs3c24x0
前加上“Tab”键
2、测试编译
[root@localhostu-boot-2009.08]$make
测试通过后进行下一步
移植U-Boot-2009.08到友善之臂mini2440
(二)
2.1修改cpu/arm920t/start.S
(1)删除AT91RM9200使用的LED代码,117、118行,关闭LED代码。
start_code:
/*
*setthecputoSVC32mode
*/
mrsr0,cpsr
bicr0,r0,#0x1f
orrr0,r0,#0xd3
msrcpsr,r0
//blcoloured_LED_init
//blred_LED_on
(2)修改编译条件支持s3c2440,在134行,修改寄存器地址定义,修改CPU频率初始化设置
#ifdefined(CONFIG_S3C2400)||defined(CONFIG_S3C2440)||defined(CONFIG_S3C2410)
/*turnoffthewatchdog*/
#ifdefined(CONFIG_S3C2400)
#definepWTCON0x15300000
#defineINTMSK0x14400008/*Interupt-Controllerbaseaddresses*/
#defineCLKDIVN0x14800014/*clockdivisorregister*/
#else
#definepWTCON0x53000000
#defineINTMSK0x4A000008/*Interupt-Controllerbaseaddresses*/
#defineINTSUBMSK0x4A00001C
#defineCLKDIVN0x4C000014/*clockdivisorregister*/
#endif
修改CPU频率初始化设置
//xujun
#defineCLK_CTL_BASE0x4C000000
#defineMDIV_4050x7f<<12
#definePSDIV_4050x21
#defineMDIV_2000xa1<<12
#definePSDIV_2000x31
(3)修改中断禁止部分
165行修改0x3ff为0x7ff
#ifdefined(CONFIG_S3C2410)
ldrr1,=0x7ff/*根据2410芯片手册,INTSUBMSK有11位可用*/
ldrr0,=INTSUBMSK
strr1,[r0]
#endif
169行添加
#ifdefined(CONFIG_S3C2440)
ldrr1,=0x7fff
ldrr0,=INTSUBMSK
strr1,[r0]
#endif
(4)修改时钟设置(2440的主频为405MHz。
)
//xujun
#ifdefined(CONFIG_S3C2440)
/*FCLK:
HCLK:
PCLK=1:
4:
8*/
ldrr0,=CLKDIVN
movr1,#5
strr1,[r0]
mrcp15,0,r1,c1,c0,0
orrr1,r1,#0xc0000000
mcrp15,0,r1,c1,c0,0
movr1,#CLK_CTL_BASE
movr2,#MDIV_405
addr2,r2,#PSDIV_405
strr2,[r1,#0x04]
#else
/*FCLK:
HCLK:
PCLK=1:
2:
4*/
/*defaultFCLKis120MHz!
*/
ldrr0,=CLKDIVN
movr1,#3
strr1,[r0]
//xujun
mrcp15,0,r1,c1,c0,0
orrr1,r1,#0xc0000000
mcrp15,0,r1,c1,c0,0
movr1,#CLK_CTL_BASE
movr2,#MDIV_200
addr2,r2,#PSDIV_200
strr2,[r2,#0x04]
#endif
(5)将从Flash启动改成从NANDFlash启动
将relocateU-BoottoRAM 的代码注释或者删除
#if0
#ifndefCONFIG_SKIP_RELOCATE_UBOOT
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
#endif /*CONFIG_SKIP_RELOCATE_UBOOT*/
#endif//if0
在以下U-Boot的设置堆栈语句段(作用是将u-boot的源代码从norflash到sdram中):
/*Setupthestack*/
stack_setup:
ldrr0,_TEXT_BASE/*upper128KiB:
relocateduboot
的前面添加上(#endif/*CONFIG_SKIP_RELOCATE_UBOOT*/
#endif的后面添加上:
)以下的nandboot代码:
定义u-boot在nandflash中存放的长度为#defineLENGTH_UBOOT0x60000,可以方便修改u-boot因为裁剪和增添大小的改变而占的长度。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
//xujun
#defineLENGTH_UBOOT0x60000
#defineNAND_CTL_BASE0x4E000000
#ifdefCONFIG_S3C2440_NAND_BOOT
@resetNAND
#defineoNFCONF0x00
#defineoNFCONT0x04
#defineoNFSTAT0x08
#defineoNFCMD0x20
movr1,#NAND_CTL_BASE
ldrr2,=((7<<12)|(7<<8)|(7<<4)|(0<<0))
strr2,[r1,#oNFCONF]
ldrr2,[r1,#oNFCONF]
ldrr2,=((1<<4)|(0<<1)|(1<<0))
strr2,[r1,#oNFCONT]
ldrr2,[r1,#oNFCONT]
ldrr2,=(0x6)
strr2,[r1,#oNFSTAT]
ldrr2,[r1,#oNFSTAT]
movr2,#0xff
strbr2,[r1,#oNFCMD]
movr3,#0
nand1:
addr3,r3,#0x1
cmpr3,#0xa
bltnand1
nand2:
ldrr2,[r1,#oNFSTAT]
tstr2,#0x4
beqnand2
ldrr2,[r1,#oNFCONT]
orrr2,r2,#0x2
strr2,[r1,#oNFCONT]
@getreadtocallCfunctions(fornand_read())
ldrsp,DW_STACK_START
movfp,#0
@copyU-BoottoRam
ldrr0,=TEXT_BASE
movr1,#0x0
movr2,#LENGTH_UBOOT//theu-boot’slenth
blnand_read_ll
tstr0,#0x0
beqok_nand_read
bad_nand_read:
loop2:
bloop2
ok_nand_read:
@verify
movr0,#0
ldrr1,=TEXT_BASE
movr2,#0x400
go_next:
ldrr3,[r0],#4
ldrr4,[r1],#4
teqr3,r4
bnenotmatch
subsr2,r2,#4
beqstack_setup
bnego_next
notmatch:
loop3:
bloop3@CONFIG_S3C2440_NAND_BOOT
#endif
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
。
在“ldr pc,_start_armboot”之后加入LED代码:
ldrpc,_start_armboot
#ifdefined(CONFIG_MINI2440_LED)
movr1,#GPIO_CTL_BASE
addr1,r1,#oGPIO_B
ldrr2,=0x156aa
strr2,[r1,#oGPIO_CON]
movr2,#0xff
strr2,[r1,#oGPIO_UP]
movr2,#0x1c0
strr2,[r1,#oGPIO_DAT]
#endif
_start_armboot:
.wordstart_armboot
在“_start_armboot:
.wordstart_armboot”后加入:
_start_armboot:
.wordstart_armboot
#defineSTACK_BASE0x33f00000
#defineSTACK_SIZE0x10000
.align2
DW_STACK_START:
.wordSTACK_BASE+STACK_SIZE-4
移植U-Boot-2009.08到友善之臂mini2440(三)
3.1在board/mini2440/目录下加入NANDFlash读取函数(start.S中需要的nand_read_ll函数)文件nand_read.c,新建nand_read.c,这里的开发板使用的是128MB,大页的读写。
下面是nand_read.c文件的内容。
(注意和小页的NandFlash的不同)
board/mini2440/nand_read.c
#include
#include
#define__REGb(x)(*(volatileunsignedchar*)(x))
#define__REGw(x)(*(volatileunsignedshort*)(x))
#define__REGi(x)(*(volatileunsignedint*)(x))
#defineNF_BASE0x4e000000
#ifdefined(CONFIG_S3C2410)
#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)
#defineNFSTAT_BUSY1
#definenand_select()(NFCONF&=~0x800)
#definenand_deselect()(NFCONF|=0x800)
#definenand_clear_RnB()do{}while(0)
#elifdefined(CONFIG_S3C2440)
#defineNFCONF__REGi(NF_BASE+0x0)
#defineNFCONT__REGi(NF_BASE+0x4)
#defineNFCMD__REGb(NF_BASE+0x8)
#defineNFADDR__REGb(NF_BASE+0xc)
#defineNFDATA__REGb(NF_BASE+0x10)
#defineNFDATA16__REGw(NF_BASE+0x10)
#defineNFSTAT__REGb(NF_BASE+0x20)
#defineNFSTAT_BUSY(1<<2)
#definenand_select()(NFCONT&=~(1<<1))
#definenand_deselect()(NFCONT|=(1<<1))
#definenand_clear_RnB()(NFSTAT|=NFSTAT_BUSY)
#endif
staticinlinevoidnand_wait(void)
{
inti;
while(!
(NFSTAT&NFSTAT_BUSY))
for(i=0;i<10;i++);
}
#ifdefined(CONFIG_S3C2410)
#defineNAND_PAGE_SIZE512
#defineBAD_BLOCK_OFFSET517
#defineNAND_BLOCK_MASK(NAND_PAGE_SIZE-1)
#defineNAND_BLOCK_SIZE0x4000
#else
#defineNAND_5_ADDR_CYCLE
#defineNAND_PAGE_SIZE2048
#defineBAD_BLOCK_OFFSETNAND_PAGE_SIZE
#defineNAND_BLOCK_MASK(NAND_PAGE_SIZE-1)
#defineNAND_BLOCK_SIZE(NAND_PAGE_SIZE*64)
#endif
#ifdefined(CONFIG_S3C2410)&&(NAND_PAGE_SIZE!
=512)
#error"S3C2410doesnotsupportnandpagesize!
=512"
#endif
staticintis_bad_block(unsignedlongi)
{
unsignedchardata;
unsignedlongpage_num;
nand_clear_RnB();
#if(NAND_PAGE_SIZE==512)
NFCMD=NAND_CMD_READOOB;
NFADDR=BAD_BLOCK_OFFSET&0xf;
NFADDR=(i>>9)&0xff;
NFADDR=(i>>17)&0xff;
NFADDR=(i>>25)&0xff;
#elif(NAND_PAGE_SIZE==2048)
page_num=i>>11;
NFCMD=NAND_CMD_READ0;
NFADDR=BAD_BLOCK_OFFSET&0xff;
NFADDR=(BAD_BLOCK_OFFSET>>8)&0xff;
NFADDR=page_num&0xff;
NFADDR=(