cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 
Highlighted
Adventurer
Adventurer
603 Views
Registered: ‎01-20-2017

First Stage Boot Loader suddenly stops

Jump to solution

Working in Vivado 2017.4 and SDK.  I have a First Stage Bootloader that will eventually operate on-board flash memory (custom PCB w/ a Kintex 7 FPGA).  I'm running the code from the debugger and tracing its operation.   I run into a problem while it is performing memcpy's of the srec data file lines.  It successfully processes the first 50 lines of the SREC file and then the code freezes.  

This is the section of code within the bootloader.c file where it freezes:

badcode.PNG

 

And here is the terminal output showing the freeze in the middle of line 245's print statement:

 terminal_out.PNG

The memory is a Spansion 128 Mbit flash memory part.  The .srec file I'm trying to load in resides at memory address 0x00C00000 within flash memory and the .srec file is 186 KB in size.  

What could be causing the code to freeze?

 

0 Kudos
1 Solution

Accepted Solutions
Highlighted
Adventurer
Adventurer
377 Views
Registered: ‎01-20-2017

@simdav_dlp 

Thanks for your help on this.  Based on our discussion, I think I've found a solution.  It's discussed here:  https://www.xilinx.com/support/answers/47911.html

It was a simple modification to the linker script for the first stage bootloader.  With my block RAM range set to 512 KB (0x80000), I decided to use the final 128 KB of this for the bootloader (probably overkill b/c the fsbl is only 0x4468 in size upon building.  But that is ok) So I edited the MEMORY line in the fsbl linker script to read as follows:

MEMORY
{   processor_subsystem_lmb_bram_if_cntlr_2_Mem_processor_subsystem_lmb_bram_if_cntlr_1_Mem : ORIGIN = 0x60000, LENGTH = 0x1FFFF
}

And it worked.  Thanks to everyone for the help!

View solution in original post

0 Kudos
10 Replies
Highlighted
585 Views
Registered: ‎07-23-2019

 

It smells to me of memcpy overwriting what it shouldn't.

Many complain about C having unbound pointers, but no one does about potential bombs like memcpy

 

Highlighted
Adventurer
Adventurer
563 Views
Registered: ‎01-20-2017

I think the problem might be that I'm using a Spansion flash memory part but the SDK code I'm using was taken from a KC-705 project that uses a Micron part.  I fear that there is a configuration setting that I have to adjust to get the code to work with Spansion.   (@archangel-lightworks, maybe an incorrect configuration setting is causing memcpy overruns ... I'm not sure).

Can anyone point me to an application note that walks me through how to customize the Quad SPI block in my Vivado project and/or the SDK software specifically for a Spansion memory part (based on the info in the Spansion datasheet)?  

0 Kudos
Highlighted
Teacher
Teacher
538 Views
Registered: ‎06-16-2013

Hi @efpkopin 

 

Would you share your device name ?

Quad read sequence and Quad mode are very specific in each devices.

User take care it and sets correct code or have to follow correct procedure.

 

Best regards,

0 Kudos
Highlighted
Adventurer
Adventurer
524 Views
Registered: ‎01-20-2017

Sure:

- The Flash part is Spansion S25FL128SAGMFI00. 

- The FPGA is a Kintex 7 xc7k160tffg676-2

The following is how I have the Axi_quad_spi configured in Vivado:

axi_quad_spi_config.PNG 

0 Kudos
Highlighted
Explorer
Explorer
473 Views
Registered: ‎07-14-2014

@efpkopinWhat base address does the bootloader code reside at and what is the destination address for the memcpy? Sorry if you have shown that I may have skimmed over it.

When I have dealt with bootloaders in the past and this sort of thing happens, it was usually because I was trying to copy my main code over the bootloader code while it was running, causing it to crash.

Simon

 

0 Kudos
Highlighted
Adventurer
Adventurer
452 Views
Registered: ‎01-20-2017

@simdav_dlp 

I first programmed the .srec file that I'm trying to load to flash address 0x00C00000.  But I have also tried it at flash address 0x00700000 and got the same result in both cases.

The bitfile that I then upload (that has the fsbl.elf file to initialize in Block RAM embedded) is 6536 KB in size.  I program that file in flash memory starting at address 0x00000000.

 

However, for the tests that I have been doing, I've been programming the FPGA with a bitstream w/ the ELF/MEM File set to 'bootloop' and then I run fsbl.elf from the SDK debugger.  The .srec file is still in Flash memory at 0x00700000.

 

I was also wondering if the architecture of the Flash chip matters.  For the particular chip we are using, memory is made up of a hybrid of 32 sectors of 4KB and 254 sectors of 64 KB.  Is that an issue?  I was assuming that the library accounts for that given that it reads in the manufacturer and device ID as part of the RDID process.

0 Kudos
Highlighted
Explorer
Explorer
448 Views
Registered: ‎07-14-2014

@efpkopin 

I dont't think it's the location of the file in flash that is causing the problem. I think it's where you are copying it to that is causing the issue.

When you download fsbl.elf, what address does the code start executing from? Is this block RAM or external DDR?

When you do the memcpy what is the destination address of the decoded SREC?

If the destination address of that you are copying to is the same as where fsbl.elf is executing from then it will be over-writing itself?

Simon

 

0 Kudos
Highlighted
Adventurer
Adventurer
437 Views
Registered: ‎01-20-2017

@simdav_dlp 

Everything in this design is executing from block RAM.  The processor subsystem lmb_bram_if_cntlr is located in my design between 0x0000_0000 => 0x0001_FFFF.

When I first download fsbl.elf, it looks like it starts to execute at address 0x0000_0988  (but I also see a reference to -start1() at 0x0000_0074):  

starting_bootloader.PNG

The code proceeds to run through the bootloader code (copying those 50 lines).  Just before it freezes, it is executing near address 0x0000_0D40:

just before failure.PNG

As shown in my first post on this topic, I print out the addresses of each memcpy and it's copying to address 0x310 just before failure.  So maybe it is overwriting the fsbl code as you suggest!  So:

1. How do I determine how much space to reserve for the code that is being copied in?  (Is it just the size of the .srec file I put at 0x0070_0000?)

2. How do I tell the fsbl code to start executing at an address just past the target 'copy-to' address range?

 

 

0 Kudos
Highlighted
Explorer
Explorer
426 Views
Registered: ‎07-14-2014

@efpkopin 

Our setup was slightly different. We ran from a small area of BRAM (0x00000000 - 0x00000FFF) I think, which is where the bootloader lived. The bootloader then copied the main code into a much higher memory address in DDR (0xC000000) then effectively used a function pointer to a fixed address to run the main code . This does have the disadvantage of consuming part of the stack with bootloader data, but it seemed to work for us. In your case, you would copy it to an address that is above the bootloader area in your RAM (e.g. 0x00001000) map. You could also use some inline assembler I think to perform a jump instruction to your newly copied code.

You can't really use the SREC file size determine how much RAM space you'll need for the code as each line in the SREC contains encoded saying how many bytes are on that line and where they need to go. The program size normally gets dumped out during the compile process (I think. It's been a long while since I had to work with the software).

I'll have to go and study our memory maps/code if you need any further info.

Simon

0 Kudos
Highlighted
Adventurer
Adventurer
378 Views
Registered: ‎01-20-2017

@simdav_dlp 

Thanks for your help on this.  Based on our discussion, I think I've found a solution.  It's discussed here:  https://www.xilinx.com/support/answers/47911.html

It was a simple modification to the linker script for the first stage bootloader.  With my block RAM range set to 512 KB (0x80000), I decided to use the final 128 KB of this for the bootloader (probably overkill b/c the fsbl is only 0x4468 in size upon building.  But that is ok) So I edited the MEMORY line in the fsbl linker script to read as follows:

MEMORY
{   processor_subsystem_lmb_bram_if_cntlr_2_Mem_processor_subsystem_lmb_bram_if_cntlr_1_Mem : ORIGIN = 0x60000, LENGTH = 0x1FFFF
}

And it worked.  Thanks to everyone for the help!

View solution in original post

0 Kudos