Skip to content
dinuxbg edited this page Dec 27, 2016 · 36 revisions

PRU ELF file format

The current examples use the old UIO pru loader. Remoteproc kernel driver requires a small patch in order to load binutils PRU ELF firmware images. See examples' issue #2 for more information.

Please note that sometimes the PRU Binutils ELF format changes from release-to-release. Intention is to slowly make it compatible with the TI ELF format. User impact of these changes should be minimal - just rebuild all source files when upgrading the toolchain.

PRU ELF machine code previously was arbitrarily chosen to be EM_PRU=0xfebc. Now both PRU-GCC and TI toolchain use 0x90.

DATA segment is at offset 0x0. TEXT segment is put by linker at offset 0x20000000. The PMEM byte address can be calculated by masking bits 29-31 of the TEXT segment address.

TI ELF PRU RelocationsRelocations:

Work is ongoing to make Binutils and TI ELF relocations compatible. In simple terms, goal is to allow intermediate object files to be freely mixed between the two toolchains.

Current Binutils/GCC equivalent TI ID example generator for this relocation
???? 1 Debug REL relocation.
PRU_16_PMEM 5 .2byte %pmem(text_label)
PRU_U16_PMEMIMM 6 jmp text_label; ldi r0, %pmem(text_label)
BFD_RELOC_16 8 .ushort data_label ; 2 bytes
PRU_U16 9 ldi r0, data_label
PRU_32_PMEM a .4byte %pmem(text_label)
BFD_RELOC_32 b .uint data_label ; 4 bytes
PRU_S10_PCREL e qbeq text_label, r1,r2
PRU_U8_PCREL f loop text_label, r0
PRU_LDI32 12 ldi32 r0, data_label
---------------------------------- ------- -------------------------------------------
BFD_RELOC_8 64 .byte data_label_1
PRU_GNU_DIFF8 65 .byte data_label_1 - data_label_2
PRU_GNU_DIFF16 66 .2byte data_label_1 - data_label_2
PRU_GNU_DIFF32 67 .4byte data_label_1 - data_label_2
PRU_GNU_DIFF16_PMEM 68 .2byte %pmem(text_label_1 - text_label_2)
PRU_GNU_DIFF32_PMEM 69 .4byte %pmem(text_label_1 - text_label_2)

GCC PRU ABI

The TI PRU C ABI is described in http://www.ti.com/lit/ug/spruhv7a/spruhv7a.pdf , table 6-3, page 101. Below are pointed only the differences between GCC PRU and TI PRU C.

Item TI PRU C PRU-GCC
Optional label operand marker. `
Pointers to text segment. Pointer size is 16-bit. All pointers, including function pointers, are 32-bit.
Text labels in assembler. $CODE(text_label) Assembler programmers must mark all text labels with %pmem(__label__). Internally linker uses byte-addressing for text segment, so this explicit macro is needed to convert the byte-address to word-address.
Near/far data pointers. Supported. Not supported.
Register packing. A single 32-bit register can hold four distinct 8-bit variables. No packing supported. One register per variable.
Function argument packing. Arguments "fill-in the available holes". Arguments are placed in strictly consecutive registers, aligned to 32 bits.
Intrinsics, e.g. __xin,__xout,. Supported. Planned to be supported, either via __builtin or inline assembly macros.
C++ Supported. Preliminary support. Not tested much.
Endianness. Both supported. Only little endianness supported.
PRU core versions. All supported. Only AM33xx version supported. AM437x should also work but has not been tested.
__R30/__R31 builtin variables. Supported. Similar functionality available via read_r30/write_r30/read_r31/write_r31 macros from <pru/io.h>.
Stack organization. TODO TODO
Data variables initialization. Both --rom_model and --ram_model supported. PRU GCC/Newlib CRT supports only load-time variable initialization (equivalent of TI's --ram_model)
Clone this wiki locally