S3C2410下WinCE6.0的启动过程详解
从上面的代码可以看出,KernelStart()通过OEMAddressTable初始化了MMU,然后通过调用函数ARMInit()获得kernel.dll的入口点,最后跳转到kernel.dll的入口点处。
为了找到Kernel.dll的入口点,用IDA反汇编kernel.dll文件,可以看到,Kernel.dll的入口点为NKStartup。
NKStartup()的实现在文件C:\WINCE600\PRIVATE\WINCEOS\COREOS\NK\KERNEL\ARM\ mdarm.c中,代码如下:
Code
//
//NKStartup-entrypointofkernel.dll.
//
//NKLoadersetuponlytheminimalmappings,whichincludesARMHigharea,andthecachedstaticmappingarea,
//with*EVERYTHINGUNCACHED*.Interruptvectorsarenotsetupeither.So,theinitsequencereqiures:
//(1)pickupdatapassedfromnkloader
//(2)Findentrypointofoal,exchangeglobals,findoutthecachemode.
//(3)fillintherestofstaticmappedarea(0xa0000000-0xbfffffff),PSLfaultingaddress,interruptvectors,
//modstacks,etc.Then,changethecachedstaticmappingareatousecache,andflushI&DTLB.
//(4)continuenormalloadingofkernel(findKITLdll,callOEMInitDebugSerial,etc.)
//
voidNKStartup(structKDataStruct*pKData)
{
PFN_OEMInitGlobalspfnInitGlob;
PFN_DllMainpfnKitlEntry;
DWORDdwCpuId=GetCpuId();
//(1)pickupargumentsfromthenkloader
g_pKData=pKData;
pTOC=(constROMHDR*)pKData->dwTOCAddr;
g_pOEMAddressTable=(PADDRMAP)pKData->pAddrMap;
/*getarchitectureidandupdatepageprotectionattributes*/
pKData->dwArchitectureId=(dwCpuId>>16)&0xf;
if(pKData->dwArchitectureId>=ARMArchitectureV6){
//v6orlater
pKData->dwProtMask=PG_V6_PROTECTION;
pKData->dwRead=PG_V6_PROT_READ;
pKData->dwWrite=PG_V6_PROT_WRITE;
pKData->dwKrwUro=PG_V6_PROT_URO_KRW;
pKData->dwKrwUno=PG_V6_PROT_UNO_KRW;
}else{
//pre-v6
pKData->dwProtMask=PG_V4_PROTECTION;
pKData->dwRead=PG_V4_PROT_READ;
pKData->dwWrite=PG_V4_PROT_WRITE;
pKData->dwKrwUro=PG_V4_PROT_URO_KRW;
pKData->dwKrwUno=PG_V4_PROT_UNO_KRW;
}
//initializenkglobals
FirstROM.pTOC=(ROMHDR*)pTOC;
FirstROM.pNext=0;
ROMChain=&FirstROM;
KInfoTable[KINX_PTOC]=(long)pTOC;
KInfoTable[KINX_PAGESIZE]=VM_PAGE_SIZE;
g_ppdirNK=(PPAGEDIRECTORY)&ArmHigh->firstPT[0];
pKData->pNk=g_pNKGlobal;
//(2)findentryofoal
pfnInitGlob=(PFN_OEMInitGlobals)pKData->dwOEMInitGlobalsAddr;
//nocheckinghere,ifOALentrypointdoesntexist,wecantcontinue
g_pOemGlobal=pfnInitGlob(g_pNKGlobal);
g_pOemGlobal->dwMainMemoryEndAddress=pTOC->ulRAMEnd;
pKData->pOem=g_pOemGlobal;
//setupglobals
pVMProc=g_pprcNK;
pActvProc=g_pprcNK;
g_pNKGlobal->pfnWriteDebugString=g_pOemGlobal->pfnWriteDebugString;
//(3)setupvectors,UCmappings,modestacks,etc.
ARMSetup();
//
//cacheisenabledfromhereon
//
//(4)commonstartupcode.
//trytoloadKITLifexist
if((pfnKitlEntry=(PFN_DllMain)g_pOemGlobal->pfnKITLGlobalInit)||
(pfnKitlEntry=(PFN_DllMain)FindROMDllEntry(pTOC,KITLDLL))){
(*pfnKitlEntry)(NULL,DLL_PROCESS_ATTACH,(DWORD)NKKernelLibIoControl);
}
#ifdefDEBUG
CurMSec=dwPrevReschedTime=(DWORD)-200000;//~3minutesbeforewrap
#endif
OEMInitDebugSerial();
//debugchkonlyworksafterwehavesomethingtoprintto.
DEBUGCHK(pKData==(structKDataStruct*)PUserKData);
DEBUGCHK(pKData==&ArmHigh->kdata);
OEMWriteDebugString((LPWSTR)NKSignon);
/*Copyinterlockedapicodeintothekpage*/
DEBUGCHK(sizeof(structKDataStruct)<=FIRST_INTERLOCK);
DEBUGCHK((InterlockedEnd-InterlockedAPIs)+FIRST_INTERLOCK<=0x400);
memcpy((char*)g_pKData+FIRST_INTERLOCK,InterlockedAPIs,InterlockedEnd-InterlockedAPIs);
/*setupprocessorversioninformation*/
CEProcessorType=(dwCpuId>>4)&0xFFF;
CEProcessorLevel=4;
CEProcessorRevision=(WORD)dwCpuId&0x0f;
CEInstructionSet=PROCESSOR_ARM_V4I_INSTRUCTION;
RETAILMSG(1,(L"ProcessorType=%4.4xRevision=%d\r\n",CEProcessorType,CEProcessorRevision));
RETAILMSG(1,(L"OEMAddressTable=%8.8lx\r\n",g_pOEMAddressTable));
OEMInit();//initializefirmware
//flushI&DTLB
OEMCacheRangeFlush(NULL,0,CACHE_SYNC_FLUSH_TLB);
KernelFindMemory();
DEBUGMSG(1,(TEXT("NKStartupdone,startingupkernel.\r\n")));
KernelStart();
//neverreturned
DEBUGCHK(0);
}
S3C2410WinCE6 0启动过 相关文章:
- Windows CE 进程、线程和内存管理(11-09)
- RedHatLinux新手入门教程(5)(11-12)
- uClinux介绍(11-09)
- openwebmailV1.60安装教学(11-12)
- Linux嵌入式系统开发平台选型探讨(11-09)
- Windows CE 进程、线程和内存管理(二)(11-09)