UPDATE 2 December 2019:
I'm having trouble with the m68k-elf toolchain. What I want to do is to translate a simple 68k-assembly file source.s
like this:
.text
move.w %d0,%d1
Into an object file, then use a linker script memmap.ldscript
:
MEMORY
{
ROM1 (rx) : ORIGIN = 0x00, LENGTH = 16
ROM2 (rx) : ORIGIN = 0x10, LENGTH = 16
}
SECTIONS
{
.text :
{
*(.text)
} >ROM2
}
OUTPUT_FORMAT(binary)
to link this object file into a raw binary file. The final file should look like this (viewed in a hex editor):
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
30 01 00 00 00 00 00 00 00 00 00 00 00 00 00 00
If I build it like this
m68k-elf-as -o source.o source.s
m68k-elf-ld -T memmap.ldscript -o final.rom source.o
Then final.rom
only contains:
30 01
So the code of the section is placed at 0x00 instead 0x05.
I need "raw" machine code to burn onto a E(E)PROM. But I'd like to use a linker and linker script to be able to assemble sections from several source files into objects files, then link them into one final ROM with the section placement controlled by a linker script. Is this possible with m68k-elf?
You need to force the linker to emit the ROM1 region by creating an output section with some content. The manual says:
Other link script directives that allocate space in an output section will also create the output section. So too will assignments to dot even if the assignment does not create space, except for ‘. = 0’, ‘. = . + 0’, ‘. = sym’, ‘. = . + sym’ and ‘. = ALIGN (. != 0, expr, 1)’ when ‘sym’ is an absolute symbol of value 0 defined in the script. This allows you to force output of an empty section with ‘. = .’.
So this should work:
MEMORY
{
ROM1 (rx) : ORIGIN = 0x00, LENGTH = 16
ROM2 (rx) : ORIGIN = 0x10, LENGTH = 16
}
SECTIONS
{
.dummy :
{
. = ORIGIN(ROM1) + LENGTH(ROM1);
} >ROM1
.text :
{
*(.text)
. = ORIGIN(ROM2) + LENGTH(ROM2);
} >ROM2
}
OUTPUT_FORMAT(binary)
However, at least with my binutils version 2.33.1, it doesn't. .=.
doesn't work either. If you only need the region for padding, you can emit some data into it, e.g. by a BYTE(0)
directive and that works:
MEMORY
{
ROM1 (rx) : ORIGIN = 0x00, LENGTH = 16
ROM2 (rx) : ORIGIN = 0x10, LENGTH = 16
}
SECTIONS
{
.dummy :
{
BYTE(0);
. = ORIGIN(ROM1) + LENGTH(ROM1);
} >ROM1
.text :
{
*(.text)
. = ORIGIN(ROM2) + LENGTH(ROM2);
} >ROM2
}
OUTPUT_FORMAT(binary)
If you do have some content for ROM1 then of course just create input section for it but make sure it always exists otherwise the linker will remove it. Strangely enough, even a zero sized section works.