Skip to content

Instantly share code, notes, and snippets.

@fardjad
Last active Aug 4, 2021
Embed
What would you like to do?
[How to Build an ARM Toolchain on OSX for RaspberryPI] WIP #raspberrypi #toolchain #osx #arm

Building an ARM Toolchain on OSX for RaspberryPI

Requirements

  1. MacPorts

     sudo port selfupdate
     sudo port upgrade outdated
    
  2. GCC prerequisites

     sudo port install gcc48 bash gawk gzip bzip2 gmake gnutar perl5 zip unzip gmp mpfr mpc isl cloog
     sudo port install autoconf m4 automake gettext gperf dejagnu expect tcl autogen guile flex subversion openssh diffutils gpatch
    

    Make sure to prepend /opt/local/libexec/gnubin to PATH

  3. Other packages

     sudo port install wget tree
    

Case-sensitive file system

If you don't have a partition with case-sensitive file system, create a disk image and format it with a case-sensitive filesystem:

hdiutil create -fs HFSX -size 100g -type SPARSEBUNDLE -volname toolchain toolchain
hdiutil attach toolchain.sparsebundle -owners on

Use bash

Bash is a POSIX compliant shell which is required for building GCC. ZSH and some other shells are not fully POSIX compliant.

Environment variables

Set the following environment variables to make things easier

export VOLUME_ROOT_DIR="/Volumes/toolchain"

export ARCHIVE_DIR="$VOLUME_ROOT_DIR/archive"
export SRC_DIR="$VOLUME_ROOT_DIR/src"
export BUILD_DIR="$VOLUME_ROOT_DIR/build"

export PREFIX_DIR="$VOLUME_ROOT_DIR/arm"
export SYSROOT_DIR="$PREFIX_DIR/sysroot"

export BUILD="x86_64-apple-darwin13.0.0" # run gcc -v
export TARGET="armv6zk-hardfloat-linux-gnueabi"
export CPU="arm1176jzf-s"
export ABI="aapcs-linux"
export FPU="vfp"
export FLOAT="hard"

# Use MacPorts installed libraries
export LDFLAGS="-L/opt/local/lib"
export CPPFLAGS="-I/opt/local/include"
export LD_LIBRARY_PATH="/opt/local/lib"
export LD_INCLUDE_PATH="/opt/local/include"

export CPUP1=$(($(sysctl hw.ncpu | awk '{print $2}')+1))

elf.h

sudo port install libelf
sudo ln -s /opt/local/include/libelf /usr/include/libelf
sudo curl http://www.opensource.apple.com/source/dtrace/dtrace-78/sys/elftypes.h?txt -o  /usr/include/elftypes.h
sudo curl http://www.opensource.apple.com/source/dtrace/dtrace-78/sys/elf.h?txt -o /usr/include/elf.h

Edit elf.h and add

#define R_386_NONE        0
#define R_386_32          1
#define R_386_PC32        2
#define R_ARM_NONE        0
#define R_ARM_PC24        1
#define R_ARM_ABS32       2
#define R_MIPS_NONE       0
#define R_MIPS_16         1
#define R_MIPS_32         2
#define R_MIPS_REL32      3
#define R_MIPS_26         4
#define R_MIPS_HI16       5
#define R_MIPS_LO16       6

Directory structure

mkdir -p $ARCHIVE_DIR $SRC_DIR $BUILD_DIR $PREFIX_DIR $SYSROOT_DIR

Download sources

Download the following packages into ARCHIVE_DIR:

  1. linux-rpi-3.10.21
  2. binutils-2.23.2
  3. gcc-linaro-4.8-2013.11
  4. gdb-linaro-7.5-2012.12

and extract them to SRC_DIR once they are downloaded.

Create a system root

You'll need to create a system root with the target system directory structure:

cd $SRC_DIR/linux-rpi-3.10.21
make mrproper # deletes the current configuration, and all generated files
make ARCH=arm bcmrpi_defconfig
make ARCH=arm headers_check
make ARCH=arm INSTALL_HDR_PATH=$SYSROOT_DIR/usr headers_install

binutils

mkdir -p $BUILD_DIR/binutils-2.23.2
cd $BUILD_DIR/binutils-2.23.2
$SRC_DIR/binutils-2.23.2/configure --prefix=$PREFIX_DIR \
                                   --target=$TARGET \
                                   --build=$BUILD \
                                   --disable-werror \
                                   --with-build-sysroot=$SYSROOT_DIR

make all -j$CPUP1
make install
export PATH="$PATH:$PREFIX_DIR/bin"

GCC

mkdir -p $BUILD_DIR/gcc-linaro-4.8-2013.11
cd $BUILD_DIR/gcc-linaro-4.8-2013.11

$SRC_DIR/gcc-linaro-4.8-2013.11/configure --prefix=$PREFIX_DIR \
                                          --target=$TARGET \
                                          --build=$BUILD \
                                          --with-sysroot=$SYSROOT_DIR \
                                          --enable-threads=posix \
                                          --enable-checking=release \
                                          --enable-__cxa_atexit \
                                          --enable-linker-build-id \
                                          --with-cpu=$CPU \
                                          --with-abi=$ABI \
                                          --with-fpu=$FPU \
                                          --with-float=$FLOAT
                                          
make all-gcc -j$CPUP1
make install-gcc

GDB

mkdir -p $BUILD_DIR/gdb-linaro-7.5-2012.12
cd $BUILD_DIR/gdb-linaro-7.5-2012.12
$SRC_DIR/gdb-linaro-7.5-2012.12/configure --prefix=$PREFIX_DIR \
                                          --target=$TARGET \
                                          --build=$BUILD \
                                          --disable-werror \
                                          --with-build-sysroot=$SYSROOT_DIR

make all -j$CPUP1
make install

Compile a kernel for RaspberryPI

cd $SYSROOT_DIR/usr/include

for d in *; do
  sudo ln -s $PWD/$d /usr/include/$d
done

cd $SRC_DIR/linux-rpi-3.10.21
export CCPREFIX=/Volumes/toolchain/arm/bin/armv6zk-hardfloat-linux-gnueabi-

make mrproper
make ARCH=arm bcmrpi_defconfig
make ARCH=arm CROSS_COMPILE=$CCPREFIX oldconfig
make ARCH=arm CROSS_COMPILE=$CCPREFIX -j$CPUP1

# make ARCH=arm CROSS_COMPILE=$CCPREFIX modules_install INSTALL_MOD_PATH=/path/to/modules/directory

Install QEMU

sudo port install qemu +target_arm

Compile a kernel for QEMU

Get a vanilla Kernel 3.10.21, extract it and apply this patch:

patch -p1 < kernel-3.10.21-armv6-qemu.patch

Clean the source tree

make mrproper

Get the kernel configuration

wget https://gist.github.com/fardjad/7772035/raw/987c86847dc43e9af6d2a446321d588dc71c4d7a/linux-3.10.21-qemu
mv linux-3.10.21-qemu .config

Configure and build the kernel

make ARCH=arm oldconfig
make ARCH=arm -j$CPUP1

export QEMU_DIR="$VOLUME_ROOT_DIR/qemu"
mkdir -p $QEMU_DIR
cp arch/arm/boot/zImage $QEMU_DIR/kernel-qemu

Remove symlinked headers

cd $SYSROOT_DIR/usr/include

for d in *; do
  sudo unlink /usr/include/$d
done

Get a Raspbian image.

Start QEMU

Follow this tutorial (First boot section.)

Finally,

qemu-system-arm -kernel $QEMU_DIR/kernel-qemu \
                -cpu arm1176 \
                -m 256 \
                -M versatilepb \
                -no-reboot \
                -serial stdio \
                -append "root=/dev/sda2 panic=1 rootfstype=ext4 rw" \
                -hda /path/to/2013-09-25-wheezy-raspbian.img
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment