📄 loader.c
字号:
}
if (cptr->ulCopyLen != cptr->ulDestLen) {
memset((LPVOID)(cptr->ulDest+cptr->ulCopyLen),0,cptr->ulDestLen-cptr->ulCopyLen);
}
}
// Now you can read global variables...
PtrKData = &KData; // Set this to allow displaying the kpage from the KD.
MainMemoryEndAddress = pTOC->ulRAMEnd;
FirstROM.pTOC = pTOC;
FirstROM.pNext = 0;
ROMChain = &FirstROM;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
SC_NotifyForceCleanboot(void)
{
TRUSTED_API_VOID (L"SC_NotifyForceCleanboot");
if (pNotifyForceCleanboot)
pNotifyForceCleanboot(0, 0, 0, 0);
}
// should match same define in filesys\heap\heap.c
#define MAX_FILESYSTEM_HEAP_SIZE 256*1024*1024
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
DWORD
CalcFSPages(
DWORD pages
)
{
DWORD fspages;
if (pages <= 2*1024*1024/PAGE_SIZE) {
fspages = (pages*(pTOC->ulFSRamPercent&0xff))/256;
} else {
fspages = ((2*1024*1024/PAGE_SIZE)*(pTOC->ulFSRamPercent&0xff))/256;
if (pages <= 4*1024*1024/PAGE_SIZE) {
fspages += ((pages-2*1024*1024/PAGE_SIZE)*((pTOC->ulFSRamPercent>>8)&0xff))/256;
} else {
fspages += ((2*1024*1024/PAGE_SIZE)*((pTOC->ulFSRamPercent>>8)&0xff))/256;
if (pages <= 6*1024*1024/PAGE_SIZE) {
fspages += ((pages-4*1024*1024/PAGE_SIZE)*((pTOC->ulFSRamPercent>>16)&0xff))/256;
} else {
fspages += ((2*1024*1024/PAGE_SIZE)*((pTOC->ulFSRamPercent>>16)&0xff))/256;
fspages += ((pages-6*1024*1024/PAGE_SIZE)*((pTOC->ulFSRamPercent>>24)&0xff))/256;
}
}
}
return fspages;
}
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
DWORD
CarveMem(
LPBYTE pMem,
DWORD dwExt,
DWORD dwLen,
DWORD dwFSPages
)
{
DWORD dwPages, dwNow, loop;
LPBYTE pCur, pPage;
dwPages = dwLen / PAGE_SIZE;
pCur = pMem + dwExt;
while (dwPages && dwFSPages) {
pPage = pCur;
pCur += PAGE_SIZE;
dwPages--;
dwFSPages--;
*(LPBYTE *)pPage = LogPtr->pFSList;
LogPtr->pFSList = pPage;
dwNow = dwPages;
if (dwNow > dwFSPages)
dwNow = dwFSPages;
if (dwNow > (PAGE_SIZE/4) - 2)
dwNow = (PAGE_SIZE/4) - 2;
*((LPDWORD)pPage+1) = dwNow;
for (loop = 0; loop < dwNow; loop++) {
*((LPDWORD)pPage+2+loop) = (DWORD)pCur;
pCur += PAGE_SIZE;
}
dwPages -= dwNow;
dwFSPages -= dwNow;
}
return dwFSPages;
}
void RemovePage(DWORD dwAddr);
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
void
GrabFSPages(void)
{
LPBYTE pPageList;
DWORD loop,max;
pPageList = LogPtr->pFSList;
while (pPageList) {
max = *((LPDWORD)pPageList+1);
RemovePage((DWORD)pPageList);
for (loop = 0; loop < max; loop++)
RemovePage(*((LPDWORD)pPageList+2+loop));
pPageList = *(LPBYTE *)pPageList;
}
}
//------------------------------------------------------------------------------
//
// Divide the declared physical RAM between Object Store and User RAM.
//
//------------------------------------------------------------------------------
#pragma prefast(disable: 11, "if pListPrev is NULL, we can't find pTOC and won't boot anyway")
void
KernelFindMemory(void)
{
ROMChain_t *pList, *pListPrev = NULL;
extern const wchar_t NKCpuType [];
extern void InitDrWatson (void);
MEMORY_SECTION MemSections[MAX_MEMORY_SECTIONS];
DWORD cSections;
DWORD dwRAMStart, dwRAMEnd;
DWORD i;
for (pList = OEMRomChain; pList; pList = pList->pNext) {
if (pList->pTOC == pTOC) {
// main region is already in the OEMROMChain, just use it
ROMChain = OEMRomChain;
break;
}
pListPrev = pList;
}
if (OEMRomChain && !pList) {
DEBUGCHK (pListPrev);
pListPrev->pNext = ROMChain;
ROMChain = OEMRomChain;
}
if (!MDValidateRomChain (ROMChain)) {
NKDbgPrintfW (L"ERROR! XIP region span accross discontigious memory!!! System Halted!\r\n");
#if 0
while (1)
;
#endif
}
// initialize Pageing Pool (MUST OCCUR BEFORE GETTING LogPtr since it'll change MemForPT)
InitPgPool ();
// initialize Kernel Dr.Watson support
InitDrWatson ();
// *MUST* make the pointer uncached ( thus or in 0x20000000)
//
// LogPtr at the start of RAM holds some header information
//
LogPtr = (fslog_t *)PAGEALIGN_UP ((pTOC->ulRAMFree+MemForPT)| 0x20000000);
RETAILMSG(1,(L"Booting Windows CE version %d.%2.2d for (%s)\r\n",CE_MAJOR_VER,CE_MINOR_VER, NKCpuType));
#ifdef MIPS
if (IsMIPS16Supported)
RETAILMSG (1, (L"MIPS16 Instructions Supported\r\n"));
else
RETAILMSG (1, (L"MIPS16 Instructions NOT Supported\r\n"));
#endif
DEBUGMSG(1,(L"&pTOC = %8.8lx, pTOC = %8.8lx, pTOC->ulRamFree = %8.8lx, MemForPT = %8.8lx\r\n", &pTOC, pTOC, pTOC->ulRAMFree, MemForPT));
if (LogPtr->version != CURRENT_FSLOG_VERSION) {
RETAILMSG(1,(L"\r\nOld or invalid version stamp in kernel structures - starting clean!\r\n"));
LogPtr->magic1 = LogPtr->magic2 = 0;
LogPtr->version = CURRENT_FSLOG_VERSION;
}
if (fForceCleanBoot || (LogPtr->magic1 != LOG_MAGIC)) {
DWORD fspages, mainpages, secondpages, cExtSections;
//
// Ask OEM if extension RAM exists.
//
if (pNKEnumExtensionDRAM) {
cExtSections = (*pNKEnumExtensionDRAM)(MemSections, MAX_MEMORY_SECTIONS - 1);
DEBUGCHK(cExtSections < MAX_MEMORY_SECTIONS);
} else if (OEMGetExtensionDRAM(&MemSections[0].dwStart, &MemSections[0].dwLen)) {
cExtSections = 1;
} else {
cExtSections = 0;
}
dwRAMStart = pTOC->ulRAMStart;
dwRAMEnd = MainMemoryEndAddress;
mainpages = (PAGEALIGN_DOWN(MainMemoryEndAddress) - PAGEALIGN_UP(pTOC->ulRAMFree+MemForPT))/PAGE_SIZE - 4096/PAGE_SIZE;
//
// Setup base RAM area
//
LogPtr->fsmemblk[0].startptr = PAGEALIGN_UP(pTOC->ulRAMFree+MemForPT) + 4096;
LogPtr->fsmemblk[0].extension = PAGEALIGN_UP(mainpages);
mainpages -= LogPtr->fsmemblk[0].extension/PAGE_SIZE;
LogPtr->fsmemblk[0].length = mainpages * PAGE_SIZE;
cSections = 1;
//
// Setup extension RAM sections
//
secondpages = 0;
for (i = 0; i< cExtSections; i++) {
if (MemSections[i].dwLen < (PAGEALIGN_UP(MemSections[i].dwStart) - MemSections[i].dwStart)) {
MemSections[i].dwStart = MemSections[i].dwLen = 0;
} else {
MemSections[i].dwLen -= (PAGEALIGN_UP(MemSections[i].dwStart) - MemSections[i].dwStart);
MemSections[i].dwStart = PAGEALIGN_UP(MemSections[i].dwStart);
MemSections[i].dwLen = PAGEALIGN_DOWN(MemSections[i].dwLen);
if (dwRAMStart > MemSections[i].dwStart)
dwRAMStart = MemSections[i].dwStart;
if (dwRAMEnd < (MemSections[i].dwStart + MemSections[i].dwLen))
dwRAMEnd = MemSections[i].dwStart + MemSections[i].dwLen;
LogPtr->fsmemblk[cSections].startptr = MemSections[i].dwStart;
LogPtr->fsmemblk[cSections].extension = PAGEALIGN_UP(MemSections[i].dwLen / PAGE_SIZE);
LogPtr->fsmemblk[cSections].length = MemSections[i].dwLen - LogPtr->fsmemblk[cSections].extension;
secondpages += LogPtr->fsmemblk[cSections].length / PAGE_SIZE;
cSections++;
}
}
memset(&LogPtr->fsmemblk[cSections], 0, sizeof(mem_t) * (MAX_MEMORY_SECTIONS-cSections));
fspages = CalcFSPages(mainpages+secondpages);
// ask OAL to change fs pages if required
if (pOEMCalcFSPages)
fspages = (*pOEMCalcFSPages)(mainpages+secondpages, fspages);
if (fspages * PAGE_SIZE > MAX_FILESYSTEM_HEAP_SIZE) {
fspages = MAX_FILESYSTEM_HEAP_SIZE/PAGE_SIZE;
}
RETAILMSG(1,(L"Configuring: Primary pages: %d, Secondary pages: %d, Filesystem pages = %d\r\n",
mainpages,secondpages,fspages));
//
// Now split the base and extension RAM sections into Object Store and
// User RAM.
//
LogPtr->pFSList = 0;
for (i = 0; i <cSections; i++) {
fspages = CarveMem((LPBYTE)LogPtr->fsmemblk[i].startptr,LogPtr->fsmemblk[i].extension,LogPtr->fsmemblk[i].length,fspages);
}
OEMCacheRangeFlush (0, 0, CACHE_SYNC_WRITEBACK);
//
// Mark the header as initialized.
//
LogPtr->magic1 = LOG_MAGIC;
LogPtr->magic2 = 0;
RETAILMSG(1,(L"\r\nBooting kernel with clean memory configuration:\r\n"));
} else {
//
// The magic number was found. Use the memory configuration already
// set up at LogPtr.
//
RETAILMSG(1,(L"\r\nBooting kernel with existing memory configuration:\r\n"));
dwRAMStart = pTOC->ulRAMStart;
dwRAMEnd = MainMemoryEndAddress;
cSections = 0;
for (i = 0; i < MAX_MEMORY_SECTIONS; i++) {
if (LogPtr->fsmemblk[i].length) {
cSections++;
if (dwRAMStart > LogPtr->fsmemblk[i].startptr)
dwRAMStart = LogPtr->fsmemblk[i].startptr;
if (dwRAMEnd <(LogPtr->fsmemblk[i].startptr + LogPtr->fsmemblk[i].extension + LogPtr->fsmemblk[i].length))
dwRAMEnd = LogPtr->fsmemblk[i].startptr + LogPtr->fsmemblk[i].extension + LogPtr->fsmemblk[i].length;
}
}
}
RETAILMSG(1, (L"Memory Sections:\r\n"));
for (i = 0; i <cSections; i++) {
RETAILMSG(1,(L"[%d] : start: %8.8lx, extension: %8.8lx, length: %8.8lx\r\n",
i, LogPtr->fsmemblk[i].startptr,LogPtr->fsmemblk[i].extension,LogPtr->fsmemblk[i].length));
}
LogPtr->pKList = 0;
MemoryInfo.pKData = (LPVOID)dwRAMStart;
MemoryInfo.pKEnd = (LPVOID)dwRAMEnd;
MemoryInfo.cFi = cSections;
MemoryInfo.pFi = &FreeInfo[0];
for (i = 0; i < cSections; i++) {
FreeInfo[i].pUseMap = (LPBYTE)LogPtr->fsmemblk[i].startptr;
memset((LPVOID)LogPtr->fsmemblk[i].startptr, 0, LogPtr->fsmemblk[i].extension);
FreeInfo[i].paStart = GetPFN(LogPtr->fsmemblk[i].startptr+LogPtr->fsmemblk[i].extension - PAGE_SIZE) + PFN_INCR;
FreeInfo[i].paEnd = FreeInfo[i].paStart + PFN_INCR * (LogPtr->fsmemblk[i].length / PAGE_SIZE);
FreeInfo[i].paRealEnd = FreeInfo[i].paEnd;
}
memset(&FreeInfo[cSections], 0, sizeof(FREEINFO) * (MAX_MEMORY_SECTIONS-cSections));
GrabFSPages();
KInfoTable[KINX_GWESHEAPINFO] = 0;
KInfoTable[KINX_TIMEZONEBIAS] = 0;
}
#pragma prefast(pop)
//------------------------------------------------------------------------------
// Relocate a page
//------------------------------------------------------------------------------
BOOL
RelocatePage(
e32_lite *eptr,
o32_lite *optr,
ulong BasePtr,
ulong BaseAdj,
DWORD pMem,
DWORD pData,
DWORD prevdw
)
{
DWORD Comp1 = 0, Comp2;
#if defined(MIPS)
DWORD PrevPage;
#endif
struct info *blockptr, *blockstart;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -