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

Do you have a question? Post it now! No Registration Necessary

Translate This Thread From English to

Threaded View
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

Re: How to create a ROM library using GNU gcc and ld?
Quoted text here. Click to load it

You could use partial linking.

Use: ld -r with your object files and libraries to generate another .o
file.

Name this .o file explicitly in your linker script to put it in the
ROM area.

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

Quoted text here. Click to load it

   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?
Quoted text here. Click to load it

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?
Quoted text here. Click to load it


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

Re: How to create a ROM library using GNU gcc and ld?
Quoted text here. Click to load it

   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?
Quoted text here. Click to load it

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?
Quoted text here. Click to load it

   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

Re: How to create a ROM library using GNU gcc and ld?
Quoted text here. Click to load it

I'd use -nostartfiles so crt* will not be linked.


--
42Bastian
Do not email to snipped-for-privacy@yahoo.com, it's a spam-only account :-)
We've slightly trimmed the long signature. Click to see the full one.

Site Timeline