Implementing the Boot Loader StartUp Function
Other versions of this page are also available for the following:
8/27/2008
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.
Note
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.
To implement the boot loader StartUp function
Edit the file Startup.s.
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.
STARTUPTEXT 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 CPWAIT ;-------------------------------------------------------------------- ; 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 RealStartup IF EBOOT bl EbootMain ELSE adr r0, OEMAddressTable ; r0 = physical address of OEMMemoryMap bl KernelStart ENDIF ; ; Control should never return to this routine; if it does, spin. ; spin b spin ENTRY_END