uboot启动流程Word文档下载推荐.docx
- 文档编号:19503336
- 上传时间:2023-01-07
- 格式:DOCX
- 页数:19
- 大小:25.81KB
uboot启动流程Word文档下载推荐.docx
《uboot启动流程Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《uboot启动流程Word文档下载推荐.docx(19页珍藏版)》请在冰豆网上搜索。
(3)初始化系统内存分配函数。
(4)如果目标系统拥有NAND设备,则初始化NAND设备。
(5)如果目标系统有显示设备,则初始化该类设备。
(6)初始化相关网络设备,填写IP、MAC地址等。
(7)进去命令循环(即整个boot的工作循环),接受用户从串口输入的命令,然后进行相应的工作。
3U-Boot.lds代码分析
/*******************************************************/
OUTPUT_FORMAT("
elf32-littlearm"
"
"
)
;
指定输出可执行文件是elf格式,32位ARM指令,小端
OUTPUT_ARCH(arm)
指定输出可执行文件的平台为ARM
ENTRY(_start)
指定输出可执行文件的起始代码段为_start.
SECTIONS
{
.=0x00000000;
指明目标代码的起始地址从0x0位置开始,"
."
代表的是当前位置
.=ALIGN(4);
代码以4字节对齐
.text:
指定代码段
{
cpu/arm920t/start.o(.text);
代码的第一个代码部分,指明start.s是入口程序代码,被放到代码段的开头
*(.text);
其它代码部分
}
.=ALIGN(4)
.rodata:
{*(.rodata)};
指定只读数据段,RO段
.=ALIGN(4);
.data:
{*(.data)};
指定读/写数据段,RW段
.got:
{*(.got)};
指定got段,got段式是uboot自定义的一个段,非标准段
__u_boot_cmd_start=.;
把__u_boot_cmd_start赋值为当前位置,即起始位置
.u_boot_cmd:
{*(.u_boot_cmd)};
指定u_boot_cmd段,uboot把所有的uboot命令放在该段.
__u_boot_cmd_end=.;
把__u_boot_cmd_end赋值为当前位置,即结束位置
__bss_start=.;
把__bss_start赋值为当前位置,即bss段的开始位置
.bss:
{*(.bss)};
指定bss段
_end=.;
把_end赋值为当前位置,即bss段的结束位置
}
/****************************************/
从这里可以看出start.s是程序的入口点。
4start.S代码分析
//global声明一个符号可被其它文件引用,相当于声明了一个全局变量,.globl与.global相同。
//该部分为处理器的异常处理向量表。
地址范围为0x00000000~0x00000020,刚好8条指令。
.globl_start
_start:
breset/*跳转到reset标号执行*/
ldrpc,_undefined_instruction
ldrpc,_software_interrupt
ldrpc,_prefetch_abort
ldrpc,_data_abort
ldrpc,_not_used
ldrpc,_irq
ldrpc,_fiq
//.word伪操作用于分配一段字内存单元(分配的单元都是字对齐的),并用伪操作中的expr初始化。
.long与.int作用与之//相同。
_undefined_instruction:
.wordundefined_instruction
_software_interrupt:
.wordsoftware_interrupt
_prefetch_abort:
.wordprefetch_abort
_data_abort:
.worddata_abort
_not_used:
.wordnot_used
_irq:
.wordirq
_fiq:
.wordfiq
.balignl16,0xdeadbeef
/*
*StartupCode(resetvector)
*
*doimportantinitonlyifwedon'
tstartfromRAM!
*-relocatearmboottoram
*-setupstack
*-jumptosecondstage
*/
//TEXT_BASE在开发板相关的目录中的config.mk文件中定义,它定义了
//代码在运行时所在的地址,那么_TEXT_BASE中保存了这个地址
_TEXT_BASE:
.wordTEXT_BASE
//声明_armboot_start并用_start来进行初始化,在board/u-boot.lds中定义。
.globl_armboot_start
_armboot_start:
.word_start
*Thesearedefinedintheboard-specificlinkerscript.
//声明_bss_start并用__bss_start来初始化,其中__bss_start定义在与板相关的u-boot.lds中。
//_bss_start保存的是__bss_start这个标号所在的地址,这里涉及到当前代码所在
//的地址不是编译时的地址的情况,这里直接取得该标号对应的地址,不受编译时
//地址的影响._bss_end也是同样的道理.
.globl_bss_start
_bss_start:
.word__bss_start
//同上
.globl_bss_end
_bss_end:
.word_end
#ifdefCONFIG_USE_IRQ
/*IRQstackmemory(calculatedatrun-time)*/
.globlIRQ_STACK_START
IRQ_STACK_START:
.word0x0badc0de
.globlFIQ_STACK_START
FIQ_STACK_START:
#endif
//MRS{<
cond>
}Rd,CPSR|SPSR将CPSR|SPSR传送到Rd
//使用这两条指令将状态寄存器传送到一般寄存器,只修改必要的位,再将结果传送回状态寄存器,这样可以最好地完成对CRSP或者SPSR的修改
//MSR{<
}CPSR_<
field>
|SPSR_<
Rm或者是MSR{<
}CPSR_f|SPSR_f,#<
32-bitimmediate>
//MRS与MSR配合使用,作为更新PSR的“读取--修改--写回”序列的一部分
//bicr0,r1,r2;
r0:
=r1andnotr2
//orrro,r1,r2;
=r1orr2
//这几条指令执行完毕后,进入SVC模式,该模式主要用来处理软件中断(SWI)
reset:
mrsr0,cpsr/*setthecputoSVC32mode*/
bicr0,r0,#0x1f/*(supervisermode,M=10011)*/
orrr0,r0,#0xb3/*disableirqandfrqSVCmode*/
msrcpsr,r0
/*关闭看门狗,S3C2410手则*/
#ifdefined(CONFIG_S3C2400)
#definepWTCON0x15300000
#defineINTMSK0x14400008/*Interupt-Controllerbaseaddresses*/
#defineCLKDIVN0x14800014/*clockdivisorregister*/
#elifdefined(CONFIG_S3C2410)
#definepWTCON0x53000000
#defineINTMSK0x4A000008/*Interupt-Controllerbaseaddresses*/
#defineINTSUBMSK0x4A00001C
#defineCLKDIVN0x4C000014/*clockdivisorregister*/
#ifdefined(CONFIG_S3C2400)||defined(CONFIG_S3C2410)
ldrr0,=pWTCON
movr1,#0x0
strr1,[r0]
/*
*屏蔽所有中断
*/
movr1,#0xffffffff
ldrr0,=INTMSK
#ifdefined(CONFIG_S3C2410)
ldrr1,=0x3ff
ldrr0,=INTSUBMSK
#endif
/*设置FCLK:
HCLK:
PCLK=1:
2:
4*/
/*FCLK默认为120MHz!
ldrr0,=CLKDIVN
movr1,#3
#endif/*CONFIG_S3C2400||CONFIG_S3C2410*/
/*该语句首先调用cpu_init_crit进行CPU的初始化,并把下一条指令的地址保存在LR中,以使得执行完后能够正常返回。
后面会分析*/
#ifndefCONFIG_SKIP_LOWLEVEL_INIT
blcpu_init_crit
//调试阶段的代码是直接在RAM中运行的,而最后需要把这些代码固化到Flash中,因此U-Boot需要自己从Flash转移到
//RAM中运行,这也是重定向的目的所在。
//通过adr指令得到当前代码的地址信息:
如果U-boot是从RAM开始运行,则从adr,r0,_start得到的地址信息为
//r0=_start=_TEXT_BASE=TEXT_BASE=0xa3000000;
如果U-boot从Flash开始运行,即从处理器对应的地址运行,
//则r0=0x0000,这时将会执行copy_loop标识的那段代码了。
//_TEXT_BASE定义在board/pxa255_idp/config.mk中
#ifndefCONFIG_SKIP_RELOCATE_UBOOT
relocate:
/*relocateU-BoottoRAM*/
adrr0,_start/*r0<
-currentpositionofcode*/
ldrr1,_TEXT_BASE/*testifwerunfromflashorRAM*/
cmpr0,r1/*don'
trelocduringdebug*/
beqstack_setup
ldrr2,_armboot_start
ldrr3,_bss_start
subr2,r3,r2/*r2<
-sizeofarmboot*/
addr2,r0,r2/*r2<
-sourceendaddress*/
copy_loop:
ldmiar0!
{r3-r10}/*copyfromsourceaddress[r0]*/
stmiar1!
{r3-r10}/*copytotargetaddress[r1]*/
cmpr0,r2/*untilsourceendaddreee[r2]*/
blecopy_loop
#endif/*CONFIG_SKIP_RELOCATE_UBOOT*/
/*Setupthestack*/
stack_setup:
ldrr0,_TEXT_BASE/*upper128KiB:
relocateduboot*/
subr0,r0,#CFG_MALLOC_LEN/*mallocarea*/
subr0,r0,#CFG_GBL_DATA_SIZE/*bdinfo*/
//这里如果需要使用IRQ,还有给IRQ保留堆栈空间
subr0,r0,#(CONFIG_STACKSIZE_IRQ+CONFIG_STACKSIZE_FIQ)
//这里是直接减去12,但是在后面board.c中的cpu_init中代码是减8再减4的(如下),大家看到后面再反过来看看,会觉得很有意//思
intcpu_init(void)
*setupupstacksifnecessary
IRQ_STACK_START=_armboot_start-CFG_MALLOC_LEN-CFG_GBL_DATA_SIZE-4;
FIQ_STACK_START=IRQ_STACK_START-CONFIG_STACKSIZE_IRQ;
return0;
subsp,r0,#12/*leave3wordsforabort-stack*/
//该部分将未初始化数据段_bss_start----_bss_end中的数据清零。
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
#if0
/*trydoingthisstuffaftertherelocation*/
*maskallIRQsbysettingallbitsintheINTMR-default
ldrr0,=INTMR
/*FCLK:
/*defaultFCLKis120MHz!
/*ENDstuffafterrelocation*/
//通过该语句跳转到C代码执行,stage1的使命也算完成。
ldrpc,_start_armboot
_start_armboot:
.wordstart_armboot
cpu_init_crit:
*flushv4I/Dcaches
movr0,#0
mcrp15,0,r0,c7,c7,0/*flushv3/v4cache*/
mcrp15,0,r0,c8,c7,0/*flushv4TLB*/
*关闭MMU和缓存,这里用到了协处理器P15,参看手则,哈哈,这里有的很多看了
mrcp15,0,r0,c1,c0,0
bicr0,r0,#0x00002300@clearbits13,9:
8(--V---RS)
bicr0,r0,#0x00000087@clearbits7,2:
0(B----CAM)
orrr0,r0,#0x00000002@setbit2(A)Align
orrr0,r0,#0x00001000@setbit12(I)I-Cache
mcrp15,0,r0,c1,c0,0
/*进入lowlevel_init,这里主要是初始化存储控制器,S3C2410的是Bank0-bank6,比如位宽等,这个要根据自己的板子来进行相应的配置,比如网卡放在第几个bank,位宽多少,SDRAM放在哪里,多大等,移植UBOOT的时候就有的学了*/
movip,lr
bllowlevel_init
movlr,ip
movpc,lr
#endif/*CONFIG_SKIP_LOWLEVEL_INIT*/
//程序后面的都是中断的处理,定义了一系列的宏,然后就是中断的处理函数和异常处理函数,这里就不在列出了
5.
main_loop()函数
main_loop()函数做的都是与具体平台无关的工作,主要包括初始化启动次数限制机制、设置软件版本号、打印启动信息、解析命令等。
(1)设置启动次数有关参数。
在进入main_loop()函数后,首先是根据配置加载已经保留的启动次数,并且根据配置判断是否超过启动次数。
代码如下:
1.295
void
main_loop
(void)
2.296
{
3.297
#ifndef
CFG_HUSH_PARSER
4.298
static
char
lastcommand[CFG_CBSIZE]
=
{
0,
};
5.299
int
len;
6.300
rc
1;
7.301
flag;
8.302
#endif
9.303
10.304
#if
defined(CONFIG_BOOTDELAY)
&
(CONFIG_BOOTDELAY
>
0)
11.305
*s;
12.306
bootdelay;
13.307
14.308
#ifdef
CONFIG_PREBOOT
15.309
*p;
16.310
17.311
CONFIG_BOOTCOUNT_LIMIT
18.312
unsigned
long
bootcount
0;
19.313
bootlimit
20.314
*bcs;
21.315
bcs_set[16];
22.316
#endif
/*
CONFIG_BOOTCOUNT_LIMIT
*/
23.317
24.318
defined(CONFIG_VFD)
defined(VFD_TEST_LOGO)
25.319
ulong
bmp
default
bitmap
26.320
extern
trab_vfd
(ulong
bitmap);
27.321
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- uboot 启动 流程