Part Number: PROCESSOR-SDK-AM335X
Other Parts Discussed in Thread: SYSBIOS
Tool/software: TI C/C++ Compiler
Not a question. I am posting this for posterity, in the event anyone else had this problem, to avoid spending weeks trying to figure it out.
Goal: Using the TI compiler for a BeagleBone Black, to create an image of the program, which is named "app", and placed on an SD card, to be loaded by the bootloader.
The link below shows how to build the SD card, load the bootloader, modify your file to be the "app", etc... But the problem is that these steps don't properly create an app that has the entry point at address 0x80000000, which is required by the MLO bootloader. That actually needs to happen during the compile and link stage. And the compile needs to be done twice, as you will see.
processors.wiki.ti.com/.../AM437x
So, after much begging for help, and digging and many failures from older posts, I have it solved.
(Old posts on E2E didn't work. And I suspect, given TI's penchant to change things and break the way things work, this will probably not work for long. But it works now.)
We need to tell the linker to set the address of function _c_int00 to be at location 0x80000000. The TI compiler along with the entire build environment doesn't make that easy to figure out. To do that, we need to have a linker script which tells it so. So we add a "custom.cmd" script to the project at the root level.
In order to figure out what to put in the custom linker script, you need to find out:
1. Where the entry point is
2. What library file provided the entry point.
And this also isn't well documented... Build your program and look in the MAP file to find out the entry point address. In my test, it was 80008698. So, based on the address of 80008698, I looked further down the the map file for that address, and that says what library and object file provided the function.
ENTRY POINT SYMBOL: "_c_int00" address: 80008698
800085a0 0000007c sysbios.aea8fnv : arm_TaskSupport_asm.obj (.text:_ti_sysbios_family_arm_TaskSupport_buildTaskStack)
8000861c 0000007c ti.targets.arm.rtsarm.aea8fnv : Assert.oea8fnv (.text:xdc_runtime_Assert_raise__I)
--->> 80008698 00000074 boot.aea8fnv : boot.oea8fnv (.text)
8000870c 00000074 sysbios.aea8fnv : BIOS.obj (.text:ti_sysbios_family_arm_a8_intcps_Hwi_dispatchFIQC__I)
This would indicate the function came from something called boot.aea8fnv... Which appears to be an "archive" file (to some of us Window programmers, it's a library file, which we know is just a big blob of object files). So if I am reading the map file correctly, that was pulled from object file boot.oea8fnv.
So, next we have to create the "SECTION" in a custom.cmd file to tell it to load that at address 80000000:
We search the C:\Ti\bios_ww_xx_yy_zz folder for that archive file. Then put the absolute path into the script:
SECTIONS {
.text:_c_int00 { C:\ti\bios_6_46_05_55\packages\ti\targets\arm\rtsarm\lib\boot.aea8fnv<boot.oea8fnv>(.text) } > 0x80000000
}
Just about every linker script file I've seen seems to have it's own custom syntax, I can only guess at what this is. Other are welcome to add an understanding to this as they want.
.text:_c_int00 - This means into the "text" section, function named _c_int00
{ C:\ti\bios_6_46_05_55\packages\ti\targets\arm\rtsarm\lib\boot.aea8fnv<boot.oea8fnv>(.text) } - This appears to be the library-archive-filename<actual-object-filename>... But I have no idea what the significance of (.text) is, since it's already at the front of the line... Nor do I know why we need to provide any of this anyway, since the linker knows the function we are linking to. But it doesn't work without it.
> 0x80000000 - is obviously telling it to put this function at address 80000000
Re-run the build, and verify the entry point where it's supposed to be.
ENTRY POINT SYMBOL: "_c_int00" address: 80000000
output attributes/
section page origin length input sections
-------- ---- ---------- ---------- ----------------
.text:_c_int00
* 0 80000000 0000008c
80000000 00000074 boot.aea8fnv : boot.oea8fnv (.text)
80000074 00000008 rtsv7A8_A_le_n_v3_eabi.lib : args_main.obj (.tramp._args_main.1)
Next, you have to use the tools to create the HEX file, and add the 8 byte header. But when using the "arm-none-eabi-objcopy.exe" and the "tiimage.exe" programs, you will have to specify the absolute path to those executables, since they are GNU tools, and the environment is pointing to the TI compiler. I simply put this, and ran it on my own command prompt from inside the debug or release directory.
C:\ti\ccsv7\tools\compiler\gcc-arm-none-eabi-6-2017-q1-update\bin\arm-none-eabi-objcopy.exe -O binary TI_BLinkTest.out TI_BLinkTest.bin C:\ti\pdk_am335x_1_0_7\packages\ti\starterware\tools\ti_image\tiimage.exe 0x80000000 NONE TI_BLinkTest.bin app
Where (in this case) the compiler output file name was "TI_BlinkTest.out" and it generates the file named "app". Place that on the SD card, and it should boot properly.
If anyone wishes to add information to provide a better understanding, that would be appreciated.