Do you have a question? Post it now! No Registration Necessary
Subject
- Posted on
- wyse03br
March 31, 2008, 1:01 am

Hi all,
Using GNU linker ld, I'd like to create a section .rom_code
grouping
some routines and all its dependencies, including the implicit called
ones such as math routines provided by libm.a. Going down in more
details, my intention is creating a stand-alone ROM image containing
several utility routines (with all its dependencies) that will be
used
by programs loaded in RAM.
The C code is something like:
% cat test.c <<HERE
#include <stdio.h>
#include <math.h>
extern int main();
void _start() { main(); }
volatile float a, b, c;
volatile float res;
__attribute__((section(".rom_code"))) void rom_function();
void rom_function() {
c = a / b; // Use implicitely libm.a routine
res = sin(c); // Use explictly libm.a routine
}
int main() {
rom_function();
return 0;
}
HERE
% gcc -g test.c -lm -Wl,-T lib.lnk
Compiling and linking in the usual way, only the rom_function()
went to ROM, not its dependencies. These are the references
to .rom_code section, only the rom_function() routine can be found
there:
% objdump -x a.out | grep rom_code
7 .rom_code 00000070 00008000 00008000 00018000 2**2
00008000 l d .rom_code 00000000
00008000 g F .rom_code 00000070 rom_function
The sin() was placed in .text and not in .rom_code:
% objdump -x a.out | grep sin
00000000 l df *ABS* 00000000 s_sin.c
00000000 l df *ABS* 00000000 k_sin.c
00001438 g F .text 000000f8 __kernel_sin
00000514 g F .text 000000ec sin
The linker script used is:
MEMORY
{
RAM_CODE : o = 0x0000 , l = 0x8000
ROM_CODE : o = 0x8000 , l = 0x8000
}
SECTIONS
{
.bss : { *(.bss) } > RAM_CODE
.sbss : { *(.sbss) } > RAM_CODE
.rodata : { *(.rodata*) } > RAM_CODE
.got2 : { *(.got*) } > RAM_CODE
.data : { *(.data) } > RAM_CODE
.sdata : { *(.sdata*) } > RAM_CODE
.text : { *(.text .text.*) } > RAM_CODE
.rom_code : { *(.rom_code) } > ROM_CODE
}
Any ideas on how to put also the rom_function() dependencies into
ROM?
Tks
Walter
Using GNU linker ld, I'd like to create a section .rom_code
grouping
some routines and all its dependencies, including the implicit called
ones such as math routines provided by libm.a. Going down in more
details, my intention is creating a stand-alone ROM image containing
several utility routines (with all its dependencies) that will be
used
by programs loaded in RAM.
The C code is something like:
% cat test.c <<HERE
#include <stdio.h>
#include <math.h>
extern int main();
void _start() { main(); }
volatile float a, b, c;
volatile float res;
__attribute__((section(".rom_code"))) void rom_function();
void rom_function() {
c = a / b; // Use implicitely libm.a routine
res = sin(c); // Use explictly libm.a routine
}
int main() {
rom_function();
return 0;
}
HERE
% gcc -g test.c -lm -Wl,-T lib.lnk
Compiling and linking in the usual way, only the rom_function()
went to ROM, not its dependencies. These are the references
to .rom_code section, only the rom_function() routine can be found
there:
% objdump -x a.out | grep rom_code
7 .rom_code 00000070 00008000 00008000 00018000 2**2
00008000 l d .rom_code 00000000
00008000 g F .rom_code 00000070 rom_function
The sin() was placed in .text and not in .rom_code:
% objdump -x a.out | grep sin
00000000 l df *ABS* 00000000 s_sin.c
00000000 l df *ABS* 00000000 k_sin.c
00001438 g F .text 000000f8 __kernel_sin
00000514 g F .text 000000ec sin
The linker script used is:
MEMORY
{
RAM_CODE : o = 0x0000 , l = 0x8000
ROM_CODE : o = 0x8000 , l = 0x8000
}
SECTIONS
{
.bss : { *(.bss) } > RAM_CODE
.sbss : { *(.sbss) } > RAM_CODE
.rodata : { *(.rodata*) } > RAM_CODE
.got2 : { *(.got*) } > RAM_CODE
.data : { *(.data) } > RAM_CODE
.sdata : { *(.sdata*) } > RAM_CODE
.text : { *(.text .text.*) } > RAM_CODE
.rom_code : { *(.rom_code) } > ROM_CODE
}
Any ideas on how to put also the rom_function() dependencies into
ROM?
Tks
Walter

Re: How to create a ROM library using GNU gcc and ld?
Hi,

If I understood correctly, compilation and linking will be done in
2 steps - first compile the ROM library functions generating an a.aux
intermediary file and second link it when compilling the non ROM
library functions (main(), for instance):
% ppc-elf-gcc -g lib.c -lm -Wl,-T lib.lnk -Wl,-r -o a.aux -DROM #-
DROM selects the ROM-based routines
% ppc-elf-gcc lib.c -Wl,-T lib_aux.lnk a.aux -o a.out
This strategy doesn't work so well, because some symbols are
introduced twice (apparently by CRT0):
/lib/gcc-lib/ppc-elf/3.3.2/crtsavres.o(.text+0x1cc): In function
`_restgpr_31_x':
: multiple definition of `_restgpr_31_x'
a.aux(.text+0x1578): first defined here
collect2: ld returned 1 exit status
Have I misundestood something? Any workaround?
Tks

If I understood correctly, compilation and linking will be done in
2 steps - first compile the ROM library functions generating an a.aux
intermediary file and second link it when compilling the non ROM
library functions (main(), for instance):
% ppc-elf-gcc -g lib.c -lm -Wl,-T lib.lnk -Wl,-r -o a.aux -DROM #-
DROM selects the ROM-based routines
% ppc-elf-gcc lib.c -Wl,-T lib_aux.lnk a.aux -o a.out
This strategy doesn't work so well, because some symbols are
introduced twice (apparently by CRT0):
/lib/gcc-lib/ppc-elf/3.3.2/crtsavres.o(.text+0x1cc): In function
`_restgpr_31_x':
: multiple definition of `_restgpr_31_x'
a.aux(.text+0x1578): first defined here
collect2: ld returned 1 exit status
Have I misundestood something? Any workaround?
Tks

Re: How to create a ROM library using GNU gcc and ld?

Don't use gcc for the partial link.
First use gcc to convert .c file into .o file, then call ld manually to
do partial link (without linker script). Something like this:
% ppc-elf-gcc -g -c lib.c -DROM # creates lib.o file
% ppc-elf-ld -g -r -o a.aux lib.o -lm # add library code
Then build the rest of your project, adding a.aux file to final link stage.
I would call it rom.o instead of a.aux, but that's a personal preference.

Re: How to create a ROM library using GNU gcc and ld?

There are risks for problems, however.
If the library code assumes that the memory is all read/write,
it may break when the code is forced to a write-only section.
Also, you need initialization for initialized variables in
the .data section before the ROM code works. I assume that
you do not have a mechanism for setting the values for the
.data section at start.
Usually, both the application and libraries have to be compiled
so that they can be put into a ROM.
--
Tauno Voipio
tauno voipio (at) iki fi
Tauno Voipio
tauno voipio (at) iki fi

Re: How to create a ROM library using GNU gcc and ld?

Thanks for the info, it makes sense. I did something slightly
different, but the overall result seems to be the same:
% ppc-elf-gcc -g lib.c -lm -Wl,-r -DROM -o rom.out
% ppc-elf-gcc -c lib.c -o lib.o
% ppc-elf-ld lib.o rom.out -T lib.lnk -o lib.out
Just for the records, the linker script is:
SECTIONS
{
/* Selects the sections from rom_code file which should go in ROM
*/
/* This line must come before the other .text section */
.rom_code : { rom.out(.text* .rodata*) } > ROM_CODE
.bss : { *(.bss) } > RAM_CODE
.sbss : { *(.sbss) } > RAM_CODE
.rodata : { *(.rodata*) } > RAM_CODE
.got2 : { *(.got*) } > RAM_CODE
.data : { *(.data) } > RAM_CODE
.sdata : { *(.sdata*) } > RAM_CODE
/* main() and other routines go in RAM */
.text : { *(.text*) } > RAM_CODE
}
Rgds

Re: How to create a ROM library using GNU gcc and ld?

I think this puts the crt code in ROM as well, including your entry
point. This startup code then calls main() which resides in RAM,
creating a dependency between your ROM library and the main application.
Linking the same ROM code to another application may then not work as
expected.
The way I suggested it, the crt code shoult end up in RAM, and can be
different for each application.

Re: How to create a ROM library using GNU gcc and ld?

Right. On the other hand, if I don't add the library -lm on first
compilation, the sin() and other auxiliary functions don't go into
the .rom_code section, which is a major requisite... I guess that the -
nostartup seems to be the answer - _start and main goes in RAM and
rom_function and sin goes in ROM:
% gcc -g lib.c -lm -Wl,-r -Wl,-L/usr/lib -nostartfiles -DROM -o
rom.out
% gcc -g lib.c rom.out -Wl,-T lib_linux.lnk -o lib.out
% objdump -x lib.out | egrep ' (_start|rom_function|main|sin)$'
08048120 g F .rom_code 0000005f rom_function
08094860 g F .text 00000000 _start
08048180 w F .rom_code 00000026 sin
08094924 g F .text 0000001c main
There are also issues with the initialization of global variables
declared in ROM-targetted code that I need to work out. If anyone has
tips on this, be welcome.
Rgds
Site Timeline
- » FSK/ASK on PLCC?
- — Next thread in » Embedded Programming
-
- » Connect4: It all works perfectly
- — Previous thread in » Embedded Programming
-
- » Using C preproc to uniquely identify structure members
- — Newest thread in » Embedded Programming
-
- » Подвох
- — The site's Newest Thread. Posted in » Electronic Circuits (Russian)
-