0

I am developing small hello world app for Freescale iMX6 board, that will run from On-chip RAM. I am able to run the complete code from OCRAM but if I modify the linker script to generate a data section in external DDR ram's memory space, the output binary file suddenly increases in size from 114 KB to 259 MB. It works just fine if that section is created in OCRAM. It is surely related to linking but I cannot find the reason and how to avoid it. Below are selected portions from the linker script:

`MEMORY
{
    OCRAM (rwx) : ORIGIN = 0x00900000, LENGTH = 256K
    DDR (rwx)   : ORIGIN = 0x10000000, LENGTH = 2048M
}`

.
.
.
.ex_ram (ORIGIN(DDR)) : { . = . + 0x10; } > DDR

Looks like something related to huge gap between the OCRAM and DDR ram address space to me, but can't rectify it!

Hamzahfrq
  • 696
  • 1
  • 6
  • 25
  • 2
    There are various solutions to this issue. Look at the `AT` command and the concepts of *LMA* and *VMA*. I am guessing that you will need to copy your code from DDR to OCRAM on startup as the OCRAM is limited. Your **binary** must be a solid chunk as *dwelch* notes. The initial *loader* will copy the OCRAM code from the *load* DDR location to the *runnning* VMA location. This is the standard way to reduce the size of a binary, where code runs from different memory devices. Unallocated sections like `BSS` (Ie, zero memory) do not create output and won't increase the size. – artless noise Apr 02 '14 at 14:11
  • possible duplicate of [How to run code from RAM on ARM architecture](http://stackoverflow.com/questions/15137214/how-to-run-code-from-ram-on-arm-architecture) – artless noise Apr 02 '14 at 14:15
  • @artlessnoise I find the above mentioned question having a broader and somewhat different scope. My question is very specific to my case. Your first comment (and some other posts) are quite helpful nonetheless, but not the above mentioned question. I do not want to use external RAM at all because my routine will eventually test the external RAM for wiring errors (and I will induce errors in the PCB routes to test my routine) – Hamzahfrq Apr 02 '14 at 14:48
  • 1
    Maybe you understood this but what artless noise is telling you is that you can have your separate segments, but you cant tell the linker "here is where it is in memory space" and separately "here is where you put it in the binary" then using linker variables and a bootstrap time mem copy you move the data from the binary location to its final/proper home before starting your C (or higher level language) code. This way the binary is much smaller because the padding is removed, yet the overall result is the same minus some time to copy. – old_timer Apr 02 '14 at 14:52
  • I think now I am able to run my code from OCRAM directly without copying, since I don't trust external RAM (how can I trust it when I am producing wiring errors myself). Simultaneously, I'll be able to store variables in external RAM for the sake of testing it, without increasing the binary file like hell and keeping whole address-specific information limited in the linker script. Thanks guys! – Hamzahfrq Apr 02 '14 at 15:09
  • Ok, it sounds like just `NOLOAD` would solve your issue. You may find [ARM memtest86](http://stackoverflow.com/questions/11640062/how-to-do-memory-test-on-arm-architecture-hardware-something-like-memtest86) useful. – artless noise Apr 02 '14 at 20:02
  • @dwelch a little clarification needed from your comment. If a NOLOAD section is made by the user and a variable is placed there in C code, does the bootloader copy that variable at that location automatically or is it the responsibility of the user to take care of it? I am using Freescale iMX6 architecture with on-chip boot ROM for booting, if this info is important for answering. – Hamzahfrq Apr 16 '14 at 08:48
  • I dont know what objcopy does specifically for various corner cases, the simple answer is just try it... – old_timer Apr 16 '14 at 12:31

1 Answers1

2

of course it does, you asked it to convert the file to a binary right? So even if you have only a single byte of data in the data segment you need to have (0x10000000-0x00900000)+(amount of data) bytes in the .bin file...the raw binary file format does not have any address information therefore it needs to cover all loadable segments and pad with fill in between, so you get that size of a file (0x10000000-0x00900000)+(amount of data). Do an experiment and change your 0x10000000 to 0x20000000 and you will see a file more than twice the size.

If you use elf or coff or intel hex or srec or some binary format that includes addresses as well as data and does not require padding between the segments in the file, then your files wills stay small...

old_timer
  • 69,149
  • 8
  • 89
  • 168
  • this was my guess as well BUT the supplied linker file has sections for both OCRAM and DDR ram, still the output binary is regular size i.e. 113kb – Hamzahfrq Apr 02 '14 at 14:02
  • The alternative image format is a good suggestion. However, for some things like initial boot code, this may not be possible. If the OP (or anyone) is using *u-boot*, etc then switching image formats is the easy solution. – artless noise Apr 02 '14 at 14:17
  • After careful comparison, I got the reason for smaller bin file with original linker script. The original linker script loads nothing in the OCRAM. IT simply divides into three sections that are NOLOAD so no data goes into them. The binary file has to take care of the data that is in the DDR section only, hence the smaller size. @artlessnoise I am using bare metal SDK and the manufacturing tool (image downloader) doesn't seem to support elf format. Looks like I have to use "at" or pointers and do it from C language – Hamzahfrq Apr 02 '14 at 14:44