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

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

Reply to
wyse03br
Loading thread data ...

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.

Reply to
Arlet

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

Reply to
wyse03br

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.

Reply to
Arlet Ottens

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
Reply to
Tauno Voipio

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

Reply to
wyse03br

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.

Reply to
Arlet Ottens

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

--
42Bastian
Do not email to bastian42@yahoo.com, it's a spam-only account :-)
Use @monlynx.de instead !
Reply to
42Bastian Schick

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

Reply to
wyse03br

ElectronDepot website is not affiliated with any of the manufacturers or service providers discussed here. All logos and trade names are the property of their respective owners.