微波EDA网,见证研发工程师的成长!
首页 > 硬件设计 > 嵌入式设计 > S3C2410下WinCE6.0的启动过程详解

S3C2410下WinCE6.0的启动过程详解

时间:11-20 来源:互联网 点击:

从上面的代码可以看出,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);
}

Copyright © 2017-2020 微波EDA网 版权所有

网站地图

Top