GCC Cross-Compiler for x86 64
From OSDev Wiki
Contents |
Introduction
This is an add-on to GCC Cross-Compiler. Make sure you have understood that page before trying this...
As of GCC 4.3.2/Binutils 2.18, the x86_64-elf target appears to have been added to the GCC source. Before trying this tutorial, see GCC Cross-Compiler, substituting x86_64-elf as the TARGET.
Creating a cross-compiler to a different CPU is harder than just targeting a different binary format. To add insult to injury, x86_64 is a special case since it does not support a plain, non-linux, ELF target (yet?). Binutils works fine, but GCC causes problems when trying to build it as --target=x86_64-elf, so we have to trick our way around it.
Patches for the toolchain are available on sourceware and [from http://gcc.gnu.org/ml/gcc-patches/2005-03/msg01286.html the GCC website]. The binutils patch (on SourceWare) is applied by default in 2.17, so if you use 2.17 you don't need that patch. The GCC patch isn't applied in any publically released version (as of 4.1.1 and lower that is), so you'll probably need that.
- Note: you are strongly encouraged to use these patches. You might need to modify the sources instead (but then again, if you're making a compiler you should be able to).
Lots of thanks go to Mikkel Krautz for creating & submitting these patches.
Preparation
With patches:
mkdir /usr/cross export PREFIX=/usr/cross export TARGET=x86_64-pc-elf cd /usr/src mkdir build-binutils build-gcc
Without patches:
mkdir /usr/cross export PREFIX=/usr/cross export TARGET=x86_64-pc-linux cd /usr/src mkdir build-binutils build-gcc
This is the same as in the generic how-to above, save for the different TARGET.
Binutils
cd /usr/src/build-binutils ../binutils-x.xx/configure --target=$TARGET --prefix=$PREFIX --enable-64-bit-bfd make all install
Compiling binutils is again nearly identical; note however the additional option --enable-64-bit-bfd.
The BFD library is the method all binutils programs use to access files, and it grows considerably larger and slower if you add 64-bit support to it. Since there are very few systems that use 64-bit, they don't want to add it by default, and for some reason they don't add it depending on the host, so you have to add it manually. Note, the binutils do not actually do anything with the target, they work with binary files, not code. In the binary files special codes are used to specify what needs to be done, in a way that the code doesn't have to be understood or in most cases even read.
GCC
Compiling GCC with patches is pretty much equal to the normal FAQ. Without the patches, however, compiling requires use of -k and ignoring errors. The compiler stubbornly tries to compile some libraries that require a normal environment (such as linux) that you don't have (or haven't specified).
Both with and without patches you'll use all-gcc and install-gcc. The installer tries to make a few libraries if you don't and will fail at this. When your platform gets to a reasonable size of userbase support, you can try to use plain all and install instead, for a more complete GCC environment. With patches:
cd /usr/src/build-gcc
export PATH=$PATH:$PREFIX/bin
../gcc-x.x.x/configure --target=$TARGET --prefix=$PREFIX \
--disable-nls --enable-languages=c,c++ --with-newlib --without-headers
make all-gcc install-gcc
Without patches:
cd /usr/src/build-gcc
export PATH=$PATH:$PREFIX/bin
../gcc-x.x.x/configure --target=$TARGET --prefix=$PREFIX \
--disable-nls --enable-languages=c,c++ --with-newlib --without-headers
make -k all-gcc install-gcc
Since we could not select a plain ELF target, GCC stubbornly insists on compiling some OS dependent libraries, which of course does not work because we don't have them in our OS. The use of the -k option to make forces the build process to continue nevertheless, ignoring the errors. So far, this seems to work.
