uboot启动流程Word文档下载推荐.docx

上传人:b****5 文档编号:19503336 上传时间:2023-01-07 格式:DOCX 页数:19 大小:25.81KB
下载 相关 举报
uboot启动流程Word文档下载推荐.docx_第1页
第1页 / 共19页
uboot启动流程Word文档下载推荐.docx_第2页
第2页 / 共19页
uboot启动流程Word文档下载推荐.docx_第3页
第3页 / 共19页
uboot启动流程Word文档下载推荐.docx_第4页
第4页 / 共19页
uboot启动流程Word文档下载推荐.docx_第5页
第5页 / 共19页
点击查看更多>>
下载资源
资源描述

uboot启动流程Word文档下载推荐.docx

《uboot启动流程Word文档下载推荐.docx》由会员分享,可在线阅读,更多相关《uboot启动流程Word文档下载推荐.docx(19页珍藏版)》请在冰豆网上搜索。

uboot启动流程Word文档下载推荐.docx

(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 

展开阅读全文
相关资源
猜你喜欢
相关搜索

当前位置:首页 > 医药卫生

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1