This thread has been locked.

If you have a related question, please click the "Ask a related question" button in the top right corner. The newly created question will be automatically linked to this question.

C6678 EVM: How to boot MAD image directly from RBL (without the EVM's IBL)

Hello,

I have been reading through a number of TI documents and forum posts over the last week, and during that time I have learned a lot about how to boot Keystone multicore devices. I have a specific question regarding how one might boot a MAD image from memory (e.g., NOR flash) using the ROM bootloader (RBL) and without using any sort of secondary bootloader (IBL).

As I understand it, the image that will be processed by the RBL consists of a boot parameter table followed by a boot table that contains the boot image. The romparse utility can be used to combine a boot parameter table and boot table into the final image that is burned to flash.

My question is -- how does one convert a MAD image (created using maptool.py) into the boot table format so that it can be processed by romparse?

Thanks in advance for your assistance!

Best regards,
Dave

  • Hi Dave,
    We will get back to you on this query. Thank you for your patience.
  • Thank you Raja!

  • Hi Dave,

    There are specific bootmodes on the C6678 for which you may still require the IBL like PCIE but for master NAND, SPI and I2C  boot you can boot the image directly from the boot ROM. The IBL expects the boot image the same way as the RBL so you should be able to flash the image on your board the same way as you have been doing on the EVM. On the EVM there is an FPGA firmware that forces the device to execute the IBL to proceed to boot from a specific boot media so you cant try this on an EVM but on your custom hardware.

    For SPI NOR, follow the instructions given here (other than first 2 steps that refer to IBL configuration) :


    Regards

    Rahul

  • Hi Rahul, thank you for the information! I hope to try this out in the next few days; I'll make a follow-up post with my results. Best regards, Dave
  • Rahul, I'm sorry it has taken me so long to reply here; I finally got back to looking at this a couple of days ago. I have been successful in booting a MAD image from NOR flash on the TMDSEVM6678L without using an intermediate bootloader. I wanted to report the procedure here in case it might be of use to someone else.

    Objective: Boot a MAD image on the TMDSEVM6678L eval board with the boot mode DIP switches set for "ROM SPI Boot". This boot mode does not use an intermediate bootloader (IBL).

    Procedure:

    1. Create a MAD image according to the information provided in the "Multicore Application Deployment (MAD) Utilities User's Guide" wiki page. In my case, I created an image using Prelinker Bypass mode that deployed two separate applications on cores 0 and 1. At the end of the process, you will invoke the MAP tool (maptool.py) to create an output image BIN file. This BIN file contains a load image in ROMFS binary format; this is what I refer to as the "MAD image."

    2. (Optional but highly recommended!) Test the MAD image on the eval board by loading and running it using CCS. This gives the assurance that the MAD image is working properly so there are no doubts when we attempt to load it using the KeyStone ROM bootloader (RBL). There are instructions for "Loading and running MAD linked image using CCS" at the end of the MAD Utilities User's Guide. After running the MAD image, connect to the core(s) that should be running and confirm that they are operating properly (e.g., you might have the application on each core increment a counter as it runs that you can check through CCS). Debug as necessary, but do not proceed until you have a working MAD image.

    3. Now that we have the MAD image, we are going to work on using the RBL to 1) load the MAD image from SPI NOR to DDR (we will store it at base address 0x9E000000), and 2) jump to the entry point of the MAD loader in the image (address 0x9E001040). The process of booting from SPI NOR is documented very well in 1452.Booting_from_SPI NOR_C6678.pdf (originally posted by Rahul on https://e2e.ti.com/support/dsp/c6000_multi-core_dsps/f/639/p/229915/1080095?pi316458=7#pi316458=7

    4. The first step in the PDF is to create the boot table in ASCII hex format (the same format generated by hex6x.exe with the -a argument; I recommend starting with any such file generated by hex6x so you have a guideline). I chose to piece my boot table together manually in Notepad++. Note that the ASCII hex file MUST have an "STX" (0x02) ASCII character on the first line and a "dummy" address line as the second line in the file because the b2i2c.exe utility we will use later will discard both the first and second lines. The boot table begins on the third line of the file and has the following format:

      First DWORD: address to branch to after the boot table is loaded (in our case, this would be the MAD loader's entry point, 9E 00 10 40).
      Second DWORD: size of the first load section (in bytes)
      Third DWORD: address at which to load the section
      Fourth DWORD: start of the data for the section

      In our case, we need to load the MAD image to DDR, so we must initialize the DDR controller prior to loading the MAD image. There are a couple of ways to initialize the DDR controller; I chose to use a "DDR EMIF table" as described in section 3.12.3 of the KeyStone Architecture DSP Bootloader User Guide (SPRUGY5). The table is 112 bytes in size. The fields of the table are defined in table 2-23, "DDR3 Configuration Table," in the C6678 datasheet (SPRS691). The base address of the table (0x873500) is provided in table 2-3 of the same datasheet. After reviewing some other forum posts and taking some educated guesses, I found that the following contents of the DDR Configuration Table seem to work for the eval board:

      02 42 80 F4 00 00 00 00 00 00 00 00 00 00 00 00 63 06 2A 32 00 00 00 00 
      00 00 14 50 11 13 78 3C 30 71 7F E3 55 9F 86 AF 00 00 00 00 00 00 00 00 
      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 70 07 32 14 
      00 00 00 00 00 10 01 0F 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
      00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 05 

      The first load section in our boot table is going to be the DDR Configuration Table, which has a size of 112 bytes (0x70) and address of 0x873500. Therefore, the beginning of the ASCII hex file will be as follows:

      STX ASCII character (0x02)
      $A12345678,
      9E 00 10 40 
      00 00 00 70 00 87 35 00 02 42 80 F4 00 00 00 00 00 00 00 00 00 00 00 00 
      63 06 2A 32 00 00 00 00 00 00 14 50 11 13 78 3C 30 71 7F E3 55 9F 86 AF 
      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
      00 00 00 00 70 07 32 14 00 00 00 00 00 10 01 0F 00 00 00 00 00 00 00 00 
      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 05 

    5. The boot table can have additional load sections as necessary. Each section has the following format:

      First DWORD: size of the load section (in bytes)
      Second DWORD: address at which to load the section
      Third DWORD: start of the data for the section

      In our case, we only need one more load section, which will contain the MAD image. Unfortunately, our MAD image is in a binary format (the BIN file generated by maptool.py) and the boot table is in an ASCII file. I wrote a short C program to convert the MAD image into the ASCII hex format; I could not find a TI-provided tool for this purpose. Important note: I found that my C program needed to reverse the endianness of each DWORD in the MAD image when converting it to ASCII:

      fprintf(pOutputFile, "%02X %02X %02X %02X ", pBinaryData[byteIndex+3], pBinaryData[byteIndex+2],     pBinaryData[byteIndex+1], pBinaryData[byteIndex]);

      Once you have the MAD image converted to ASCII hex format, you can simply append the second load section to the ASCII hex file that we began in the previous step. Remember that you will need to put the size of the MAD image in the first DWORD (in my case it was 586,752 bytes) and the address at which to load the MAD image (0x9E000000) as the second DWORD. Here is how my ASCII hex file looked after adding the MAD image section (only the first two lines of the MAD image section are shown:)

      STX ASCII character (0x02)
      $A12345678,
      9E 00 10 40 
      00 00 00 70 00 87 35 00 02 42 80 F4 00 00 00 00 00 00 00 00 00 00 00 00 
      63 06 2A 32 00 00 00 00 00 00 14 50 11 13 78 3C 30 71 7F E3 55 9F 86 AF 
      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
      00 00 00 00 70 07 32 14 00 00 00 00 00 10 01 0F 00 00 00 00 00 00 00 00 
      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 03 05 
      00 08 F4 00 9E 00 00 00 
      6D 6F 72 2D 2D 73 66 31 30 F0 08 00 55 55 55 55 4C 64 61 4D 49 64 61 6F 
      65 67 61 6D 00 00 00 00 49 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 

    6. Finally, we need to terminate the boot table by placing a DWORD of zero immediately following the MAD image section. This DWORD must not be included in the length of the MAD image section, so don't do that by accident! Then, the last line of the ASCII hex file should contain a single "ETX" (0x03) ASCII character. We now have a complete boot table in ASCII hex format.

    7. The second step in the PDF is to convert the boot table into the I2C/SPI format required by the RBL by passing it through b2i2c.exe. Unfortunately, the b2i2c.exe provided in the MCSDK is limited to working with a file size of 0x20000 bytes (see line 161 of b2i2c.c), so you will most likely need to increase the value of this constant and rebuild b2i2c.exe before it will work with your ASCII hex file. (Otherwise, you will receive the following error from b2i2c.exe -- "Max input array size exceeded.") After running the (modified) b2i2c.exe, your boot table will be in "RBL format." Here's how the beginning of my RBL boot table looked; you can compare it with the original bootloader ASCII hex file above. I colored the headers added by b2i2c.exe purple.

      STX ASCII character (0x02)
      $A000000,
      00 80 3A 56 9E 00 10 40 00 00 00 70 00 87 35 00 02 42 80 F4 00 00 00 00
      00 00 00 00 00 00 00 00 63 06 2A 32 00 00 00 00 00 00 14 50 11 13 78 3C
      30 71 7F E3 55 9F 86 AF 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      00 00 00 00 00 00 00 00 00 00 00 00 70 07 32 14 00 00 00 00 00 10 01 0F
      00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
      00 00 00 00 00 00 03 05 00 80 9F D3 00 08 F4 00 9E 00 00 00 6D 6F 72 2D
      2D 73 66 31 30 F0 08 00 55 55 55 55 4C 64 61 4D 49 64 61 6F 65 67 61 6D

    8. The third step in the PDF is to convert the RBL boot table into the CCS DAT file format so that we can load it to memory through CCS. Use the b2ccs.exe provided in the MCSDK to accomplish this. After running b2ccs.exe, your RBL boot table will be in CCS DAT file format (but otherwise unchanged).

    9. The fourth step in the PDF is to use the romparse.exe utility from the MCSDK to prepend a "boot parameter table" onto the RBL boot table in CCS DAT format. Important note: Don't forget to edit the output of the ROM PARSE utility (change 0x51 -> 0x00) as shown in the PDF! I don't remember how I came up with this ROM PARSE command file, but here it is:

      section
      {
        boot_mode = 50
        param_index = 0
        options = 1
        core_freq_mhz = 800
        exe_file = "<The name of your CCS DAT file from the previous step>"
        next_dev_addr_ext = 0x0
        sw_pll_prediv = 5
        sw_pll_mult = 32
        sw_pll_postdiv = 2
        sw_pll_flags = 1
        addr_width = 24
        n_pins = 4
        csel = 0
        mode = 0
        c2t_delay = 0
        bus_freq_mhz = 0
        bus_freq_khz = 500
      }

      Unfortunately, romparse.exe will crash if the input CCS DAT file is too large, and this was the case for me. What I ended up doing was giving a smaller CCS DAT file to ROM PARSE so that it wouldn't crash, and then I manually copied the first 256 lines of the output DAT file (this is the "boot parameter table") and pasted them at the very beginning of the large CCS DAT file that was generated in the previous step. If you do this, don't forget to increase the value of the length field in the DAT file header (the last value on the header line) by 0x100 (256 DWORDs).

      In summary, the output of this step is almost the same CCS DAT file as was previously generated by b2ccs.exe, except this file has 256 additional DWORDs at the very beginning.

    10. The fifth step in the PDF is to use the byteswapccs.exe utility from 2845.SPI_Bootloader.zip (this can be found in the forum post that I mentioned earlier) on the CCS DAT file from the ROM PARSE step.

      The output of byteswapccs.exe is the final CCS DAT file that you will burn to NOR flash on the eval board. Please refer to the documentation in tools\writer\nor in the MCSDK for information on how to program a user application (the CCS DAT file in our case) to NOR flash. Once the CCS DAT file has been programmed to NOR flash, change the boot mode DIP switches on the eval board to "ROM SPI Boot", cycle power to the board, and hope for the best! Give the board several seconds to boot, and then connect through CCS and try to verify that the MAD image is running properly (you can use the same method that you did back in step 2). If it is running, then congratulations! If not, good luck debugging the RBL :-)   It's not fun, but I had to do it so it certainly is possible (you didn't think I got this all working on the first try, did you??) I would recommend checking whether the DDR controller has been initialized correctly (make sure you are NOT using a GEL file in CCS when checking this) -- if yes, then you know the first section of the boot table was loaded properly, and the problem lies sometime after that in the boot process. If not, then you know the first section of the boot table was not loaded properly, and the problem lies sometime before that in the boot process.

    I hope this information helps someone on their adventure to learn the KeyStone bootloader!

  • Hi Butters,

    Thank you for the detailed post.

  • Hi Rajasekaran K, 

    im following your steps but got stuck at point 4.

    Im able to generate .bin file from MAD utility and verified through CCS also.

    But in order to add DDR initialization data what i have done converted .bin file in ascii hex file then made .btbl and finally used b2i2c.exe utilty to get .btbl.i2c but got wrong .btbl.i2c file. 

    pls check this post,

    could you pls help me to figure out where i did mistake.

    Thanks in advance.

    regards,

    Gourav