WINCE60+S3C2443的启动过程eboot.docx
- 文档编号:2555971
- 上传时间:2023-05-04
- 格式:DOCX
- 页数:49
- 大小:914.12KB
WINCE60+S3C2443的启动过程eboot.docx
《WINCE60+S3C2443的启动过程eboot.docx》由会员分享,可在线阅读,更多相关《WINCE60+S3C2443的启动过程eboot.docx(49页珍藏版)》请在冰点文库上搜索。
WINCE60+S3C2443的启动过程eboot
WINCE6.0+S3C2443的启动过程---eboot
********************************LoongEmbedded***********************
作者:
LoongEmbedded(kandi)
时间:
2010.10.15
类别:
WINCEbootloader开发
********************************LoongEmbedded***********************
我们知道从nboot把eboot从nandflash中拷贝到内存指定的地址后,就接着在这个地址处开始运行eboot了,之后,nboot的工作就完成了,那么那么eboot开始执行的地址在哪里呢?
我们看看\Src\Bootloader\Eboot\boot.bib下面的配置
MEMORY
;NameStartSizeType
;---------------------------
ARGS8002080000000800RESERVED
RAM800210000000B000RAM
STACK8002c0000000A000RESERVED
EBOOT8003800000040000RAMIMAGE
BINFS8008000000021000RESERVED
我们根据EBOOT的这一项可以知道,EBOOT对应的虚拟起始地址就是0x80038000,实际的物理地址是0x30038000,根据\Src\Bootloader\Eboot\sources下面的内容
TARGETNAME=eboot
TARGETTYPE=PROGRAM
RELEASETYPE=PLATFORM
EXEENTRY=StartUp
可知eboot的入口是StartUp,下面两个图是从eboot.map的截取出来的
通过上图可以知道eboot的入口地址是0x00009d68
根据上图可知StartUp函数的地址是0x00009d68,所以可以确定eboot的入口地址就是Startup函数,也就是eboot从这个Startup函数开始执行。
1.startup函数
系统上电后第一步就是运行Startup函数的代码,这是一个汇编语言函数,主要其最主要功能是执行芯片级初始化:
禁止中断,配置系统时钟频率,复制BootLoader镜像到内存,设置存储器的读写周期,构造内存映射表,启用MMU,并启用虚拟内存等操作。
Startup函数有两条重要的地址定义,定义ram空间的物理基地址和页表的基地址,这是startup函数主要操作的物理地址空间,如下所示
定义RAM空间的物理基地址和页表的基地址
PHYBASEEQU0x30000000;physicalstart
PTsEQU0x30010000;1stlevelpagetableaddress(PHYBASE+0x10000)
;saveroomforinterruptvectors.
本文来自CSDN博客,转载请标明出处:
1.1startup函数的入口
入口函数首先通过对协处理器的操作来清空TLB、指令Cache和数据Cache
p15是系统控制协处理器,主要是对内存还有cashe进行管理。
mcr指令,把ARM寄存器中的值传递到协处理寄存器中。
C8是TLBControl寄存器,C7是Cache/WriteBufControl寄存器,
ResetHandler
;MakesurethatTLB&cacheareconsistent
movr0,#0
mcrp15,0,r0,c8,c7,0;flushbothTLB
mcrp15,0,r0,c7,c5,0;invalidateinstructioncache
mcrp15,0,r0,c7,c6,0;invalidatedatacache
下面为了更好去理解上面这段代码,我们来学习相关知识:
MCR和MRC
对CP15协处理器的操作使用mcr和mrc两条协处理器指令,这两条指令的记法是从后往前看:
mcr是把r(CPU核寄存器)中的数据传送到c(协处理器寄存器)中,mrc则是把c(协处理器寄存器)中的数据传送到r(CPU核寄存器)中。
对CP15协处理器的所有操作都是通过CPU核寄存器和CP15寄存器之间交换数据来完成的。
TLB
TLB(translationlookasidebuffer),旁路转换缓冲区,或称页表缓冲,里面存放的是一些页表文件(虚拟地址到物理地址的转换表),TLB是MMU中的一块高速缓存(也是一种cache),它缓存最近查找过的V对应的页表项,如果TLB里缓存了当前VA的页表项就不必做TranslationTableWalk(也就是从发出VA到定位到PA的过程)了,否则去物理内存中读出页表项来保存在TLB中,TLB缓存可以减少访问物理内存的次数。
instructioncache
instructioncache(ICache),cache是高速缓冲存储器,是介于CPU和主存之间的缓冲器,ICache是用于存在正在执行的指令地址附近的一部分指令,供CPU在一段时间内使用。
当系统上电或重起(Reset)的时候,ICaches功能是被关闭的,我们必须往lcrbit置1去开启它,lcrbit在CP15协处理器中控制寄存器1的第12位(关闭ICaches功能则是往该位置0)。
ICaches功能一般是在MMU开启之后被使用的(为了降低MMU查表带来的开销),但有一点需要注意,并不是说MMU被开启了ICaches才会被开启,正如本段刚开始讲的,ICaches的开启与关闭是由lcrbit所决定的,无论MMU是否被开启,只要lcrbit被置1了,ICaches就会发挥它的作用,见下图
datacache
datacache(DCache),cache是高速缓冲存储器,是介于CPU和主存之间的缓冲器,DCache是用于存在正在执行的指令地址附近的一部分数据,供CPU在一段时间内使用。
ARM920T有16KB的ICache,也有16KB的DCache,另外外加4KB的steppingstone,那么S3C2440自带的RAM有36KB.
与ICaches一样,系统上电或重起(Reset)的时候,DCaches功能是被关闭的,我们必须往Ccrbit置1去开启它,Ccrbit在CP15协处理器中控制寄存器1的第2位(关闭DCaches功能则是往该位置0)。
与ICaches不同,DCaches功能是必须在MMU开启之后才能被使用的。
Eboot是通过下面的操作来disableICache和DCache的
mcrp15,0,r0,c7,c5,0;invalidateinstructioncache
mcrp15,0,r0,c7,c6,0;invalidatedatacache
c7是个只写寄存器,这个寄存器用来管理ICache和DCache,其中包括Invalidatecache
见下图我们就知道上面代码的意义了。
--->待续1
1.2关闭所有的CPU中断
通过对INTMSK,INTSUBMSK寄存器特定为设置为1来屏蔽中断源的中断请求,接着通过对中断模式寄存器INTMOD清零来把中断设置为IRQ模式。
1.3系统时钟设置
我的另一篇博客介绍了S3C2443的时钟管理
这些红色字体的值在S3C2443.inc文件中定义,
Startup_MdivEQU81
Startup_PdivEQU2
Startup_SdivEQU1
这些值的实际意义是什么呢?
我们先来看看上图的第188行到190行对MPLLCON寄存器的设置,结合下表
可知FOUT=534MHZ,这就是MSysClk,也就是ARMCLK、HCLK、PCLK、DDRCLK等时钟的基准时钟,下图可以很清楚描述这些时钟的关系
现在我们知道FOUT=534MHZ了,S3C2443.inc文件中定义
Startup_ARMCLKdivEQU0
Startup_PREdivEQU0x1
Startup_HCLKdivEQU0x1
Startup_PCLKdivEQU1
那么这些值代表的意义是什么呢?
其中Startup_ARMCLKdiv=0,根据CLKDIVO寄存器对ARMDIV位的定义可知ARMCLK=MSysClk=534MHZ,也就是ARM内核的主频是534MHZ。
Startup_PREdiv=1,根据上图,可知MSysClkPreDiv=MSysClk/2。
Startup_HCLKdiv=1,Startup_PCLKdiv=1,根据下表可知HCLK:
DDRCLK:
PCLK=4:
2:
8,可以得到HCLK=ARMCLK/4,PCLK=ARMCLK/8
这些关系会在bsp_cfg.h中对FCLK、PCLK和HCLK中得到体现。
下面接着看对CLKSRC寄存器的设置
ldrr0,=CLKSRC;SelectMPLLclockoutforSYSCLK
ldrr1,[r0]
orrr1,r1,#0x50
strr1,[r0]
上面代码主要是选择MPLL输出作为MSysClk的基准时钟,选择EPLL输出作为ESYSCLK的基准时钟。
1.4设置CPU的总线模式
通过调用函数MMU_SetAsyncBusMode来把CPU的总线模式设置为同步模式
blMMU_SetAsyncBusMode
此函数体定义如下
MMU_SetAsyncBusMode
mrcp15,0,r0,c1,c0,0
orrr0,r0,#R1_nF:
OR:
R1_iA
mcrp15,0,r0,c1,c0,0
movpc,lr
通过上图我们可知mrcp15,0,r0,c1,c0,0是用于读取控制寄存器C1到R0中,也知道C1在系统复位后C1控制寄存器除了V位之外的所有控制位都为0,见下图
那么就是上电复位后,控制寄存器C1的iA和nF位,也即iA和nF位这两位的值也为0,下表是iA和nF位这两位组合的定义
结合上面这些图表及下面的定义
R1_iAEQU(1<<31)
R1_nFEQU(1<<30)
所以orrr0,r0,#R1_nF:
OR:
R1_iA的意义就是先判断R1_nF是否为1,如为1,则对C1的nF位做或运算,也即把CPU的时钟模式设置为Synchronous模式;如为0,则对C1的iA位做或运算,也即把CPU的时钟模式设置为FastBus模式,接着通过mcrp15,0,r0,c1,c0,0语句把运算后的结果写回C1控制寄存器。
1.5设置CLKOUT0和CLKOUT1的时钟源
设置CLKOUT0的时钟源为PCLK,设置CLKOUT1的时钟源为HCLK。
ldrr0,=MISCCR
ldrr1,[r0]
bicr1,r1,#0x770
orrr1,r1,#0x320
strr1,[r0]
配置GPH13和GPH14分别为CLKOUT0与CLKOUT1。
ldrr0,=GPHCON
ldrr1,[r0]
bicr1,r1,#0x3C000000
orrr1,r1,#0x28000000
strr1,[r0]
--->待续2
1.6
OEMAddresstable只是用来初始化一级页表,就是所谓的段(section)描述,每个段是1MB,分为4096个段,总共4G——虚拟内存空间4G就是由此而来。
并且这个OEMAddresstable可以用在查表法中用来转换虚拟地址、物理地址(相互转换都可以)。
PTs(pointertosection)的相关定义如下:
;DefineRAMspaceforthePageTables:
;
PHYBASEEQU0x30000000;physicalstart
PTsEQU0x30010000;1stlevelpagetableaddress(PHYBASE+0x10000)
PTs保存在物理内存中的地址是0x30010000,上图的301行的0x2000是什么意义呢?
我们知道没有缓存的虚拟地址起始地址是0x80000000,那这个虚拟地址对应的物理地址是多少呢?
根据VA映射到PA的规则,见下图:
从0x80000000中取出[31:
20]位,也即0x800来左移2位之后(0x2000,这个就是上面这个值的来由)加上translationbase(在这里是PTs),也即上图addr10,r10,#0x2000这行语句的意义,执行这行语句之后r0=0x30012000,这就是计算了4G虚拟地址空间中从0x80000000地址开始的虚拟地址对应的物理起始地址是0x30012000,也就是sectionbaseaddress=0x30012000。
PTE:
pointertoenter
接下来
我们知道r1指向g_oalAddressTable,假如g_oalAddressTable的定义如下:
g_oalAddressTable
[{TRUE}
DCD0x80000000,0x30000000,128;128MBDRAMBANK6
…………………………
DCD0x00000000,0x00000000,0;endoftable
]
那么上面语句的307到309行就是实现(r2)=0x80000000,(r3=0x30000000)和(r4=128)这些功能,而311行就是用于判断在建立一级页表是否完成,如果完成,也即cacheable地址0x80000000~0xa0000000这段虚拟内存映射的物理内存创建完毕,就跳到下面标号为40的地方开始执行;如果没有完成,会接下来执行。
ldrr5,=0x1FF00000
andr2,r2,r5;VAneeds512MB,1MBaligned.
因为是对0x80000000~0xa0000000这段虚拟内存映射(512MB),并且是要求1MB对齐的,所以需要用0x1FF00000来保证。
ldrr5,=0xFFF00000
andr3,r3,r5;PAneeds4GB,1MBaligned.
对PA物理地址进行4G对齐。
addr2,r10,r2,LSR#18
addr0,r0,r3;(r0)=PTEfornextphysicalpage
获取下一个物理页的入口地址。
35strr0,[r2],#4
addr0,r0,#0x00100000;(r0)=PTEfornextphysicalpage
1M递增,因为1<<18=256K,而每一个pte描述4k页,所以最终描述256k*4k=1M地址空间
subr4,r4,#1;DecrementnumberofMBleft
cmpr4,#0
bne%b35;MapnextMB
遍历到该region结束
bicr0,r0,#0xF0000000;ClearSectionBaseAddressField
bicr0,r0,#0x0FF00000;ClearSectionBaseAddressField
清空r0中的地址信息
b%b30;Getnextelement
继续创建oemaddrtab_cfg.inc描述的下一region
40tstr0,#8
bicr0,r0,#0x0C;clearcachable&bufferablebitsinPTE
addr10,r10,#0x0800;(r10)=ptrto1stPTEfor"unmappeduncachedspace"
bne%b25;gosetupPTEsforuncachedspace
subr10,r10,#0x3000;(r10)=restoreaddressof1stlevelpagetable
;1.Setupmmutomap(VA==0)to(PA==0x30000000).
;1-1.cachedarea.
ldrr0,=PTs;PTEentryforVA=0
ldrr1,=0x3000040E;cache/buffer/rw,PAbase==0x30000000
;ldrr1,=0x30000402;cache/buffer/rw,PAbase==0x30000000
strr1,[r0]
;1-2.uncachedarea.
addr0,r0,#0x0800;PTEentryforVA=0x0200.0000,uncached
ldrr1,=0x30000402;uncache/unbuffer/rw,base==0x30000000
strr1,[r0]
;Comment:
;ThefollowingloopistodirectmapRAMVA==PA.i.e.
;VA==0x30XXXXXX=>PA==0x30XXXXXXforS3C2400
;Fillin8entriestohaveadirectmappingforDRAM
;
ldrr10,=PTs;restoreaddressof1stlevelpagetable
ldrr0,=PHYBASE
addr10,r10,#(0x3000/4);(r10)=ptrto1stPTEfor0x30000000
addr0,r0,#0x1E;1MBcachablebufferable
orrr0,r0,#0x400;setkernelr/wpermission
movr1,#0
movr3,#64
45movr2,r1;(r2)=virtualaddresstomapBankat
cmpr2,#0x20000000:
SHR:
BANK_SHIFT
addr2,r10,r2,LSL#BANK_SHIFT-18
strlor0,[r2]
addr0,r0,#0x00100000;(r0)=PTEfornextphysicalpage
subsr3,r3,#1
addr1,r1,#1
bgt%b45
ldrr10,=PTs;(r10)=restoreaddressof1stlevelpagetable
一级页表的映射关系建立完成之后,要把一级页表的基地址保存会r10中。
;Thepagetablesandexceptionvectorsaresetup.
;InitializetheMMUandturniton.
movr1,#1
mcrp15,0,r1,c3,c0,0;setupaccesstodomain0
mcrp15,0,r10,c2,c0,0
mcrp15,0,r0,c8,c7,0;flushI+DTLBs
mrcp15,0,r1,c1,c0,0
orrr1,r1,#0x0071;Enable:
MMU
orrr1,r1,#0x0004;Enablethecache
ldrr0,=VirtualStart
cmpr0,#0;makesurenostallon"movpc,r0"below
mcrp15,0,r1,c1,c0,0
movpc,r0;&jumptonewvirtualaddress
nop
;MMU&cachesnowenabled.
;(r10)=physcialaddressof1stlevelpagetable
;
VirtualStart
movsp,#0x80000000;havetobemodefied.referoemaddrtab_cfg.inc,DonGo
addsp,sp,#0x30000;arbitraryinitialsuper-pagestackpointer
注意0x80000000+0x30000=0x80030000,不能超过eboot\boot.bib中下面
MEMORY
;NameStartSizeType
;---------------------------
ARGS8002080000000800RESERVED
RAM800210000000B000RAM
STACK8002c0000000A000RESERVED
EBOOT8003800000040000RAMIMAGE
BINFS8008000000021000RESERVED
对stack中指定的值,也即0x8002c000+0x0000A000=0x80036000,其对应的物理地址是0x30036000,也即0x80000000+0x30000的值要在0x3002c000~0x30036000之间。
bmain
到这里就跳转到eboot的main函数了。
ENTRY_END
----》待续
2main函数
voidmain(void)
{
//MemoryTest_Function();
BootloaderMain();
//Shouldnevergethere.
SpinForever();
}
Main函数主要是通过调用BootloaderMain函数来实现其功能的,下面来看看BootloaderMain函数的流程图:
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- WINCE60 S3C2443 启动 过程 eboot