FAQ:Link
This FAQ section deals with the GNU linker. The linker is the tool that you will use to do the final link and create the final binary based on one or several object files and libraries.
Contents |
Mapping Programs to Memory
What is the memory.x?
The memory.x file is used when you use the m68hc11elfb linker script. It defines memory banks that tell the linker where to put the text, data and other program sections. The name of memory banks are specified within the linker script. A typical memory.x file defines the MEMORY banks as follows:
MEMORY { page0 (rwx) : ORIGIN = 0x0, LENGTH = 256 text (rx) : ORIGIN = 0xE000, LENGTH = 2048 data : ORIGIN = 0x0, LENGTH = 0 }
This definition creates 3 memory banks:
- page0 represents a the HC11/HC12 region for direct addressing mode. This memory bank must always be completely included in the [0..0x0ff] interval.
- text represents the memory bank where the linker will put the .text sections which contains the code. In most cases it represents the ROM of the board (but it can also represent RAM).
- data represents the memory bank used to put the initialized and non-initialized data. This bank usually represents RAM.
See Also How does the linker know where memory.x is?
How does the linker know where memory.x is?
The memory.x file is searched in the current directory and in all directories specified with the -L switch. There is also a default directory which is /usr/m6811-elf/lib or xxx\m6811-elf\lib.
For example, in GEL, the memory.x file is read from the board specific config directory. This is caused by the option:
-L$(GEL_BASEDIR)/config/$(TARGET_BOARD)
For example:
-L/opt/gel-hc1x-1.4.2/config/m68hc11-32k
and this configuration directory contains the memory.x file that corresponds to the m68hc11-32k generic board.
See Also What is the memory.x?
What does "region text is full" mean?
This error occurs when the program is too big to fit in the memory you specified in memory.x. I don't have your memory.x so I can't tell what is your limit but in the following example:
MEMORY { page0 (rwx) : ORIGIN = 0x0, LENGTH = 256 /* Board with 32K ROM. */ text (rx) : ORIGIN = 0x8000, LENGTH = 0x8000 /* And 32K RAM. */ data : ORIGIN = 0x1040, LENGTH = 0x8000-0x1040 }
the program memory is limited by the text region which is 32Kb.
This can happen if you try to link with too many files (whose total exceeds your text region size). It is often the case if you use the Newlib or use floating point operations. The -mshort and -fshort-double may help in reducing that but in many cases this is not enough.
The printf() which comes with Newlib is pretty big and as far as I'm concerned I prefer not to use it. However, it is useful for gcc validation.
Some tips:
- Try compiling with -mshort -fshort-double -Os
- Consider using linker relaxation with -mrelax
- Try using garbage collection of sections
- Avoid using Newlib and printf
See Also What is the memory.x? How can I remove unused functions? How do I tell the compiler to use direct addressing mode to access data
How can I put the soft registers in a specific section?
The soft registers are defined in the section .softregs. During the final link, this section is merged with either the .page0 section (68HC11) or the .bss section (68HC12).
You can change this by using your own linker script and putting the following definition:
*(.softregs)
In the section you want.
For example, copy /usr/m6811-elf/lib/ldscripts/m68hc11elfb.x to your project.
Change:
.page0 : { *(.page0) *(.softregs) } > page0
Into:
.page0 : { *(.page0) } > page0
And add the *(.softregs) somewhere in .bss for example, like:
.bss : { __bss_start = .; *(.softregs) *(.sbss) *(.scommon) *(.dynbss) *(.bss) *(.bss.*) *(.gnu.linkonce.b.*) *(COMMON) PROVIDE (_end = .); } > data
And link with your own linker script with: -Wl,--script,myscript.ld
Be sure to compile with -mrelax otherwise you might have errors during the link (addresses truncated because too big for direct addressing modes).