BareMetal environment
Table of Contents
none-eabi gcc
The bare-metal ABI will assume a different C library (newlib for example, or even no C library) to the Linux ABI (which assumes glibc). Therefore, the compiler may make different function calls depending on what it believes is available above and beyond the Standard C library.
gcc flags
-ffreestanding
Assert that compilation targets a freestanding environment. This implies -fno-builtin. A freestanding environment is one in which the standard library may not exist, and program startup may not necessarily be at main. The most obvious example is an OS kernel. This is equivalent to -fno-hosted.
See Language Standards Supported by GCC, for details of freestanding and hosted environments.
这个选项告诉gcc,目标系统上可能没有标准库的实现,比如libc库.
-specs=nosys.specs
gcc docs
这个选项告诉gcc,读取nosys.specs这个文件来获得编译参数
https://gcc.gnu.org/onlinedocs/gcc-10.2.0/gcc/Spec-Files.html#Spec-Files
/usr/aarch64-none-elf/lib/nosys.specs
%rename link_gcc_c_sequence nosys_link_gcc_c_sequence
*nosys_libgloss:
-lnosys
*nosys_libc:
%{!specs=nano.specs:-lc} %{specs=nano.specs:-lc_nano}
*link_gcc_c_sequence:
%(nosys_link_gcc_c_sequence) --start-group %G %(nosys_libc) %(nosys_libgloss) --end-group
- link_gcc_c_sequence
默认值link_gcc_c_sequence"%G %{!nolibc:%L %G}"
默认选项为如果链接时没有使用-nolibc参数, 那么就将libgcc链接进去
这里将这个重命名为nosys_link_gcc_c_sequence, 而nosys版本中,将额外链接nosys库, nosys库中实现了空的_exit, _write等libc需要使用到的函数 - –start-group
这个选项解决了循环依赖的问题
https://stackoverflow.com/questions/5651869/what-are-the-start-group-and-end-group-command-line-options
https://stackoverflow.com/questions/45135/why-does-the-order-in-which-libraries-are-linked-sometimes-cause-errors-in-gcc/409470#409470 - libnosys.a
在baremetal种,系统会去链接libnosys.a这个静态库
这个库提供了libc所需要的几个操作函数,_exit, _write 1, 其中有几个函数是必须要实现的,比如_close, _write, _read如果没有提供将会在链接时报出warning,并提供出一个空实现. - 根据specs的设置来选择使用libc或者libc_nano, nano版本更加小
libc
baremetal中,也可以选择多种不通的libc实现,比较常用的有newlib和nanolibc这两种
newlib vs nanolibc
newlib
build
mkdir build
cd build
../configure --target=aarch64-none-elf --prefix=$(pwd)
make -j8
make install
refs
https://alex-robenko.gitbook.io/bare_metal_cpp/
From Zero to main(): Bootstrapping libc with Newlib
stackoverflow: How to compile baremetal hello_world.c and run it on qemu-system-aarch64?
https://stackoverflow.com/questions/53614538/undefined-reference-to-posix-memalign-in-arm-gcc
https://stackoverflow.com/questions/15316384/do-not-pass-build-id-to-linker-from-gcc
https://github.com/embeddedartistry/libc
http://cs107e.github.io/guides/gcc/
https://releases.linaro.org/components/toolchain/binaries/latest-7/aarch64-elf/
https://stackoverflow.com/questions/65896336/how-to-compile-baremetal-hello-world-c-and-run-it-on-qemu-system-aarch64
http://sourceware-org.1504.n7.nabble.com/MMU-Off-Strict-Alignment-td251601.html
Howto: Porting newlib A Simple Guide
https://stackoverflow.com/questions/38535738/does-aarch64-support-unaligned-access