Baremetal C program compilation - Startup files error



I’m learning Baremetal C programming on Raspberry Pi 400.

I’m following Baremetal examples from

The tutorial uses an older toolchain but I’ve downloaded Arm GNU Toolchain Version 11.2-2022.02 (gcc-arm-11.2-2022.02-x86_64-aarch64-none-elf.tar.xz).

I am able to successfully install this toolchain on my Ubuntu VM. Whenever I want to use this toolchain, I go to the toolchain’s bin directory, and type “export PATH=$PATH:$PWD” in the shell. This makes the toolchain good to go.


Although the new toolchain has different options from the ones given in the examples on the site, I was able to figure out the correct options for the basic baremetal programs for Raspberry Pi 400 ( Though I had to change the example program’s Register GPIO programming in line with ).


Now the questions I'm struggling with:

Question 1:

The C file contains the lines:
/** Main function - we'll never return from here */
int main(void) __attribute__((naked));
int main(void)

When I compile my program with following command, I see warnings:

/armc-07$ aarch64-none-elf-gcc -g -nostartfiles -DRPI4 -O0 -march=armv8.1-a -mtune=cortex-a72 armc-07.c -o kernel.elf


armc-07.c:20:1: warning: 'naked' attribute directive ignored [-Wattributes]

   20 | int main(void) __attribute__((naked));

      | ^~~

/home/aditya/gcc-arm-11.2-2022.02-x86_64-aarch64-none-elf/bin/../lib/gcc/aarch64-none-elf/11.2.1/../../../../aarch64-none-elf/bin/ld: warning: cannot find entry symbol _start; defaulting to 0000000000400000

These are just warnings. I was able to convert the elf file to img file with command:

armc-07$ aarch64-none-elf-objcopy kernel.elf -O binary kernel8.img

 I’m able to replace the original kernel8.img with this one on the Raspain SD card, and run the GPIO programme successfully (GPIO pin ON/OFF).  

But question is - why is the attribute directive being ignored, and how to fix it? I guess it’s not supported in ARM. But what does it do, and what’s the workaround.

Question 2:

I’m at a complete loss when I follow the removal of warning related to _start.

E.g. In example 10 of Part 4, I’m unable to understand how a .s file will be compiled with other .c files. I’m trying the command:

 armc-010$  aarch64-none-elf-gcc -g -nostartfiles -DRPI4 -O0 -march=armv8.1-a -mtune=cortex-a72 -Wl,-z,max-page-size=0x04, -T rpi.x armc-010-start.S armc-010.c armc-010-cstartup.c armc-010-cstubs.c -o kernel.elf


but the cross-compiler throws error -

armc-010-start.S:18: Error: operand 1 must be an integer register -- `ldr sp,=0x8000'

 Now, if I comment out the line ‘`ldr sp,=0x8000'’ from armc-010-start.S , and compile again with same command, then the following error surfaces:

 /home/aditya/gcc-arm-11.2-2022.02-x86_64-aarch64-none-elf/bin/../lib/gcc/aarch64-none-elf/11.2.1/../../../../aarch64-none-elf/bin/ld: error: cannot change output format whilst linking AArch64 binaries


Any idea what’s going on here, and how to fix it?