Code
//
// NKStartup - entry point of kernel.dll.
//
// NK Loader setup only the minimal mappings, which includes ARMHigh area, and the cached static mapping area,
// with *EVERYTHING UNCACHED*. Interrupt vectors are not setup either. So, the init sequence reqiures:
// (1) pickup data passed from nk loader
// (2) Find entry point of oal, exchange globals, find out the cache mode.
// (3) fill in the rest of static mapped area (0xa0000000 - 0xbfffffff), PSL faulting address, interrupt vectors,
// mod stacks, etc. Then, change the 'cached' static mapping area to use cache, and flush I&D TLB.
// (4) continue normal loading of kernel (find KITLdll, call OEMInitDebugSerial, etc.)
//
void NKStartup (struct KDataStruct * pKData)
{
PFN_OEMInitGlobals pfnInitGlob;
PFN_DllMain pfnKitlEntry;
DWORD dwCpuId = GetCpuId ();
// (1) pickup arguments from the nk loader
g_pKData = pKData;
pTOC = (const ROMHDR *) pKData->dwTOCAddr;
g_pOEMAddressTable = (PADDRMAP) pKData->pAddrMap;
/* get architecture id and update page protection attributes */
pKData->dwArchitectureId = (dwCpuId >> 16) & 0xf;
if (pKData->dwArchitectureId >= ARMArchitectureV6) {
// v6 or later
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;
}
// initialize nk globals
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) find entry of oal
pfnInitGlob = (PFN_OEMInitGlobals) pKData->dwOEMInitGlobalsAddr;
// no checking here, if OAL entry point doesn't exist, we can't continue
g_pOemGlobal = pfnInitGlob (g_pNKGlobal);
g_pOemGlobal->dwMainMemoryEndAddress = pTOC->ulRAMEnd;
pKData->pOem = g_pOemGlobal;
// setup globals
pVMProc = g_pprcNK;
pActvProc = g_pprcNK;
g_pNKGlobal->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 exist
if ((pfnKitlEntry = (PFN_DllMain) g_pOemGlobal->pfnKITLGlobalInit) ||
(pfnKitlEntry = (PFN_DllMain) FindROMDllEntry (pTOC, KITLDLL))) {
(* pfnKitlEntry) (NULL, DLL_PROCESS_ATTACH, (DWORD) NKKernelLibIoControl);
}
#ifdef DEBUG
CurMSec = dwPrevReschedTime = (DWORD) -200000; // ~3 minutes before wrap
#endif
OEMInitDebugSerial ();
// debugchk only works after we have something to print to.
DEBUGCHK (pKData == (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 <= 0x400);
memcpy((char *)g_pKData+FIRST_INTERLOCK, InterlockedAPIs, InterlockedEnd-InterlockedAPIs);
/* setup processor version information */
CEProcessorType = (dwCpuId >> 4) & 0xFFF;
CEProcessorLevel = 4;
CEProcessorRevision = (WORD) dwCpuId & 0x0f;
CEInstructionSet = PROCESSOR_ARM_V4I_INSTRUCTION;
RETAILMSG (1, (L"ProcessorType=%4.4x Revision=%d\r\n", CEProcessorType, CEProcessorRevision));
RETAILMSG (1, (L"OEMAddressTable = %8.8lx\r\n", g_pOEMAddressTable));
OEMInit(); // initialize firmware
// flush I&D TLB
OEMCacheRangeFlush (NULL, 0, CACHE_SYNC_FLUSH_TLB);
KernelFindMemory();
DEBUGMSG (1, (TEXT("NKStartup done, starting up kernel.\r\n")));
KernelStart ();
// never returned
DEBUGCHK (0);
}
S3C2410下WinCE6.0的启动过程详解(3)
内容版权声明:除非注明,否则皆为本站原创文章。
转载注明出处:https://www.heiqu.com/392d14ee7c46bd4a232f80e3976d6e8b.html