| ||||||
|
|
Preparing for PROMs:
|
| runs the C compiler with the given source file (eg1.c) | |
| links the generated object code with the run-time system file crt0.o | |
| links any required library functions | |
| uses the script file eg1.ld | |
| leaves a map in the file eg1.map. |
It is useful to get a map file so that you can convince yourself that everything has been placed where you expect it.
Now let us look at the linker script file.
The first part of the script defines the layout of memory.
MEMORY {
rom8 : ORIGIN = 0x000000, LENGTH = 16K
ram16 : ORIGIN = 0x010000, LENGTH = 32K
}
The second line of the MEMORY command specifies a block of memory starting at address zero, and extending for 16K bytes. This is our 8K word ROM.
The third line specifies a block of memory starting at byte address 64K, which is word address 32K. The block extends for 32K bytes or 16384 words. This is our 16K of RAM, and it is in the top half of memory.
Note that the names "rom8" and "ram16" are arbitrary, and are in the linkers private name space.
The next line in the script gives a value to the linker symbol __stack. The stack may be anywhere but must not cross the 32K word line where addresses change sign.
PROVIDE (__stack = 0x10000 + 32k - 2);
The value we have given is the byte address of the highest word in the stack, and becomes the initial value of the stack pointer. The code in file crt0.c imports __stack and sets the stack pointer using the LIM instruction. Usually there is no stack limit check, so you need to be very careful about allowing sufficient space for the stack. If the stack overflows, it is most likely that you will corrupt the .bss area.
Note: you can solve this and other memory problems using the 1750's memory management unit.
The next part of the linker script is the SECTIONS command. This tells the linker what to do with program sections read from object code files and libraries given on its command line.
In GCC-1750, each object file may contain some or all of the following kinds of sections:
| The .text section - contains instructions | |
| The .data section - contains static initialized data | |
| The .rdata section - contains static constant data | |
| The .bss section - contains uninitialized data | |
| The .ctor section - contains addresses of global constructors | |
| The .dtor section - contains addresses of global destructors | |
| The .stabs section - part of the debug symbol table | |
| The .stabstr section - part of the debug symbol table |
All of these sections must be placed somewhere. If you specify a MEMORY command, then the chances are that the default placement will not be what you want. So you should have a statement in the SECTIONS command to tell the linker where to place each kind of section.
Of course, you may want finer control than this. Rather than place all instructions in ROM, you may have several ROMs and wish to place certain object code modules in one ROM, and the rest in another. You can do this with the linker, but we are not going cover that here.
The SECTION command builds linker sections from object code sections, and usually you use the same section names. So the linker puts all .text sections into a compound section called .text.
In this example, well collect all the .text sections, read-only data (.rdata) sections, .ctor and .dtor sections, and put them into the ROM. The linker will locate the instructions for crt0 first.
Here is the SECTIONS command. If you do not intend to use C++ or to define constructors in C, (yes you can do this in GNU C), then the all the stuff to do with CTOR and DTOR can be deleted. You will also need to delete the run-time system functions that refer to these. You will find this code in crt0.c.
SECTIONS
{
.text : {
/* Include all .text sections, and mark each end with a label.
We use the underscore prefix to avoid clashes with names
in your C or C++ source files. */
_stext = .;
*(.text)
_etext = .;
} > rom8
/* All initialized data sections go into ram. Don't forget to
write additional code to intialize these sections. Better
still, include explicit initialization code in your
application program. */
.data : {
_sdata = .;
*(.data)
_edata = .;
} > ram16
/* All read-only sections go into the second ROM. */
.rdata : {
*(.rdata)
/* Include any C++ global constructors. If you're not using
C++ then you can delete this and the code in crt0.c that
refers to it. */
__CTOR_LIST__ = .;
LONG((__CTOR_END__ - __CTOR_LIST__) / 4 - 2)
*(.ctors)
LONG(0)
__CTOR_END__ = .;
/* Include any C++ global destructors. You can delete
this too. */
__DTOR_LIST__ = .;
LONG((__DTOR_END__ - __DTOR_LIST__) / 4 - 2)
*(.dtors)
LONG(0)
__DTOR_END__ = .;
} > rom8
/* The .bss sections, which are uninitialized in the source and
set to zero at run time, are located in RAM after the .data
sections. Beyond the end of the .bss sections are the
heap and stack. */
.bss : {
__bss_start = .;
*(.bss)
*(COMMON)
end = ALIGN(0x2);
_end = ALIGN(0x2);
} > ram16
/* Debug symbol tables are not loaded, but do need to get
linked with the rest of the program. */
.stab 0 (NOLOAD) :
{
[ .stab ]
}
.stabstr 0 (NOLOAD) :
{
[ .stabstr ]
}
}
|