S3C2410下WinCE60的启动过程详解

上传人:lis****211 文档编号:117667197 上传时间:2022-07-09 格式:DOCX 页数:24 大小:218.90KB
收藏 版权申诉 举报 下载
S3C2410下WinCE60的启动过程详解_第1页
第1页 / 共24页
S3C2410下WinCE60的启动过程详解_第2页
第2页 / 共24页
S3C2410下WinCE60的启动过程详解_第3页
第3页 / 共24页
资源描述:

《S3C2410下WinCE60的启动过程详解》由会员分享,可在线阅读,更多相关《S3C2410下WinCE60的启动过程详解(24页珍藏版)》请在装配图网上搜索。

1、S3C2410下WinCE6.0的启动过程详解通过前两篇文章的介绍,我们已经知道NBOOT用来引导EBOOT,继而 EBOOT加载并引导WinCE操作系统(NK)。那么,WinCE6.0的启动过程又是 怎样的呢?本文基于S3C2410的平台做一个详细的分析。需要说明的是, WinCE6.0的整个启动过程对于同一类型的MCU来说大同小异,如S3C2410 和PXA270同属ARM平台的MCU,所以他们的启动过程是类似的,可以说 唯一的不同就在OAL处,而WinCE操作系统的启动正是从OAL开始的。OAL (OEMAdaptation Layer)即OEM适配层,它的主要作用是在移 植WinCE到

2、新的硬件平台时减少操作系统的修改,通俗的说就是为WinCE 操作系统抹平MCU的差异,使其能很方便的在不同MCU上运行。所以,OAL 包括了和系统硬件通讯的最底层代码。内核则通过OAL跟硬件进行交互。 逻辑上, OAL 是介于 CE 内核和设备硬件之间的一个代码层,是一个抽象 的概念。物理上,OAL和其他一些库一起链接成可执行文件,在WinCE6.0 中对应的文件是OAL.exe,这是OAL的客观存在。WinCE6.0中的OAL跟先 前的OAL比,是有一些变化的,它从内核中分离出来成为OAL.exe,而内 核则变成了 Kernel.dll。这样做的好处是可以单独升级OAL。但整体的 OAL结构

3、并没有改变,OEM函数保持一致,OAL和Kernel的接口由共享结 构NKGLOBAL实现。这一部分的具体内容下一篇再做介绍。下图所示为 WinCE6.0 的 OAL 设计。kerne1. dllCache libraryNKGLOBALkitl iocn.Startup library=haryInterruptlibraryHardwareUSBportEthernetportSerialport在移植WinCE到新的硬件平台时,创建OAL是最复杂的任务之一。- 般来说,最简单的方法是拷贝一个跟新的硬件平台类似的且成熟的 OAL,然后根据硬件的不同进行修改,使其满足目标硬件的特定要求。这里

4、不展 开说明,回头再单独整理。从 EBOOT 到 OAL.exe 的跳转是从 OEMLaunch ()开始的,函数OEMLaunch ()中调用 Launch (dwPhysLaunchAddr),它的实现代码如下:田日CodeLEAF_ENTRY Launchldrr2, = PhysicalStartldrr3,= (VIR_RAM_START -PHY_RAM_START)subr2,r2, r3movr1,#0x0070; Disable MMUmcrp15,0, r1, c1, c0, 0nopmovpc,r2; Jump to PStartnop; MMU & caches now

5、 disabled.PhysicalStartmovr2, #0mcrp15, 0, r2, c8,c7, 0Flush theTLBmovpc, r0; Jumpto programwe are launching.函数Launch ()的参数为物理地址,因为在跳转之前已将MMU关闭。该地址可通过 VIEWBIN 来查看,如下图所示:C:WINCE600OSDesigns2410DX2410DRelDir2410D_ARMU4I_Releaseuieubin NK.bin UieuBin. NK.binImage Start = 0x80200000, length = 0X00967ED4

6、Etart address = 0x80205394Checking record #95 for potential TOC (ROMOFFSET = 0x00000000Found pTOC = 0x80b667d4ROMOFFSET = QxQQ&QQ&QQDone .如何确定这个地址对应的是NK.bin中的哪一个文件呢,先前说是 OAL.exe,证据何在。在PB6.0中增加了浏览NK.bin的功能,我们可以利 用此功能查看NK.bin的详细情况,如下图所示:从上图中可以看出0x80205394处对应的是NK.exe,而这里的NK.exe 即为 OAL.exe。至此,我们已经知道EBOO

7、T是如何跳转到OAL.exe中的了。接下来 继续看 OAL.exe 的执行过程。OAL 的启动代码如下: 田日CodeLEAF_ENTRY StartUp; Compute the OEMAddressTables physical address and ; load it into r0. KernelStart expects r0 to contain ; the physical address of this table. The MMU isnt ; turned on until well into KernelStart.add r0, pc, #g_oalAddressTa

8、ble - (. + 8) bl KernelStartOAL的启动代码和EBOOT的启动代码经常复用,但为了代码的简洁, 最好还是分开实现,而且在EBOOT中如果已经初始化了相关硬件,那么 OAL 的启动代码就可以省去那部分工作,可以很简练,如上面的代码所示可以看出,OAL的启动代码又调用了函数Kernels tar t(),而这个函 数是在文件 C:WINCE600PRIVATEWINCEOSCOREOSNKLDRARMarmstart.s 中实现 的,代码如下:田日Code LEAF_ENTRY KernelStart(r11) = &OEMAmov r11, r0ddressTable

9、 (save pointer); figure out the virtual address of OEMAddressTable mov r1, r11; (r1) = &OEMAddressTable (2nd argument to VaFromPa)blVaFromPamovr6, r0; (r6) = VA ofOEMAddressTable; convert base of PTs to Physical addressldrr4, =PTs; (r4) = virtualaddress ofFirstPTmovr0, r4; (r0)= virtualaddress ofFir

10、stPTmovr1, r11; (r1)= &OEMAddressTable (2nd argument to PaFromVa)blPaFromVamovr10, r0; (r10) = ptr to FirstPT (physical)Zero out page tables & kernel data pagemovr0, #0; (r0-r3) = 0sto storemovr1, #0movr2, #0movr3, #0movr4, r10; (r4) = firstaddressto clearaddr5, r10, #KDEnd-PTs; (r5) = last address+

11、118stmiar4!, r0-r3stmiar4!, r0-r3cmpr4, r5blo%B18; readthe architecture informationblGetCpuIdmovr5, r0 LSR #16; r5 = 16andr5, r5, #0x0000000f; r5 &= 0x0000000f = architecture id; Setup 2nd level page table to map the high memory area which contains the; first level page table, 2nd level page tables,

12、 kernel data pa ge, etc.; (r5) = architecture idaddr4, r10, #HighPT-PTs; (r4) = ptr tohigh page tablecmpr5, #ARMv6; v6 or later?; ARMV6_MMUorrge r0, r10, #PTL2_KRW + PTL2_SMALL_PAGE + ARMV6_MM U_PTL2_SMALL_XN; (r0) = PTE fo r 4K, kr/w u-/- page, uncached unbuffered, nonexecutable; PRE ARMV6_MMUorrlt

13、 r0, r10, #PTL2_KRW + (PTL2_KRW 2) + (PTL2_KR W 4) + (PTL2_KRW 6); Need to repli cate AP bits into all 4 fieldsorrlt r0, r0, #PTL2_SMALL_PAGE + PREARMV6_MMU_PTL2_S MALL_XN; (r0) = PTE fo r 4K, kr/w u-/- page, uncached unbuffered, nonexecutablestrr0,r4,#0xD0*4 ;store the entry into4 slotstomap 16K of

14、 primary page tableaddr0,r0,#0x1000 ;step on the physicaladdressstrr0,r4,#0xD1*4addr0,r0,#0x1000 ;step on the physicaladdressstrr0,r4,#0xD2*4addr0,r0,#0x1000 ;step on the physicaladdressstrr0,r4,#0xD3*4addr8,r10,#ExceptionVectors-PTs ;(r8) = ptr tovectorpageorrr0,r8,#PTL2_SMALL_PAGE ;construct thePT

15、E (C=B=0); The exception stacks and the vectors are mapped as a single kr/w page.; Any alternative will use more physical memory.; Multiple mappings dont provide any real protection: if the vectors were in a r/o page,; they could still be corrupted via the kr/w setting required for the stacks.cmpr5,

16、 #ARMv6v6 or later?; ARMV6_MMUorrge r0, r0, #PTL2_KRW; PRE ARMV6_MMUorrlt r0, r0, #PTL2_KRW + (PTL2_KRW 2) + (PTL2_KRW 4) + (PTL2_KRW 6); Need to repli cate AP bits into all 4 fields for pre-V6 MMUstore entry fother 3 entristr r0, r4, #0xF0*4 or exception stacks and vectorses now unusedaddr9,r10, #K

17、Page-PTskdata pageorrr0,r9, #PTL2_SMALL_PAGE4K (C=B=0)ARMV6_MMU (condition codes still set)(r9) = ptr to(r0)=PTE fororrge r0, r0, #PTL2_KRW_URONo subpage access control, so we must set this all to kr/w+ur/oPRE ARMV6_MMUorrlt r0, r0, #(PTL2_KRW 0) + (PTL2_KRW 2) + (P TL2_KRW_URO 4)rms kr/w kr/w kr/w+

18、ur/o r/ostr r0, r4, #0xFC*4 or kernel data pageorrr0,r4, #PTL1_2Y_TABLEvel PTE for high memory sectionaddr1,r10, #0x4000strr0,r1, #-4last slot of 1st level table(r0) = set pe store entry f(r0) = 1st lestore PTE in; Fill in first level page table entries to create stati cally mapped regions; from the

19、 contents of the OEMAddressTable array.(r5) = architecture id(r9) = ptr to KData page(r10) = ptr to 1st level page table(r11) = ptr to OEMAddressTable arrayaddr10, r10, #0x2000(r10) = ptr to 1st PTE for unmapped spacemovr0, #PTL1_SECTIONorrr0, r0, #PTL1_KRW; (r0)=PTE for0: 1MB (C=B=0,kernel r/w)20 m

20、ovr1, r11; (r1) = ptr toOEMAddressTable array (physical)25 ldrr2, r1, #4; (r2) = virtual address tomap Bank atldrr3, r1, #4; (r3) = physical address tomap fromldrr4, r1, #4; (r4) = num MBto mapcmpr4, #0; End of table?beq%F29ldrr12, =0x1FF00000andr2, r2, r12; VA needs 512MB, 1MB aligned.ldrand , 1MB

21、aligned.r12, =0xFFF00000 r3, r3, r12; PA needs 4GBaddr2, r10, r2, LSR #18addr0, r0, r3; (r0) = PTE for next physicalpage28 strr0, r2, #4addr0, r0, #0x00100000; (r0) = PTE for next physicalpagesubr4, r4, #1; Decrement number of MB leftcmpr4, #0bne%B28; Map next MBbicr0, r0, #0xF0000000; Clear Section

22、Base Address Fieldbicr0, r0, #0x0FF00000; Clear SectionBase Address Fieldent%B25Get next elem29sub r10, r10, #0x2000 re address of 1st level page table(r10) = resto; The minimal page mappings are setup. Initialize the M MU and turn it on.; there are some CPUs with pipeline issues that require s iden

23、tity mapping before turning on MMU.; Well create an identity mapping for the address wel l jump to when turning on MMU on and remove; the mapping after we turn on MMU and running on Virtu al address.ldr r12, =0xFFF00000for section bits(r12) = maskand r1, pc, r12ess of where we arephysical addrNOTE:

24、we assume that the KernelStart function never spam across 1M boundary.orrr0, r1, #PTL1_SECTIONorrr0, r0, #PTL1_KRW(r0) = PTE for 1M for current physical address, C=B=0, kernel r/wadd r7, r10, r1, LSR #18 ; (r7) = vel PT entry for the identity mapldrr8, r7; (r8) =content of the 1st-level PTstrr0, r7;

25、 createentity map1st lesavedthe idmov r1, #1mtc15 r1, c3to domain 0 and clear otherSetup accessmtc15 r10, c2tion base (physical of 1st level PT)setup translamovmcrr0, #0p15, 0, r0, c8, c7, 0Flush the I&DTLBsmfc15 r1, c1orr r1, r1, #0x007F ; changed to re ad-mod-write for ARM920 Enable: MMU, Align, D

26、Cache, WriteBuffercmpr5,#ARMv6; r5 still set; ARMV6_MMUorrger1,r1,#0x3000; vector adjust, ICacheorrger1,r1,#1dwTOCAddr;g_pOEMAddressTable = (PADDRMAP) pKData-pAddrMap;PG_V6_PROTECTION;PG_V6_PROT_READ;PG_V6_PROT_WRITE;PG_V6_PROT_URO_KRW;PG_V6_PROT_UNO_KRW;s */ else / pre-v6 pKData-dwProtMask pKData-d

27、wRead pKData-dwWrite pKData-dwKrwUro pKData-dwKrwUnoPG_V4_PROTECTION;PG_V4_PROT_READ;PG_V4_PROT_WRITE;PG_V4_PROT_URO_KRW;PG_V4_PROT_UNO_KRW;pKData-dwArchitectureId = (dwCpuId 16) & 0xf; if (pKData-dwArchitectureId = ARMArchitectureV6) / v6 or later pKData-dwProtMask pKData-dwRead pKData-dwWrite pKDa

28、ta-dwKrwUro pKData-dwKrwUno/ initialize nk globalsFirstROM.pTOC=(ROMHDR *)pTOC;FirstROM.pNext=0;ROMChain=&FirstROM;KInfoTableKINX_PTOC = (long)pTOC; KInfoTableKINX_PAGESIZE = VM_PAGE_SIZE;g_ppdirNK = (PPAGEDIRECTORY) &ArmHigh-firstPT0; pKData-pNk = g_pNKGlobal;/ (2) find entry of oal pfnInitGlob = (

29、PFN_OEMInitGlobals) pKData-dwOEMInitGlobals Addr;/ no checking here, if OAL entry point doesnt exist, we c ant continueg_pOemGlobal = pfnInitGlob (g_pNKGlobal); g_pOemGlobal-dwMainMemoryEndAddress = pTOC-ulRAMEnd; pKData-pOem = g_pOemGlobal;/ setup globalspVMProc= g_pprcNK;pActvProc= g_pprcNK;g_pNKG

30、lobal-pfnWriteDebugString = g_pOemGlobal-pfnWriteDebugString;/ (3) setup vectors, UC mappings, mode stacks, etc. ARMSetup ();/ cache is enabled from here on/ (4) common startup code./ try to load KITL if existif (pfnKitlEntry = (PFN_DllMain) g_pOemGlobal-pfnKITLGlob alInit) |(pfnKitlEntry = (PFN_Dll

31、Main) FindROMDllEntry (pTOC, KI TLDLL) (* pfnKitlEntry) (NULL, DLL_PROCESS_ATTACH, (DWORD) NKK ernelLibIoControl);#ifdef DEBUGCurMSec = dwPrevReschedTime = (DWORD) -200000; / 3 m inutes before wrap#endifOEMInitDebugSerial ();/ debugchk only works after we have something to print to. DEBUGCHK (pKData

32、 = (struct KDataStruct *) PUserKData); DEBUGCHK (pKData = &ArmHigh-kdata);OEMWriteDebugString (LPWSTR)NKSignon);/* Copy interlocked api code into the kpage */DEBUGCHK(sizeof(struct KDataStruct) = FIRST_INTERLOCK);DEBUGCHK(InterlockedEnd-InterlockedAPIs)+FIRST_INTERLOCK 4) & 0xFFF; CEProcessorLevel =

33、 4;CEProcessorRevision = (WORD) dwCpuId & 0x0f;CEInstructionSet = PROCESSOR_ARM_V4I_INSTRUCTION;RETAILMSG (1, (LProcessorType=%4.4x Revision=%drn, CEP rocessorType, CEProcessorRevision);RETAILMSG (1, (LOEMAddressTable = %8.8lxrn, g_pOEMAddre ssTable);OEMInit();/ initialize firmware/ flush I&D TLBOEM

34、CacheRangeFlush (NULL, 0, CACHE_SYNC_FLUSH_TLB);KernelFindMemory();DEBUGMSG (1, (TEXT(NKStartup done, starting up kernel.rn );KernelStart ();/ never returned DEBUGCHK (0);NKS tar tup ()的代码就不多解释了,注释已经很详细。该函数的最 后又调用了 KernelS tart ()函数。注意这里的Kernels tar t()跟上面曾提 到的Kernels tar t()是不一样的。这里Kernels tar t()的

35、实现在文件 C:WINCE600PRIVATEWINCEOSCOREOSNKKERNELARMarmtrap.s 中, 代码和反汇编的对比如下图所示。kernels tart called after ITECStartup f ini-shedLEAF ENTB.r Kerne IS tartI CXLLKerne Unitmovg pfnWriteDebugString (TEXT(Windows CE KernelIn itrn);#endifAPICallInit ();/ setup API setHeapInit ();/ setup kernel heapInitMemoryPo

36、ol ();/ setup physical memoryPROCInit ();/ initialize processVMInit (g_pprcNK);/ setup VM for kernelTHRDInit ();/ initialize threadsMapfileInit ();#ifdef DEBUGg_pNKGlobal-pfnWriteDebugString (TEXT(Scheduling the firs t thread.rn);#endif这段代码跟 WinCE5.0 中的结构基本一致,但实际上有很大的不同。 跟 WinCE6.0 启动最紧密的函数是 THRDIni

37、t (),这之前都是做相应的初 始化。THRDInit ()的实现在文件C:WINCE600PRIVATEWINCEOSCOREOSNKKERNELthread.c 中,代码如 下:田日Code/ / THRDInit - initialize thread handling (called at system star tup)/ void THRDInit (void)LPBYTE pStack;DEBUGLOG (1, g_pprcNK);/ dont allow thread create one memory drop below 1% avail ableif (g_cMinPag

38、eThrdCreate pfnMapW32Priority) BYTE prioMapMAX_WIN32_PRIORITY_LEVELS;int i;memcpy (prioMap, W32PrioMap, sizeof (prioMap); g_pOemGlobal-pfnMapW32Priority (MAX_WIN32_PRIORITY_LEV ELS, prioMap);/ validate the the priority is mono-increasefor (i = 0; i = prioMapi+1)break;DEBUGMSG (MAX_WIN32_PRIORITY_LEV

39、ELS-1) != i, (LProcIn it: Invalid priority map provided by OEM, Ignored!rn);if (MAX_WIN32_PRIORITY_LEVELS-1) = i) memcpy (W32PrioMap, prioMap, sizeof (prioMap);/ allocate memory for the 1st thread pCurThread = AllocMem (HEAP_THREAD); DEBUGCHK (pCurThread);dwCurThId = (DWORD) HNDLCreateHandle (&cinfT

40、hread, pCurThre ad, g_pprcNK) & 1;DEBUGCHK (dwCurThId);InitThreadStruct (pCurThread, (HANDLE) dwCurThId, g_pprcNK, THREAD_RT_PRIORITY_ABOVE_NORMAL);if (g_pOemGlobal-cbCoProcRegSize) DEBUGCHK (g_pOemGlobal-pfnInitCoProcRegs);DEBUGCHK (g_pOemGlobal-pfnSaveCoProcRegs);DEBUGCHK (g_pOemGlobal-pfnRestoreC

41、oProcRegs);/ check the debug register related values.if (g_pOemGlobal-cbCoProcRegSize MAX_COPROCREGSIZE) g_pOemGlobal-cbCoProcRegSize = g_pOemGlobal-fSave CoProcReg = 0; else PNAME pTmp = AllocName (g_pOemGlobal-cbCoProcRegSi ze);DEBUGCHK (pTmp); g_dwCoProcPool = pTmp-wPool;FreeName (pTmp); else g_p

42、OemGlobal-fSaveCoProcReg = FALSE;DEBUGMSG (ZONE_SCHEDULE,(TEXT(cbCoProcRegSize = %drn), g_pOemGlobal-cbCoProcRegSize);AddToDListHead (&g_pprcNK-thrdList, &pCurThread-thLink); g_pprcNK-wThrdCnt +;#ifdef SHx SetCPUGlobals();OEMCacheRangeFlush (0, 0, CACHE_SYNC_ALL); #endifif (!OpenExecutable (NULL, TE

43、XT(NK.EXE), &g_pprcNK-oe, T OKEN_SYSTEM, NULL, 0) LoadE32 (&g_pprcNK-oe, &g_pprcNK-e32, 0, 0, 0); g_pprcNK-BasePtr = (LPVOID)g_pprcNK-e32.e32_vbase; UpdateKmodVSize(&g_pprcNK-oe, &g_pprcNK-e32);/ create/setup stack pStack = VMCreateStack (g_pprcNK, KRN_STACK_SIZE); pCurThread-dwOrigBase = (DWORD) pS

44、tack; pCurThread-dwOrigStkSize = KRN_STACK_SIZE;pCurThread-tlsSecure = pCurThread-tlsNonSecure = pCurThre ad-tlsPtr = TLSPTR (pStack, KRN_STACK_SIZE);pCurThread-hTok = TOKEN_SYSTEM;/ Save off the threads program counter for getting its na me later.pCurThread-dwStartAddr = (DWORD) SystemStartupFunc;M

45、DSetupThread (pCurThread, (LPVOID)SystemStartupFunc, 0, TH _KMODE, 0);CELOG_ThreadCreate(pCurThread, g_pprcNK, NULL);MakeRun(pCurThread); DEBUGMSG(ZONE_SCHEDULE,(TEXT(Scheduler: Created master thr ead %8.8lxrn),pCurThread);可以看到,这里开始了一个线程,线程处理函数为SystemStartupFunc(),其实现在文件 C:WINCE600PRIVATEWINCE0SC0RE

46、0SNKKERNELschedule.c,实现代 码如下:田日Code/ voidSystemStartupFunc(ulong param)HANDLE hTh;/ record PendEvent address for SetInterruptEvent KInfoTableKINX_PENDEVENTS = (DWORD) &PendEvents1;KernelInit2();/ adjust alarm resolution if it its not in boundif (g_pOemGlobal-dwAlarmResolution dwAlarmResolution = MIN_NKALARMRESOLUTION _

展开阅读全文
温馨提示:
1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
2: 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
3.本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
关于我们 - 网站声明 - 网站地图 - 资源地图 - 友情链接 - 网站客服 - 联系我们

copyright@ 2023-2025  zhuangpeitu.com 装配图网版权所有   联系电话:18123376007

备案号:ICP2024067431-1 川公网安备51140202000466号


本站为文档C2C交易模式,即用户上传的文档直接被用户下载,本站只是中间服务平台,本站所有文档下载所得的收益归上传人(含作者)所有。装配图网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。若文档所含内容侵犯了您的版权或隐私,请立即通知装配图网,我们立即给予删除!