Bootloading an application out of flash and into block RAM is useful when the FPGA bitstream is not going through as many iterations as the software (ELF); it might be impractical to burn the flash every time a software iteration is made (in order to test in hardware).
If this is not an issue, an easier method without a bootloader is described in (Xilinx Answer 46518).
In this tutorial, we will be using 64 KB of block RAM, placing an SREC bootloader into a bitstream, and our block RAM linked application at an offset in our parallel flash device. You can use less block RAM, but this tutorial will assume 64KB.
We place the bootloader at the END of the block RAM range, so we can use the full range of memory for our end application, and so that we do not overwrite the block RAM-linked bootloader while it is copying the ELF out of flash.
- Create a project in XPS for your board, include a linear flash device (via the EMC), and 64K block RAM. A Base System Builder design is ideal, but not required.
- Export to SDK with bitstream.
- In SDK, create your application ("userApp").
- Right-click on the application -> Generate Linker Script
- Ensure the userApp is linked to block RAM
- Create a new SREC bootloader (File -> New Xilinx C Project) ("bootloader")
- In the bootloader's src folder, change the address in blconfig.h to the flash base address.
- Be sure to include an offset if you plan on burning the bootloader bitstream to the flash as well.
- An address of FLASH_BASEADDRESS + 0x01200000 works for most devices.
- Right-click on the bootloader application -> Generate Linker Script
- Ensure the bootloader is linked to block RAM. You do not need any Heap space
- You can open the bootloader.c file, and comment out line 42 for a smaller and faster bootloader; in this mode, you should be able to reduce stack space to 0x100.
- Open the linker script for the bootloader (located under the "src" folder)
- There will be a small tab at the bottom of the window that opens titled "Source", click this.
- In the source for the bootloader's linker script, edit the origin of the block RAM and the length to something near the end. For example:
- microblaze_0_i_bram_ctrl_microblaze_0_d_bram_ctrl : ORIGIN = 0x00000050, LENGTH = 0x0000FFAF
- microblaze_0_i_bram_ctrl_microblaze_0_d_bram_ctrl : ORIGIN = 0x00002000, LENGTH = 0x00002000
- This change allows the bootloader to start copying the user application into its same block RAM at the origin that user App is still linked to (Origin 0x00000050)
You can then click on Xilinx Tools -> Program FPGA, select the bootloader.elf (NOT the bootloop), and burn this bitstream to the flash via(Xilinx Answer 46518) (or add bootloader.elf to your top-level ISE or PlanAhead project, and then burn that bitstream).
You can then use FlashWriter (Xilinx Tools -> Program Flash) to burn your ELF (converted to SREC with the checkbox) to the offset you described in step 7; burning only the user App is much faster than an entire bitstream. You can tweak the ORIGIN and LENGTH to suit your needs.