1

what flags do i need to add to:

arm-none-eabi-gcc test.c -o test -mcpu=cortex-m4 -Wall -Os

to get FDPIC binary ?

I made many experiments, and still i receive not a valid format. I know about existence of linker flags:

--oformat elf32-littlearm-fdpic

but i don't know how to pass them properly.

Spliting compiling and linking into separate steps:

arm-none-eabi-gcc -c test.c -o test.o -mcpu=cortex-m4 -Wall -Os
arm-none-eabi-ld test.o --oformat elf32-littlearm-fdpic -pie -o test

Result in that no newlib is added and warning about start is produced:

arm-none-eabi-ld: warning: cannot find entry symbol _start; defaulting to 0000000000000074

Who can help me ? What is the correct commands (flags) ?

I want to start my program on "bare" linux kernel (i have already working kernel on that stm32). I deliver it in initramfs compiled in kernel

EDIT:

arm-none-eabi-gcc test.c -o test -mcpu=cortex-m4 -Wall -fpic -fpie -Os -Xlinker "--oformat elf32-littlearm-fdpic"

Results:

/usr/lib/gcc/arm-none-eabi/10.3.1/../../../arm-none-eabi/bin/ld: unrecognized option '--oformat elf32-littlearm-fdpic'
/usr/lib/gcc/arm-none-eabi/10.3.1/../../../arm-none-eabi/bin/ld: use the --help option for usage information
collect2: error: ld returned 1 exit status
make: *** [Makefile:5: all] Error 1

MOREOVER this tends to work (but i want to use start files):

Makefile:

all:
    arm-none-eabi-as -mcpu=cortex-m4 init.S -o init.o
    arm-none-eabi-gcc -c -fpic -Os -mcpu=cortex-m4 -fpie -Wall init.c -o init-c.o
    arm-none-eabi-ld init.o init-c.o --oformat elf32-littlearm-fdpic -pie -o init --thumb-entry=_start

init.c:

#define USART1_DR (*((volatile unsigned int *)0x40011004))

int main()
{
    volatile int i;

    USART1_DR = 'A';
    
    for (i = 0; i < 1000000; i++) {
    }

    USART1_DR = 'B';

    while (1) {}
    return 0;
}

init.S:

.syntax unified
.cpu cortex-m4
.thumb
.global _start

_start:
bl main
b .

I mean compilation commands. I know my code snippet works only because STM32 has no MMU (and i configured kernel not to use MPU).

sibislaw
  • 103
  • 1
  • 9

1 Answers1

1

arm-none-eabi-gcc is for building things that run on bare-metal, with no OS involved. From a quick search FDPIC seems to be an ABI for loading shared libraries in platforms with no MMU.

If I'm not mistaken, you can't load shared libraries in bare-metal environments, thus maybe the problem is that you're building with the wrong compiler?

user16217248
  • 3,119
  • 19
  • 19
  • 37
  • I want to start my program on "bare" linux kernel (i have already working kernel on that stm32). I think for someone who knows what is FDPIC format and has some experience in gcc and embedded this is obvious. I think uclibc-ng is compiled with that flags - but uclibc-ng is too big for my solution (i have only 0,5MB left for my apps, the rest is kernel). And also this compiler compiled my kernel already with success. – sibislaw Jun 18 '23 at 11:50
  • There is nothing "bare" about the Linux kernel. As you have found, it is huge. Your compiler is suitable for compiling the kernel, but for for executables that are to be loaded by and run on that kernel. To answer your question see `-fdpic` at https://gcc.gnu.org/onlinedocs/gcc/ARM-Options.html, but you still need a suitable compiler. See also https://stackoverflow.com/questions/5731495/can-anyone-explain-the-gcc-cross-compiler-naming-convention explaining gcc cross-compiler naming convention, and why you need one that targets your kernel. Note also that for uclinux fdpic is the default. – Clifford Jun 18 '23 at 12:44
  • I am not sure it is as "obvious" as you claim, _experience_ as led me to avoid embedding Linux at all if I can help it, and certainly not to try to run it on a CM4. MMU support is probably the primary advantage of embedded Linux. Once you have lost that what remains is a large, slow, non-realtime blob of impenetrably complex code, most of which will never be executed, but will present a security and maintenance headache for years to come. – Clifford Jun 18 '23 at 12:52