Implementing the Boot Loader StartUp Function (Windows Embedded CE 6.0)


The StartUp function is the entry point to the boot loader and is the first function that is run following a CPU reset. The StartUp function is responsible for configuring the CPU and other core logic. It is a highly hardware-dependent routine and the best source of examples when implementing your own is to use existing BSP code for standard development boards (SDBs) that use the same CPU or processor.

The tasks that the StartUp function needs to perform may vary depending on the hardware, but in general, the StartUp function needs to perform the following tasks:

  • Put the CPU into the correct run mode if it does not automatically enter that mode after reset. The correct run mode enables unrestricted access to all hardware memory. This is typically called supervisor mode in the case of x86: ring 0 protected mode with a flat memory map.
  • Disable or mask interrupts at the CPU level.
  • Ensure that the memory management unit (MMU) and translation look-aside buffers (TLBs) are off.
  • Invalidate caches and write buffers, if caches are to be used later in the development process.
  • Initialize the memory controller.
  • Initialize other necessary on-chip devices like clocks.
    Board-level initialization will typically come later. For more information about board-level initialization in the boot loader, see Implementing the OEMPlatformInit Function. For more information about board-level initialization in the OAL, see Implementing the OEMInit Function.
  • Set up a stack pointer.
  • Optionally set up MMU for static logical-physical address mappings and optionally enable the caches.
  • Copy the running boot loader image from flash memory to RAM. The boot loader typically starts executing in flash memory at boot time and then will typically copy itself to RAM, and then continue running in RAM. The latter process happens because the boot loader will usually write to flash memory, but most linear flash memory cannot handle both read and write operations at the same time, or due to performance reasons.
  • Jump to C code.

The StartUp function is typically shared between the boot loader and the OS in the OAL. Differences between the boot loader and the OS environment are typically handled with the preprocessor directives #ifdef. Some of the differences between the boot loader and OS environment include handling CPU resume and power management code.

  1. Edit the file Startup.s.

  2. Add the full implementation of the StartUp function to the file Startup.s. For more information about the file containing the StartUp function, see Creating a File for the Boot Loader StartUp Function.

    The StartUp function is typically implemented in assembly code.

    The following code example shows the StartUp function for the ARM hardware platform used in this particular boot loader development process. For more information about the example hardware platform used for this example, see Boot Loader Design.

        LEAF_ENTRY StartUp
            ; Disable all interrupts, set SVC mode.
            mov     r0, #(SVC32Mode :OR: NoINTS)
            msr     cpsr_c, r0
            ; Disable MMU and caches.
            ldr                     r0, =CP15ControlInit
            WRMMU_STATE             r0
            ldr                     r0, =CP15AuxControlInit
            WRMMU_AUX_STATE         r0
            ; Flush TLBs and caches.
            mov                     r0, #0x0
            WRMMU_FlushTB           r0
            WRCACHE_FlushIDC        r0
            ; Drain write buffer.
            mov     r0, #0
            mcr     p15, 0, r0, c7, c10, 4
            ; Set up a temporary stack. Use the first 32 KB of on-chip SRAM. 
            ldr     sp, =(CPU_SRAM0 + SZ_32K - 4)
            bl      disableInts
            bl      initUART                ; Or initLEDs – for debugging.
            bl      initClocks
            bl      initStaticMem
            bl      initSDRAM               
            bl      sizeSDRAM               ; SDRAM size in MB returned in r0. 
        IF EBOOT
            ; Relocate code from flash to RAM if necessary. This step is required
            ; because Eboot code runs from physical, not virtual, addresses.
            ; Returns with r0 = linked (absolute) address for Startup, -1 if 
            ; currently executing in the correct place.
            ; Note: Because the Eboot image is built to execute from RAM but is currently
            ; executing out of flash, verify that this call is a relative branch. Once the
            ; code is relocated to RAM, absolute address references are fine.
            ; The branch with link instruction will do a relative branch and because 
            ; Thumb/ARM mode switching is not necessary, it works fine here.
            bl       EverythingRelocate
            ; If relocation was successful, jump to the new address of RealStartup. 
            ; Otherwise just fall through.
            cmp     r0, #-1
            movne   pc, r0
        ENDIF       ; IF EBOOT
        IF EBOOT
            bl      EbootMain
            adr     r0, OEMAddressTable     ; r0 = physical address of OEMMemoryMap
            bl      KernelStart
        ; Control should never return to this routine; if it does, spin.
    spin    b       spin

Community Additions