一、前言

  《osx下搭建操作系统开发环境之32位交叉开发工具集(gcc+gdb)》一文中讲解了32位交叉工具的构建。64位(专指x64,非IA64)的构建方法和32位基本相同。看过前文的朋友看本文会发现绝大多数内容都是一样的。没错,之所以不基于前文、只讲差异,是为了独立性,方便只关注x64构建方法的朋友。
  我的环境:osx 10.9

二、安装osx版的gcc

brew install gcc48

  推荐下载最新的稳定版gcc。

三、配置编译环境

  1. 下载gcc源码
    根据参考资料1的建议,最好使用最新的gcc来进行编译,被编译的源码也推荐使用一样版本的。也就是说,用gcc 4.8.2来编译gcc 4.8.2的源码。
    下载源码包并解压,得到的目录名称之为“$gcc-4.8.2”。
  2. 下载gcc依赖项
    需要的依赖项有:

将它们都解压出来,把解压出来的b、c、d的目录都放到gcc源码目录下。都需要去掉版本号,比如解压出来的目录名为“mpc-1.0.1”,那么现在就是“$gcc-4.8.2/mpc”。a无需这么做,因为它需要单独编译,参考后续的步骤4。
其中GMP源码包是lzip压缩格式,需要下载lzip工具解压(brew安装)。 3. 下载gdb源码
下载源码包并解压,得到的目录名称之为“$gdb-7.6.1”。 4. 设置环境变量

    export CC=/usr/local/bin/gcc-4.8
    export CXX=/usr/local/bin/g++-4.8
    export CPP=/usr/local/bin/cpp-4.8
    export LD=/usr/local/bin/gcc-4.8

这些都是brew版gcc4.8.2的软链接。如果不设置,那么会使用系统中默认自带的工具,这些工具的版本可能比较老。

    export PREFIX=$HOME/opt/cross
    export TARGET=x86_64-pc-linux-gnu
    export PATH="$PREFIX/bin:$PATH"

这些是编译时候使用的选项。需要注意的是:osdev上的《GCC Cross-Compiler for x86 64》建议将TARGET宏定义为x86_64-elf,但是我实验发现这样行不通,编译gdb的时候会报错“configure: error: configuration x86_64-pc-elf is unsupported.”。 5. 编译交叉版的binutils

    cd $binutils-x.y.z
    mkdir build-binutils
    cd build-binutils
    ../configure --target=$TARGET --prefix=$PREFIX --enable-64-bit-bfd --enable-werror=no
    make
    make install

四、编译交叉版的gcc

cd $gcc-4.8.2
mkdir build-gcc
cd build-gcc
../configure --target=$TARGET --prefix="$PREFIX" --disable-nls --enable-languages=c,c++ --without-headers
make all-gcc
make all-target-libgcc
make install-gcc
make install-target-libgcc

  完成后,在“~/opt/cross/bin”下就能看到编译好的交叉版的编译套件了,包括“x86_64-pc-linux-gnu-gcc”、“x86_64-pc-linux-gnu-g++”和“x86_64-pc-linux-gnu-ld ”等等。可以用“$HOME/opt/cross/bin/$TARGET-gcc –version”来验证一下版本是否正确。
  另外,为了方便使用,可以在.bashrc或者.zshrc中调整环境变量:

export PATH="$HOME/opt/cross/bin:$PATH"

五、编译交叉版的gdb

cd $gdb-7.6.1
mkdir build-$TARGET
cd build-$TARGET
../configure --target=$TARGET --prefix="$PREFIX" --disable-nls --enable-64-bit-bfd --enable-werror=no CFLAGS="-m64"
make
sudo make install

  完成后,在“~/opt/cross/bin”下就能看到编译好的交叉版的x86_64-pc-linux-gnu-gdb了。

  注:

  • 和x64的bochs配合调试的时候,需要切换到x86-64模式(默认模式是i386):

    (gdb) set architecture i386:x86-64
    The target architecture is assumed to be i386:x86-64
    
  • 在这个编译选项版本之前,我尝试了好几种其他的编译选项,虽然都能编译出gdb,但是都无法与x64的bochs进行配合调试。包括使用“../configure –enable-targets=all –enable-64-bit-bfd”。无法与x64的bochs进行配合调试的现象是,gdb能够下断,但是中断点都是错误的,比如:

    (gdb) target remote localhost:1234
    Remote debugging using 192.168.1.16:1234
    0x00000000 in ?? ()
    (gdb) b *0x7c00
    Breakpoint 1 at 0x7c00
    (gdb) c
    Continuing.
    Program received signal SIGTRAP, Trace/breakpoint trap.
    0x000e0000 in ?? ()
    

    正常应该是这样:

    (gdb) target remote 192.168.1.16:1234
    Remote debugging using localhost:1234
    0x000000000000fff0 in ?? ()
    (gdb)
    

    总结,gdb的TARGET要和bochs(而非被调试OS)的平台一致,即如果使用的是x64的bochs,那么gdb的编译TARGET也需要是x64的。

六、参考资料

七、版本记录

  • v1.0 - 2013-11-08,初始发布。

本文的pdf版:osx下搭建操作系统开发环境之64位交叉开发工具集(gcc+gdb)v1.0.pdf