Share via


Kernel Memory Allocated for Use by the Networking Stack (Windows CE 5.0)

Send Feedback

Translation look-aside buffer (TLB) misses can improve or degrade performance in some situations. In Windows CE, you can allocate memory for the networking stack out of the kernel memory region, which includes addresses above 0x80000000. This address region is mapped as two large TLBs. Code running from this region, and data addressed from it, generates no TLB miss penalties.

The following table shows how the addresses above 0x80000000 are partitioned.

Addresses Mapped to
0x80000000 - 0xa0000000 Contiguous cached physical memory.
0xa0000000 - 0xc0000000 Uncached physical memory.

In order for the OS to include DLLs in high-memory, information on the DLL files must be stored in the FILES section in the Common.bib file for your OS design. Examples of DLLs that can be loaded into the high-memory region for high-performance networking and routing scenarios include Tcpstk, Cxport, Ndis, Mbridge, Ipnat, Fw6, network miniport drivers, and wireless network miniport drivers.

Note   To load DLLs into the high-memory region to reduce TLB misses, ensure that the IMGNOTALLKMODE environment variable is cleared in the run-time image.

Since the FILES section typically follows the MODULES section in a BIB file, you can manage this change without modifying the Common.bib file for your OS design by running a script that moves the networking components to the FILES section. The following code example shows a script that moves the networking components to the FILES section of the Common.bib file for your OS design.

@echo off
IF not "%IMGLOADNETHIGH%"=="1" goto :endfile
echo Moving net components to the file regions

pushd %_FLATRELEASEDIR%

findstr "mbridge.dll ipnat.dll fw6.dll tcpstk.dll cxport.dll ndis.dll" ce.bib > ce_net.bib
findstr /v "mbridge.dll ipnat.dll fw6.dll tcpstk.dll cxport.dll ndis.dll" ec.bib > ce_nonet.bib
copy /A ce_nonet.bib+ce_net.bib ce.bib

popd

:endfile

You can also move the networking components to the FILES section by configuring the Preromimage.bt file. For more information, see Configuring a Premakeimg.bat File.

**Note   **The heap created in this high-memory region is not tracked with LMEMDEBUG. Also, the heap in this region is committed in 192 KB blocks, as opposed to the page granularity of a standard heap, and is not subject to per-page decommit on compacting. As such, it is considerably less memory-efficient than the standard heap.

To enable the networking stack to allocate memory from this kernel memory region, you must change the HKEY_LOCAL_MACHINE\Comm\Cxport registry key. The following registry example shows the value to set:

[HKEY_LOCAL_MACHINE\Comm\Cxport]
    "PhysHeap"=dword:1

To force loading DLLs into high-memory region, you must modify OEMInit in the hardward abstraction layer (HAL) code. You must set the *pfnOEMIsKernelSpaceDll variable early in OEMInit to point to a function that will be called by the loader every time a DLL is about to load. That function is then passed a pointer to the DLL's name. Return TRUE if the DLL needs to be loaded into high memory space.

The uncaught exception in the high-memory region is treated as a kernel exception and causes the entire system to halt. Debug your run-time image fully before putting DLLs into high memory region.

The following code example shows how to load DLLs into high memory region:

#if defined (IMGLOADNETHIGH)
 
static LPCWSTR pszSpecialDlls[] = {
    L"tcpstk",
    L"cxport",
    L"ndis",
    L"mbridge",
    L"ipnat",
    L"fw6",
    L"myminiportdriver",
    L"mywirelessminiportdriver"
};
 
static WCHAR lowerW(WCHAR ch) {
    return ((ch >= 'A') && (ch <= 'Z')) ? (ch - 'A' + 'a') : ch;
}
 
static int strcmponeiW(const wchar_t *pwc1, const wchar_t *pwc2) {
    while (*pwc1 && (lowerW(*pwc1) == *pwc2)) {
        pwc1++;
        pwc2++;
    }
    return (*pwc1 ? 1 : 0);
}
 
static int strcmpdllnameW(LPCWSTR src, LPCWSTR tgt) {
    while (*src && (*src == lowerW(*tgt))) {
        src++;
        tgt++;
    }
    return ((*tgt && strcmponeiW(tgt,L".dll") && strcmponeiW(tgt,L".cpl")) || (*src && memcmp(src,L".dll",10) && memcmp(src,L".cpl",10))) ? 1 : 0;
}
 
static BOOL CheckDlls (LPCWSTR pszDllName) {
    int i;
 
    for (i = 0; i < sizeof(pszSpecialDlls)/sizeof(pszSpecialDlls[0]); i ++) {
        if (!strcmpdllnameW (pszSpecialDlls[i], pszDllName)) {
            RETAILMSG (1, (L"CheckDll: %s returns TRUE\r\n", pszDllName));
            return TRUE;
        }
    }
    return FALSE;
}
 
extern BOOL (* pfnOEMIsKernelSpaceDll) (LPCWSTR pszDllName);
 
#endif
  
void OEMInit(void)
{
...
#if defined (IMGLOADNETHIGH)
   pfnOEMIsKernelSpaceDll = CheckDlls;
#endif

See Also

Improving Performance of an NDIS Miniport Driver

Send Feedback on this topic to the authors

Feedback FAQs

© 2006 Microsoft Corporation. All rights reserved.