Multiple XIP Regions (Windows CE 5.0)

Send Feedback

Execute-in-place (XIP) regions are areas where an application can execute code directly from read-only memory (ROM) rather than having to load it from RAM.

You can construct multiple XIP regions in a single system. With this capability, you can use XIP capabilities while using more than one memory area. For example, you could install the core OS features into ROM, and install the other OS features into flash memory. XIP applications could run in both places. You can still upgrade the flash region as needed; however, the XIP region of memory must be read-only.

You can chain together as many ROM regions as you want. Each time you add a ROM region, the kernel may replace another ROM region. The kernel does not physically replace the module; it replaces its functionality with a new module in a separate ROM region. The order you define for your ROM regions determines the order in which the OS overwrites modules. The ROM region that contains Nk.exe is at the bottom of the list; the kernel adds new regions to the top of the list. This enables you to replace all modules in the original image, except Nk.exe, by linking to another ROM region.

To add a ROM region to an existing run-time image, create a new .bib file that lists the modules that you want to add or replace in an existing OS design. To add a new .exe file or replace an existing one, add the .exe file to the .bib file.

You need to make an additional entry in the .bib file when you add or modify a DLL. In Windows CE, all DLLs load from the top down in a 32-MB virtual memory process space. Because Windows CE loads all DLLs for a specified .exe file in the same address location, the MODULES section of the .bin file reserves the same amount of virtual memory space for all DLLs. For any specified process, the system either loads the same DLLs to the process' address space or reserves space to load it later. When you use Makeimg.exe to build a ROM image, it generates the starting and ending addresses of all DLLs in the image. The following code example shows a sample DLL address generated by Makeimg.exe.

First DLL Address:        01f90000h
Last DLL Address:         02000000h

You need to include an entry in the CONFIG section of the new .bib file, under the DLLHIGHADDR declaration, that specifies the start address for all DLLs in the associated ROM image. This start address is the lowest address allocated for DLL virtual memory space in the original .bin file. In the new .bin file, Makeimg.exe lists the starting address where the system can begin reserving and loading virtual memory. The system reserves memory from the starting address on down. The following code example shows a sample DLL start address generated by the new .bin file.

DLLHIGHADDR=0x01f90000 

Be sure that your XIP regions do not overlap. If they do, the system will not run correctly. You can leave gaps between DLL regions without causing system problems, but this will decrease the amount of virtual memory available to a process. Because the kernel reserves the same amount of virtual memory space for all ROMs and loaded DLLs, the kernel never uses memory in a gap between the DLLs. Alternatively, you can use the gap to expand a ROM image's DLLs without having to rearrange any ROM images that follow. For example, if your main ROM's DLLs ended at 0x01f00000, you could start your next ROM's DLLs at 0x01f00000. If your second ROM's DLL ended at 0x01e00000, you might begin your third ROM's DLLs at 0x01d00000, which would allow the second ROM to grow without affecting the third ROM.

If you use multiple ROM regions, you must use the OEMInit function and the OEMRomChain variable to report this to the kernel. The following code example shows the declaration of this variable.

extern ROMChain_t *OEMRomChain;

This variable contains a chain of ROM pTOC pointers, which point to a table of contents. The kernel is stored in the ROM located at offset ROM_SIGNATURE_OFFSET+4 with a DWORD signature ROM_SIGNATURE stored at ROM_SIGNATURE_OFFSET. The following code examples show the code to add to designate a second ROM region located at 0x80400000.

static ROMChain_t SecondROM;
extern ROMChain_t *OEMRomChain;
if (*(LPDWORD)(0x80400000+ROM_SIGNATURE_OFFSET) == ROM_SIGNATURE) {
   // get the pTOC pointer from the rom at 0x80400000
   SecondROM.pTOC = *(ROMHDR **) (0x80400000+ROM_SIGNATURE_OFFSET+4); 
   SecondROM.pNext = 0;
   OEMRomChain = &SecondROM;
}

The kernel searches for a module first in the OEM generated list, and then in the kernel ROM region. This search pattern allows one ROM to replace a module in another ROM, even if the module is in a DLL that is implicitly linked to another module. The kernel must be able to write in the ROMChain_t structures that identify the ROM regions. The following code example is invalid because it does not allow the kernel to write in the ROMChain_t structure.

const ROMChain_t SecondROM = {0x8043ee00,0};
OEMRomChain = &SecondROM;

The following code example is valid because it allows the kernel to write in the structure.

ROMChain_t SecondROM = {0x8043ee00,0};
OEMRomChain = &SecondROM;

The kernel can leave a DLL out of an image altogether, even if the DLL is implicitly linked to another module. Romimage.exe prints a warning about the missing DLL, but still builds the image. This enables you to load the missing DLL from the RAM file system or the Target Control shell.

See Also

Multiple XIP Support

Send Feedback on this topic to the authors

Feedback FAQs

© 2006 Microsoft Corporation. All rights reserved.