How to link .bin or .hex file into .elf (.coff)

Go To Last Post
18 posts / 0 new
Author
Message
#1
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I use mega128 with:
Lower 64k: The program in normal way.
Upper 64k: Data produced outside GCC. Available as bin (or hex) file.

Sofar I have a small Perl script that merges the two .bin files together and creates one .hex file. The hex file is programmed into mega128.

However, I like to debug with the JTAGICE and Studio 4.08.
For this I would like to link my .bin data for the upper 64k into my .elf file. The .elf will ofcourse be converted into a .coff.

I hope there is a way to do this within the makefile.

Please give me a hint on how to do this.
(Of course any other solution that does the job would be fine too)

Mikael

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I don't have it at my hand, but AFAIK exists a tool to convert bin files to a include file for C. With that you are able to include it into your compilation.

Of course, the disadvantage is that you have to recompile your project if only the bin file changes.

HTH

Volkmar

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

My solution in such case is to convert binary file into (plain C) character array and compile and link such file as normal one.
Of course this array should be declared in PROGMEM.
If you want to place such a data at exact address you should play a little with linker script and eg. use your own section name.

Regards,

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

It's IMHO also possible to convert a bin file to an ELF file using
avr-objcopy. Of course, you have to invent a section name that is not
otherwise used, in order to not collide with anything else. I don't know
whether it's really possible to create a relocatable ELF file that
way though.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thank you for suggestions.

To convert .bin into an includefile for C is ofcourse a possible way.

My first choice is though what Jörg suggests; to use avr-objcopy. To me that seems more direct.

However I have some problems with it.
I tried this:
C:avr-objcopy -binary-architecture=avr5 file.bin file.obj
and got the response:
avr-objcopy: file.bin: File format not recognized

A raw binary file is just data how can it have an unrecognized format?
What am I doing wrong?

My next step after succeding with this would be to set the start address of the binary data.
Is --set-start= the way to go?

Mikael

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

P.S.
According to the objcopy documentation it shoud be possible to do this conversion from raw binary to obj file:

"
`-B BFDARCH'
`--binary-architecture=BFDARCH'
Useful when transforming a raw binary input file into an object
file. In this case the output architecture can be set to BFDARCH.
This option will be ignored if the input file has a known BFDARCH.
You can access this binary data inside a program by referencing
the special symbols that are created by the conversion process.
These symbols are called _binary_OBJFILE_start,
_binary_OBJFILE_end and _binary_OBJFILE_size. e.g. you can
transform a picture file into an object file and then access it in
your code using these symbols.
"

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

You also have to declare the input file format explicitly, since in
the case of a raw binary file, the tool cannot defer that
automagically from the file contents.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I linked the .bin file into the .elf with it's own section (used avr-objcopy and changed in avr5.x).
The .elf .cof and .hex file is good but Studio4 ignors the new section:(

So I now will try the other idea and change the .bin file into a C include file and add it to my C code instead.
I guess there are a way to tell the C-compiler an specific address for the included data.

How do I tell the compiler that I want my data at a specific memory location?

Mikael

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Sorry, now that you mention it: AVR Studio cannot handle sections
other than the standard .text/.data/.bss. :-(

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

So I guess I have to place my data in .text.
Are there some way to locate a constant to a specific address?
(Preferably in C but also assembler might do.)

I would like to place my data at the beginning of upper 64k (0x10000) and up but don't know how to do it. I'm looking for something like the avr assembler's .ORG.

Is it possible to do in C-code only or do I have to modify something else?
How to do it?

An alternative would be to still use the avr-objcopy (from .bin) but with section .text and in some way get this part of .text placed at 0x10000. Maybe there are some way to make the linker do this?

Any hints are welcome.

Mikael

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

.org is only useful for absolute assemblers, i. e. those assemblers
that don't use a linker. Even on the Z80 under CP/M, it wasn't in use
anymore, since in an assembler + linker combination, it's actually the
linker who decides what goes where.

So, you need to tell the linker. This usually involves changing the
linker script. The default linker script is something like avr5.x.

IMHO, the linker script can only place different sections to explicit
addresses.

Another option might be to place it into a different ELF section, but
then tell avr-objcopy to combine that ELF section along with the
original .text section into the COFF file's .text. Just an idea, I
didn't do any attempt to see whether this might work.

If all you want is debugging, best drop AVR Studio alltogether, and
use GDB (avr-gdb), maybe together with a frontend like Insight (if
that makes you more comfortable). GDB can interface to the JTAG ICE
through AVaRICE, and unlike AVR Studio, GDB can handle the full
feature list of the input ELF file.

Jörg Wunsch

Please don't send me PMs, use email if you want to approach me personally.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

YES, Jörg your suggestion to use GDB insted of studio 4 worked :D
With Insight/GDB/AVaRICE I can now debug also with my
external .bin file linked to separate section at 0x10000.

Still I would like to try to link the external .bin file into the .text section
at an fixed address (0x10000). I just want to se it work (and maybe use it).

I tried to use --change-section-address for the .text section in this file when converting from .bin to .elf with avr-objcopy.
avr-objdump shows WMA and LMA with the new value. But when linking with the rest of .obj files everything was located as usual.

If it is at all possible, I guess I have to modify the .elf (or .coff) file directely.

One trick is ofcourse to add dummy data to the text section so the last item starts at desired address.
I tried it a little with the avr-objcopy and --pad-to 0xFFFF with the original .elf file.
It did pad but I didn't find a way to link in an second .elf in the originally linked .elf.
Is there is a way to do this :?:

If someone knows, please also tell me:
Is it at all possible to place one piece of code within an section at an specified
address with .elf/.coff :?:
Where can I find detailed information on the internals of .elf and .coff files :?:

Mikael

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

I am stuck on this same issue: " File format not recognized"

 

Did you ever figure out how to bypass this?

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

12 years ago! You have to be kidding surely...

 

Ross McKenzie ValuSoft Melbourne Australia

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

The answer is given in #7 anyway.

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Re: #7: I attempted to specify the file using the following commands:

 

-I elf32-avr

-I elf32-little

-I elf32-big

 

I wasn't sure which format the file was - it was the .elf file created by the arduino IDE as it 'verified' a sketch.

 

The full command I used for each of these cases was:

 

<path to avr-objcopy> -j .text -j .data -O binary -I <one of the three options above> <path to .elf file> <arbitrary output file name.bin>

 

But I kept seeing the same error! Maybe I'm misinterpreting what he was saying in #7?

 

If it's helpful: I'm following this tutorial: http://www.freetronics.com.au/pa...

 

I'm using windows 10 (although the tutorial is written for linux), and I have figured out how to work around most of the issues so far. I assume it's possible to convert to .bin in windows.

 

Valusoft - I wish I were joking!

Last Edited: Wed. Jul 13, 2016 - 05:03 PM
  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

But what you are attempting there is NOT what was being talked about in this thread. He was trying to convert a .bin to a .obj so his would be "-I binary"

 

If you were using a sensible operating system you would have access to the file utility and it would have a pretty accurate stab at telling you what format your input files are.

 

But anyway the libbfd that avr-objcopy is based on should be able to spot an ELF file from a 1,000 yards anyway. So it should not be necessary to use any form of "-I elfXXXX" because ELF files have ELF headers and libbfd will spot this. The conclusion of this must therefore be that the file you are trying to use as input is NOT in ELF format. A further check is to try using avr-readelf on it. readelf, among all the binutils, is the one that does NOT use libbfd (in fact it exists to check that libbfd is working right!) so it should be able to tell you about any ELF header on the front of the binary.

 

And yes, of course, it's possible to convert to binary:

E:\WinAVR-20100110\bin>type data.c
char txt[] = "hello world";

E:\WinAVR-20100110\bin>avr-gcc -c -mmcu=atmega16 data.c -o data.elf

E:\WinAVR-20100110\bin>avr-readelf.exe -e data.elf
ELF Header:
  Magic:   7f 45 4c 46 01 01 01 00 00 00 00 00 00 00 00 00
  Class:                             ELF32
  Data:                              2's complement, little endian
  Version:                           1 (current)
  OS/ABI:                            UNIX - System V
  ABI Version:                       0
  Type:                              REL (Relocatable file)
  Machine:                           Atmel AVR 8-bit microcontroller
  Version:                           0x1
  Entry point address:               0x0
  Start of program headers:          0 (bytes into file)
  Start of section headers:          108 (bytes into file)
  Flags:                             0x85
  Size of this header:               52 (bytes)
  Size of program headers:           0 (bytes)
  Number of program headers:         0
  Size of section headers:           40 (bytes)
  Number of section headers:         7
  Section header string table index: 4

Section Headers:
  [Nr] Name              Type            Addr     Off    Size   ES Flg Lk Inf Al
  [ 0]                   NULL            00000000 000000 000000 00      0   0  0
  [ 1] .text             PROGBITS        00000000 000034 000000 00  AX  0   0  1
  [ 2] .data             PROGBITS        00000000 000034 00000c 00  WA  0   0  1
  [ 3] .bss              NOBITS          00000000 000040 000000 00  WA  0   0  1
  [ 4] .shstrtab         STRTAB          00000000 000040 00002c 00      0   0  1
  [ 5] .symtab           SYMTAB          00000000 000184 0000d0 10      6  11  4
  [ 6] .strtab           STRTAB          00000000 000254 000057 00      0   0  1
Key to Flags:
  W (write), A (alloc), X (execute), M (merge), S (strings)
  I (info), L (link order), G (group), x (unknown)
  O (extra OS processing required) o (OS specific), p (processor specific)

There are no program headers in this file.

E:\WinAVR-20100110\bin>avr-objcopy -j .data -O binary data.elf data.bin

and for the last step I don't know how to do this in Windows but looking at the same file in Linux:

:~/windows/WinAVR-20100110/bin$ hexdump -C data.bin
00000000  68 65 6c 6c 6f 20 77 6f  72 6c 64 00              |hello world.|
0000000c

So, yes, I have created a .bin in Windows using avr-gcc/avr binutils starting with a .c file and ending up with the data in a .bin file.

 

Notice on the objcopy I used I did not need a -I, just a -O. As I say, that's because libbfd knows an ELF file when it sees one!

  • 1
  • 2
  • 3
  • 4
  • 5
Total votes: 0

Thanks so much for your reply! Many things that you may not think are helpful because they are obvious to you are enormously helpful for me, so it's greatly appreciated.

 

Based on your suggestion I tried readelf and it too failed at recognizing this file as an elf file. I found a utility: http://mark0.net/soft-trid-e.html that can recognize file types and ran this as well on the .elf file and even this failed!

 

This led me back to the arduino IDE that created the ELF file in the first place. I re-verified the file, which created another temp .elf file, and for some reason, this time it worked, and I was able to use avr-objcopy.

 

Cliff notes: I had a corrupted ELF file. Solution: re-run IDE verification process to re-create .elf file.

 

Hopefully this is helpful to someone 12 years from now :)