Implement APIs to Restore a Snapshot (Compact 2013)


Restoring a snapshot is a partnership between the OS and the OAL snapshot boot APIs that you implement. These functions must be shared between the boot loader and the OS. Therefore, you should either create a library that can be shared between the boot loader and the kernel, or you should put your functions in an existing library that can be shared in that manner. You must implement the OAL functions shown in this procedure to restore a snapshot and resume execution at the point where the snapshot was taken.

  • SnapRestore, found in the common boot loader code located at %_WINCEROOT%\platform\common\src\common\boot\blcommon\snapboot.c, is sample code that restores a snapshot. You can choose the name of this function. The OS does not call it. You must modify your boot loader to call this function. For more information, see Modify the Boot Loader for Snapshot Boot.

    The sample code in SnapRestore() was written with the following assumptions:

    • A function to set up the page directory from the page tables stored in the snapshot is available. Sample code in MDMapSnapPages(), which is located in %_WINCEROOT%\platform\common\src\common\boot\blcommon\mapsnap.c, illustrates how to do this for an ARM CPU.
    • The boot loader has detected that the device should boot from a snapshot image, and that a buffer for decompressing the snapshot image has been allocated. It is this decompression area, and the size of it, that the boot loader passes in the dwBufferAddr and cbBufferSize parameters to SnapRestore, together with a pointer to a function that can read a page of memory from the snapshot. If a function to support snapshot paging is not provided, the buffer contains the whole snapshot image.
    • The compression and decompression functions in the Snapshot Boot Sample Code are used if the image is compressed.

    SnapRestore() begins by validating the snapshot header to make sure that it was not corrupted when saving the snapshot. The snapshot header is obtained by reading in the first page of the snapshot boot image using the reader function that was passed to SnapRestore() by the pfnRead argument. See SNAP_HEADER for the layout of the snapshot header.

    After validating the snapshot header, the page tables are read from the snapshot and the chksum for the tables is validated. The page tables are then mapped to physical addresses using the sample code in mapsnap.c. Note that the memory management unit must be active at this point so that the page tables can be mapped to physical memory, or you will be unable to boot from a snapshot.

    If the snapshot image is compressed, SnapRestore() decompresses it. Otherwise, the image is read directly into memory.

    SnapRestore() returns a pointer to the CPU context that you saved in OEMTakeCPUSnapshot so that you can restore the CPU to the state it was in when the snapshot was taken.

    When you return from SnapRestore(), you restore the CPU context. You typically have to write the function that restores the CPU context in assembly language.

    Because you saved the dwSnapPC argument to OEMTakeCPUSnapshot as the PC counter value for the CPU, after the CPU state is restored, execution jumps to OEMSnapshotResume, which is discussed here.

  • OEMSnapshotResume

    This is the first function that executes after the snapshot image and CPU context are restored. Here you reinitialize the device as if it had been cold booted. The system was put into a power-off state before the snapshot was taken. You must re-initialize the device after booting from the snapshot.

    You may want to use your OEMInit function to initialize the device as if it had just powered up. In addition, you may need to modify your OEMInit() function to handle booting from a snapshot. For example, if you use your OEMInit() function to re-initialize your hardware, you may need to modify it so that it does not initialize memory when you are booting from a snapshot because the state of that memory was restored while reading in the snapshot image. You may need to avoid initializing globals because their current values are restored from the snapshot. For more information, see Driver Re-Initialization.

    When you return from OEMSnapshotResume(), the device is in the state it was in when you took the snapshot. It appears as if it just returned from taking the snapshot.

  • OEMReadSnapshot

    Implement this optional function to support snapshot paging. If you provide this function, the OS calls it when a page of memory has to be read from the snapshot. Implementing this function may enable your device to boot from a snapshot more quickly because instead of having to read the whole snapshot image back into memory before resuming, you only have to read pageable memory from the snapshot image as it is needed.

    Memory that is stored in the snapshot is grouped into two categories:

    • Non-pageable memory, which must be restored before the system can resume.
    • Pageable memory, or memory that can be brought in on demand, which includes:
      • All of the user mode memory being used.
      • All of the memory in the shared heap.
      • All of the read/write pages of pageable kernel mode DLLs.

    Taking a snapshot sets the page tables for pages in pageable memory to a value that causes a page fault when they are accessed, and the page fault handler recognizes that the page comes from the snapshot. If you support snapshot paging, the page is reloaded using the OEMReadSnapshot() function.

    If you do not support snapshot paging, all memory is marked as nonpageable and the function that restores the snapshot (see SnapRestore) has to read the whole snapshot image into the XIP region of memory where you store the nk.bin image.