 Question:
How do I give code a different run and load address ?
Answer: Using the .sect directive to define a user definable initialized
section in C code does not always work correctly.
This method is often used when one wishes to give a
portion of code different run and load addresses.
The compiler may generate .text information, then it may
generate .const or .cinit information, and then go back to generating more .text
information. This means that a portion of the code that was intended for the user section
may be placed in the .text section.
The .label directive can be used with any initialized
section like .text, .data, or other user definable initialized sections (.sect directive)
to place a label at the load address. It does not make sense to have a run address for the
.cinit section since the data is copied to .bss at boot-time or load-time and then never
referenced again. Uninitialized sections like .bss, .stack or .sysmem only have run-time
addresses. Therefore, it does not make sense to have a separate load address. Below is a
general method of placing C code at a separate load address. I used the following command
line:
cl30 -g move.c move1.c move2.c exit.c boot.asm -z move.cmd
******************************** move.c ***************************************
asm(" .sect \".load\" ");
asm(" .global __load_addr ");
asm(" .global __run_addr ");
asm(" .label __load_addr ");
asm("__run_addr .text ");
extern int test(int in);
int main_run(int in)
{
int out = test(in);
return out;
}
asm(" .sect \".end\" ");
asm(" .global __load_end ");
asm(" .label __load_end ");
******************************** move1.c **************************************
extern int _load_addr;
extern int _load_end;
extern int _run_addr;
extern int main_run(int in);
main()
{
int (*ptr_main)(int n) = main_run;
int *load_addr = &_load_addr;
int *load_end = &_load_end;
int *run_addr = &_run_addr;
int len = load_end - load_addr;
int i;
for(i=0; i<len; i++)
*run_addr++ = *load_addr++;
i = (*ptr_main)(100);
}
******************************** move2.c **************************************
int test(int in)
{
return in;
}
******************************** move.cmd *************************************
-c /* LINK USING C CONVENTIONS */
-stack 0x100 /* 1K STACK */
-heap 0x100 /* 1K HEAP */
-lrts30.lib /* GET RUN-TIME SUPPORT */
-m c3x.map
-o c3x.out
-x
-w
/* SPECIFY THE SYSTEM MEMORY MAP */
MEMORY
{
ROM: org = 0x0 len = 0x1000 /* INTERNAL 4K ROM */
EXT0: org = 0x1000 len = 0x7ff000 /* EXTERNAL MEMORY */
XBUS: org = 0x800000 len = 0x2000 /* EXPANSION BUS */
IOBUS: org = 0x804000 len = 0x2000 /* I/O BUS */
RAM0: org = 0x809800 len = 0x400 /* RAM BLOCK 0 */
RAM1: org = 0x809c00 len = 0x400 /* RAM BLOCK 1 */
EXT1: org = 0x80a000 len = 0x1000 /* EXTERNAL MEMORY */
}
/* SPECIFY THE SECTIONS ALLOCATION INTO MEMORY */
SECTIONS
{
.boot: > EXT0
{
boot.obj (.text)
move1.obj (.text)
exit.obj (.text)
}
.text: load = EXT0, run = RAM1
{
move.obj (.load)
* (.text)
move.obj (.end)
}
.cinit: > RAM1 /* INITIALIZATION TABLES */
.const: > RAM1 /* CONSTANTS */
.stack: > RAM1 /* SYSTEM STACK */
.sysmem: > RAM1 /* DYNAMIC MEMORY - DELETE IF NOT USED */
.bss: > RAM1, block 0x10000 /* VARIABLES */
}
|