Saturday, March 17, 2012

Problem in booting ELF from Xilinx Compact Flash

If your program is debugged through XMD, but does not boot from Compact Flash, the problem is most probably the Vector Table has not been placed at Reset Vector address in the ELF image of your program. When you boot from Compact Flash, for MicroBlaze, the reset vector should be placed at 0x00000000 address. For PowerPC PPC440, the reset vector should be placed at 0xFFFFFFFC address. But, when you debug through XMD, it has to be placed at different address. Why?

Actually, when you are booting from Compact Flash, the SystemACE configures the FPGA with hardware configuration bitstream file, then loads the ELF file into the memory and then resets the processor so that the execution enters into the Reset Vector address. So, your program's vector table should be placed exactly at Reset Vector address.

But, the scenario is different when you use Xilinx Microprocessor Debugger (XMD), GNU Debugger (GDB), or the Software Development Kit (SDK). After you configure the FPGA with bitstream using tools like iMPACT, the processor comes out of reset and executes the reset vector. At this point, the processor is intentionally made to rotate into infinite loop at the reset vector, since the ELF file has not yet been loaded into the memory. The infinite loop is called as bootloop and added into the bitstream while creating the bitstream.

For MicroBlaze, the bootloop is as follows:

00000000 <_boot>:
00000000 :    b8000000     bri    00000000         // 00000000

Look at this for more explanation:
http://www.xilinx.com/support/documentation/sw_manuals/xilinx13_1/platform_studio/ps_c_dld_initializing_bitstreams_with_bootloops.htm

So, the execution has to be in infinite loop untill your ELF program is downloaded fully into the memory. At this scenario, suppose if your ELF image has your own vector table at the reset vector address, when you load your program into the memory, the reset vector(currently in infinite loop) will be overwritten with your code and the program load will crash. So, you should place your vector table at different address inside your ELF image at compile time, and it has to be copied to the reset vector address after the execution entered your program.

After the ELF is completely downloaded into the memory, the execution enters your program through ENRTY() symbol defined in linker file. If it is not defined, execution will start from the start address of your ELF image. So, after that, you copy your own vector table into reset vector address. For example, place your own vector table at SDRAM start address 0x80000000 and after the execution enters your program through the ENTRY symbol _init, copy the vector table into reset vector address 0x00000000.

ELF image:

80000000 <_boot>:
80000000 :    brai    _init

80000400 <_init>
80000400:    ..... /* (Copy vector table at 0x80000000 to 0x00000000) */

Linker Definition File:

ENTRY(_init)

This is what happens when you reset your FPGA board and when you debug your program on FPGA. This apply to all boards such as ML507, SP605, ML605.

Give your comments for improvement!

No comments: