UBoot的移植UBoot Practically Porting GuideWord格式.docx
- 文档编号:16333019
- 上传时间:2022-11-23
- 格式:DOCX
- 页数:34
- 大小:138.26KB
UBoot的移植UBoot Practically Porting GuideWord格式.docx
《UBoot的移植UBoot Practically Porting GuideWord格式.docx》由会员分享,可在线阅读,更多相关《UBoot的移植UBoot Practically Porting GuideWord格式.docx(34页珍藏版)》请在冰豆网上搜索。
例如笔者使用的是arm-iwmmxt-linux-gnueabi-gcc,因此要将上面改为:
CROSS_COMPILE=arm-iwmmxt-linux-gnueabi-
。
二是要修改board/xsbase270下的Makefile。
#COBJS:
=adsvix.opcmcia.o
COBJS:
=xsbase270.opcmcia.o
这是因为前面将该目录下的源文件adsvix.c改为了xsbase270.c。
至此,将新的目标板xsbase270的定义添加到U-Boot中的工作就算完成了。
下面的命令可以编译得到xsbase270的U-Boot:
#assumingyouareatthetopdirectoryofu-boot
#defineabuilddirectorytokeepobjectfilesduringmakeprocessandalsofinallyu-bootimage
exportBUILD_DIR=~/u-boot_xsbase270/build/
makexsbase270_config
#ifyouedityoursourcefileandwanttomakeagain,justtype“makedistclean”andthencalltheabovecommandsagain.
make
当然,要使编译出来的这个u-boot能真正适用于我们的目标板,还有很多工作要做,包括处理器工作状态、存储器映射设置、网卡驱动的移植等等。
所以,本篇的标题只是在U-Boot中添加对新目标板的“定义”,而非对新目标板的“支持”,这些工作需要对U-Boot的源代码有整体的认识,并结合自己的目标板的特性来完成。
后续的篇章将继续介绍后面的内容。
作为本篇的补充内容,您也许仍有必要了解以下要点:
(1)
在MAKEALL文件中可以将新的目标板xsbase270添加到下面的list中:
#########################################################
##XscaleSystems
LIST_pxa="
\
adsvix\
cerf250\
cradle\
csb226\
delta\
innokom\
lubbock\
pleb2\
pxa255_idp\
wepep250\
xaeniax\
xm250\
xsengine\
zylonite\
"
这并不是必须的,因为MAKEALL文件只用于为其中的所有目标板都编译一个u-boot时使用。
(2)
如何在U-Boot已有的目标板中找到与自己的目标板相近的目标板?
首要的是要找到与自己的目标板所用的处理器相同或统一系列的的目标板。
在顶层目录下的Makefile中有各个板子的config列表,例如XScale系列的板子列表如下:
##XScaleSystems
adsvix_config:
_config=)armpxaxsbase270
cerf250_config:
_config=)armpxacerf250
cradle_config:
_config=)armpxacradle
csb226_config:
_config=)armpxacsb226
delta_config:
_config=)armpxadelta
#.....
以下省略。
(3)
修改目标板的编译优化选项。
在cpu/pxa/config.mk文件中定义了目标板的编译优化选项PLATFORM_RELFLAGS和
PLATFORM_CPPFLAGS,您可以根据自己的需要进行修改。
笔者的交叉编译器arm-iwmmxt-linux-gnueabi-gcc默认有-march=iwmmxt,遵循新的ARMEABI标准,但仍要保留PLATFORM_CPPFLAGS中的“-mapcs-32,-mabi=apcs-gnu”选项,使用旧的ABI标准来编译,因为u-boot的汇编代码并非按照新的ABI规范编写。
可使用-march=armv5te来避免”warning:
targetCPUdoesnotsupportinterworking”警告。
如果编译过程中出现了关于IDE方面的错误,应修改include/configs/xsbase270.h,注释掉”#defineCONFIG_CMD_IDE”这一行,以禁止编译IDE的操作命令,因为在目标板启动阶段不需要对IDE接口进行其他操作。
U-Boot的移植之
(二)进阶篇:
从源代码看系统启动过程
为什么要分析源代码?
分析优秀的源代码本身就是一个学习的过程,也是进行深入研究的必经之路。
不过在此我们的主要目的并非要研究U-boot或Bootloader技术本身,而仅仅是为了成功的并且恰当的将U-Boot移植到我们的开发板上。
只有结合源代码了解了U-boot的系统引导过程,才能在移植和调试过程中保持清晰的思路,才能在碰到困难和问题时从根本上加以解决。
在动手分析之前,至少应该对U-Boot的源代码结构有基本的了解,很多参考书都有这方面的介绍,华清远见的《嵌入式Linux系统开发技术详解——基于ARM》的讲解就比较清晰。
本文以lubbock开发板为例,以系统启动的流程为线索进行纵向分析:
后续的移植工作也将以此开发板为模板。
Lubbock使用PXA255处理器。
首先要找到程序入口点。
从board/lubbock/u-boot.lds可以发现,u-boot的程序入口为_start,在cpu/pxa/start.o当中。
因此首先要分析start.S程序,U-Boot中所有的PXA系列的处理器都从这里开始执行第一条语句。
.globl
_start
_start:
breset
ldrpc,_undefined_instruction
ldrpc,_software_interrupt
ldrpc,_prefetch_abort
ldrpc,_data_abort
ldrpc,_not_used
ldrpc,_irq
ldrpc,_fiq
0x0地址开始是ARM异常向量表,学过ARM体系结构与编程的都明白,非常简单,不多废话。
一上电的第一条指令是跳转到reset复位处理程序:
reset:
/*
进入SVC模式
*/
#ifndefCONFIG_SKIP_LOWLEVEL_INIT
blcpu_init_crit
/*wedosys-criticalinits*/
#endif
#ifndefCONFIG_SKIP_RELOCATE_UBOOT
relocate:
......
一般不要定义CONFIG_SKIP_LOWLEVEL_INIT,因此,接下来跳转到cpu_init_crit处开始执行:
cpu_init_crit:
屏蔽所有中断
设置时钟源,关闭除FFUART,SRAM,SDRAM,FLASH以外的外设时钟
#ifdefCFG_CPUSPEED
ldrr0,CC_BASE
时钟控制寄存器基址
ldrr1,cpuspeed
/*cpuspeed:
.wordCFG_CPUSPEED*/
strr1,[r0,#CCCR]
movr0,#2
mcrp14,0,r0,c6,c0,0
setspeed_done:
#endif
/*CFG_CPUSPEED*/
跳转到lowlevel_init,这里ip即r12,用作暂存寄存器
movip,lr
bllowlevel_init
movlr,ip
/*Memoryinterfacesareworking.DisableMMUandenableI-cache.*/
ldrr0,=0x2001
关闭MMU,使能I-Cache(可选)*/
movpc,lr
这里是从cpu_init_crit返回到relocate标号
可见,在cpu_init_crit中的主要工作是设置时钟,配置处理器主频(这时CPU的工作频率还没有改变),调用lowlevel_init函数进行底层初始化(包括调整处理器工作频率、系统总线频率、存储器时钟频率以及存储系统的初始化等工作),随后关闭MMU并使能I-Cache,再返回。
lowlevel_init函数在board/lubbock/lowlevel_init.S中定义,其流程都是按照PXA27X的开发手册来的,所以不再赘述。
仅指出,其中的寄存器在include/asm-arm/arch-pxa/pxa-regs.h头文件中定义,寄存器初始化值在include/configs/lubbock.h中定义。
另外,在后面的实际移植工作中,由于目标板XSBASE270使用的PXA270处理器,可使用adsvix开发板的lowlevel_init.S文件(lubbock中没有开启turbo模式)。
接着程序的执行线索进行分析。
从cpu_init_crit返回后就开始relocate(重定位),即将U-boot从FLASH存储器搬运到SDRAM中TEXT_BASE开始的存储空间(TEXT_BASE在board/lubbock/config.mk中定义),并初始化堆栈(清零.bss段),以在SDRAM中开始进入到Bootloaderstage2的C程序入口。
Relocate部分开始的代码如下:
之前已定义的部分变量有:
_TEXT_BASE:
.wordTEXT_BASE
_armboot_start:
.word_start
_bss_start:
.word__bss_start
_bss_end:
.word_end*/
/*relocateU-BoottoRAM*/
adrr0,_start
/*r0<
-currentpositionofcode*/
ldrr1,_TEXT_BASE
/*testifwerunfromflashorRAM*/
cmpr0,r1
/*don'
trelocduringdebug*/
beq
stack_setup
ldrr2,_armboot_start
读入_start到r2*/
ldrr3,_bss_start
读入__bss_start到r3*/
subr2,r3,r2
/*r2<
-sizeofarmboot*/
addr2,r0,r2
-sourceendaddress*/
copy_loop:
ldmiar0!
{r3-r10}
/*copyfromsourceaddress[r0]*/
stmiar1!
/*copytotargetaddress[r1]*/
cmpr0,r2
/*untilsourceendaddreee[r2]*/
blecopy_loop
/*Setupthestack*/
stack_setup:
ldrr0,_TEXT_BASE
/*upper128KiB:
relocateduboot*/
subr0,r0,#CFG_MALLOC_LEN
/*mallocarea*/
subr0,r0,#CFG_GBL_DATA_SIZE
/*bdinfo*/
#ifdefCONFIG_USE_IRQ
subr0,r0,#(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
subsp,r0,#12
/*leave3wordsforabort-stack*/
clear_bss:
ldrr0,_bss_start
/*findstartofbsssegment*/
ldrr1,_bss_end
/*stophere*/
movr2,#0x00000000
/*clear*/
clbss_l:
strr2,[r0]
/*clearloop...*/
addr0,r0,#4
cmpr0,r1
bleclbss_l
ldrpc,
_start_armboot
_start_armboot:
.wordstart_armboot
这是很经典的一段代码,相信学习凡是过ARM编程的,都分析过这段代码,所以也不再赘述。
之所以列出这段代码,一是为了找到C程序入口start_armboot,二是为了给出U-Boot的一个存储器映射图:
这个图可以帮助我们更好地理解后续的C语言代码以及U-Boot对内存的分配与使用情况。
接下来进入到BootloaderStage2即C语言代码部分,入口是start_armboot,对应的源文件是lib_arm/board.c,这一文件对所有的ARM处理器都是通用的,因此在移植的时候不用修改。
相关源代码如下:
DECLARE_GLOBAL_DATA_PTR;
在include/asm-arm/global_data.h中定义的一个全局寄存器变量的声明:
*#defineDECLARE_GLOBAL_DATA_PTRregistervolatilegd_t*gdasm("
r8"
)
*
用于存放全局数据结构体gd_t的地址。
void
start_armboot(void)
{
init_fnc_t**init_fnc_ptr;
char
*s;
#ifndefCFG_NO_FLASH
ulongsize;
#ifdefined(CONFIG_VFD)||defined(CONFIG_LCD)
本次移植暂不配置VFD和LCD,后面也将不考虑的部分略去
初始化全局数据结构体指针gd*/
gd=(gd_t*)(_armboot_start-CFG_MALLOC_LEN-
sizeof(gd_t));
....../*memset在lib_generic/string.c中定义*/
memset((void*)gd,0,
sizeof
(gd_t));
/*用0填充全局数据表*gd*/
gd->
bd=(bd_t*)((char*)gd-
sizeof(bd_t));
memset(gd->
bd,0,sizeof(bd_t));
/*用0填充(初始化)*gd->
bd*/
monitor_flash_len=_bss_start-_armboot_start;
for
(init_fnc_ptr=init_sequence;
*init_fnc_ptr;
++init_fnc_ptr){
if
((*init_fnc_ptr)()!
=0){
hang();
打印错误信息并死锁
}
/*configureavailableFLASHbanks*/
size=flash_init();
/*drivers/cfi_flash.c或自定义
display_flash_config(size);
/*CFG_NO_FLASH*/
/*armboot_startisdefinedintheboard-specificlinkerscript*/
mem_malloc_init(_armboot_start-CFG_MALLOC_LEN);
/*initializeenvironment*/
env_relocate();
/*IPAddress*/
bd->
bi_ip_addr=getenv_IPaddr("
ipaddr"
);
/*MACAddress*/
int
i;
ulongreg;
*s,*e;
tmp[64];
i=getenv_r("
ethaddr"
tmp,sizeof(tmp));
s=(i>
0)?
tmp:
NULL;
(reg=0;
reg<
6;
++reg){
bi_enetaddr[reg]=s?
simple_strtoul(s,&
e,16):
0;
(s)
s=(*e)?
e+1:
e;
devices_init();
/*getthedeviceslistgoing.*/
.......
jumptable_init();
console_init_r();
/*fullyinitconsoleasadevice*/
enable_interrupts();
/*enableexceptions*/
/*Performnetworkcardinitialisationifnecessary*/
#ifdefined(CONFIG_DRIVER_SMC91111)||defined(CONFIG_DRIVER_LAN91C96)
(getenv("
))
smc_set_mac_addr(gd->
bi_enetaddr);
/*CONFIG_DRIVER_SMC91111||CONFIG_DRIVER_LAN91C96*/
/*Initializefromenvironment*/
((s=getenv("
loadaddr"
))!
=NULL){
load_addr=simple_strtoul(s,NULL,16);
#ifdefined(CONFIG_CMD_NET)
bootfile"
=NULL)
copy_filename(BootFile,s,sizeof(BootFile));
#ifdefBOARD_LATE_INIT
board_late_init();
/*main_loop()canreturntoretryautoboot,ifsojustrunitagain.*/
(;
;
){
main_loop();
gd_t是全局数据表类型,在include/asm-arm/global_data.h中定义如下:
/*
Keepit*SMALL*andrememberto
setCFG_GBL_DATA_SIZE>
sizeof(gd_t)
typedef
struct
global_data{
bd_t*bd;
unsignedlong
flags;
baudrate;
have_console;
/*serial_init()wascalled*/
reloc_off;
/*RelocationOffset
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- UBoot的移植UBoot Practically Porting Guide UBoot 移植
链接地址:https://www.bdocx.com/doc/16333019.html