Blog

  • Raspberry Pi – Setting up driver/module development environment

    Abstract: This post gives the steps required to set up a cross-compiling development environment for Raspberry Pi.
    The base platform is a Linux computer (examples are given for a SuSE 12.2 installation running as a virtual computer on SuSE 12.2 using KVM as the hypervisor).
    1. Installing some prerequisites:
      1. git (use to access the source code repositories)
        On SuSE, use YaST to install if it’s not already there
        On Debian, use apt-get git to install
      2. Create your base directory: we will use ~/Projects
    2. Installing a cross-compiler:
      1. Download and compile the latest crosstool-ng from crosstool-ng.org (you will need to be root for the final make install)
        wget crosstool-ng.org/download/crosstool-ng/crosstool-ng-1.17.0.tar.bz2
        tar -xvz crosstool-ng-1.17.0.tar.bz2
        cd crosstool-ng-1.17.0
        ./configure
        make
        make install
      2. Configure a cross compiler
        mkdir ~/Projects/souce/ccc;cd ~/Projects/souce/ccc
        ct-ng menuconfig

        The cross compiler configuration requires the following settings:

        Section Setting
        Paths and misc [x] Try features marked as EXPERIMENTAL)
        (/tools/x-tools/${CT_TARGET}) Prefix directory
        Target options Target Architecture (arm)
        Endianness: (Little endian)
        Bitness: (32-bit)
        Operating System Target OS (linux)
        Linux kernel version (3.?.?) – use the correct value!
        Binary utilities binutils version: choose the latest not marked EXPERIMENTAL
        C Compiler [x] Show Linaro vesions (EXPERIMENTAL)
        gcc version – choose one of the Lenaro versions: 4.6-2-12.04 does work
        Exit from ct-ng menu configuration.
      3. Build a cross-compiler.
        As root (or with sudo prefix):
        ct-ng buid
        Note: if build fails with a message about Static linking impossible, edit the .config file and change CT_WANTS_STATIC_LINKING=n and try again.
        The compiler will be in /tools/x-tools/arm-unknown-linux-gnueabi
        The build takes quite a while… (42 minutes on a single core of i5-2500 at 3.3GHz)
    3. Installing the Linux Kernel Sources (which are required for compiling modules and drivers):
      1. Create a source directory ~/Projects/source an running the following commands from that directory:
      2. git clone git://github.com/raspberrypi/linux.git
      3. git clone git://github.com/raspberrypi/firmware.git
      4. git clone git://github.com/raspberrypi/tools.git
      You will now have three directories under ~/Projects/source: linux, firmware and tools.
    4. Set the right version of the Linux Kernel – which needs to be the same version you are using on the RaspberryPi.
      You can find the version RaspberryPi is running using the command:

      raspberrypi:~> uname -sr
      Linux 3.2.27+
      You can see the available versions of the Linux kernel by:
      rpidev:~> cd ~/Projects/source/linux
      rpidev:linux> git branch -r
        origin/HEAD -> origin/rpi-3.6.y
        origin/master
        origin/rpi-3.2.27
        origin/rpi-3.6.y
        origin/rpi-patches
      You can set the version to rpi-3.2.27 using:
      git checkout rpi-3.2.27
      • ARM System Type=Broadcom BCM2708 family
      • When changing the kernel version, you need to initialize it. This process will remove the .config file, so it’s a good idea to keep a copy in (eg) ../linux.config
        make mrproper
        To set the configuration, use one or more of the following
        • Copy from your backup: cp ../linux.config .config
        • Get it from the Raspberry Pi ssh root@rpi zcat /proc/config > .config
        • Check the configuration: make ARCH=arm CROSS_COMPILE=/tools/x-tools/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi- oldconfig
          This will prompt you to confirm any new options – use the default except for:
      • Edit the configuration: make ARCH=arm CROSS_COMPILE=/tools/x-tools/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi- menuconfig
        Some areas you might want to configure (especially if you’re planning to use this kernel on the device):

        • Floating Point emulation: you need one emulation set
        • Networking support (enable for more, disable for smaller)
        • Device drivers (enable for more, disable for smaller)
      • You can check the version your source code tree is at using:
        make kernelversion
      • Build the kernel using: (-j2 means use 2 core in parallel)
        make ARCH=arm CROSS_COMPILE=/tools/x-tools/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi- -j2
      • To compile my_module, use the following makefile:
        obj-m:=mymodule.o
        And compile with:
        make ARCH=arm CROSS_COMPILE=/tools/x-tools/arm-unknown-linux-gnueabi/bin/arm-unknown-linux-gnueabi- -C ~/Projects/source/linux SUBDIRS=`pwd` modules
    5. SSH with keys (no passwords)

      Abstract: Instructions on setting up a Linux computer (server) so you can log in (from your client) with ssh without having to enter a password (using keys).

      Without a password, authentication is done with a key. To achieve password-less access, you need a key, and the computer you are logging in to needs to know about that key.
      A Key has two parts – private and public. You keep the private part, you give the public part to anyone who needs to know you are who you say you are.

      Generate a key on the client computer using:
      ssh-keygen -t rsa
      This will create two files:

      File Description
      ~/.ssh/id_rsa Your private key
      ~/.ssh/id_rsa.pub Your public key

      You need to add the contents of ~/.ssh/id_rsa.pub to the file ~/.ssh/authorized_keys on the server, logged in as the user you will be using:
      cat ~/.ssh/id_rsa.pub | ssh user@server "mkdir -p ~/.ssh && cat >> ~/.ssh/authorized_keys"
      This is the last time you will need to enter the password.
      From now on, you can just connect using:
      ssh user@server
      Or, if you are logged on to the client as the same username, just
      ssh-keygen -R ip-address