Sunday, July 08, 2012

Building modules for the latest Raspberry Pi firmware

The latest firmware for the Raspberry Pi is made available through the git repository. The firmware built is based on the kernel sources which are also made available through a separate git repository.

Users may want to install the latest firmware to avail of the latest fixes available for the Raspberry Pi kernel. However changes in the kernel necessitates the rebuild of any customer kernel modules installed. These are kernel modules which are not available on the usual kernel which was distributed. In my case, I need to recompile the drivers for my wireless card which aren't available on the stock kernel. 

The steps given below is to be used when you recompile your drivers from within the Raspberry Pi.

Before we start, we need to make sure that we have the required tools.
# apt-get update
# apt-get install git gcc make
To update the firmware to the latest one from the git repo, follow the steps below

Download the latest firmware repo
#  git clone --depth 1 https://github.com/raspberrypi/firmware.git
The argument --depth 1 limits the firmware downloaded to only the latest available in the repo.
OR
Update your existing firmware repo by first changing into the firmware repo directory and running the command
# git pull 
You now have to download the latest source code from the git repo. The 256 MB of memory available on the Raspberry Pi isn't sufficient to run the git clone command. To get around this, you can download the git repo on a different machine and then copy over the repo to the Raspberry Pi.
To clone the git repo, use the command
# git clone --branch rpi-patches https://github.com/raspberrypi/linux.git rapi-linux
The argument --branch rpi-patches specifies that you would like to download the branch rpi-patches which is the one on which the kernel is built.
Now copy over the directory rapi-linux created to the Raspberry Pi.
OR
Update the existing sources directory by first changing into the sources repo directory and running the command
# git checkout rpi-patches
# git pull
I have the git repos downloaded to the following location on the Raspberry Pi
/root/firmware
/root/rapi-linux
Now to build the kernel headers required to build the module.

1) Determine the git hash which represents the kernel used to build the firmware and check out the sources.
# cat /root/firmware/extra/git_hash 
85b7821857dd0b9cabab59d47f08eabed74679a3
Use this hash to checkout the kernel sources.
# cd /root/rapi-linux
# git checkout 85b7821857dd0b9cabab59d47f08eabed74679a3


2) Prepare the sources so that they can be used to build the kernel module.
Reset the sources to clear any artifacts from an earlier build
# make mrproper
Copy over the kernel configuration and prepare sources.
# zcat /proc/config.gz > .config
# make oldconfig
# make modules_prepare
3) Copy over the files require to build the module from the firmware repo
# cp /root/firmware/extra/Module.symvers /root/rapi-linux
The kernel sources required to build the kernel module is now complete.

To build the module, change into the directory containing the module sources and run the command
# cd /root/rtl8192_8188CU_linux_v3.0.2164.20110715/
# make -C /root/rapi-linux/ M=`pwd`
We pass the location of the kernel sources directory with the -C parameter. 
We pass the location to the module sources using the M= parameter.

To update the kernel on the Raspberry Pi, change into the firmware directory and copy over the required files.
First backup the existing files 
# cd /root/firmware
mkdir -p /root/fw.backups/
# rsync -av /boot /root/fw.backups/
# rsync -av /lib/modules/3.1.9+ /root/fw.backups/
Now copy over the new files
# cp -av boot/* /boot/
# cp -av modules/3.1.9+/* /lib/modules/3.1.9+/
Run depmod to build the module dependencies for modprobe
# depmod -a
Perform any additional steps required for your custom modules. In my case, I need to copy over my newly built wireless module to the new modules folder.

# cp ~/rtl8192_8188CU_linux_v3.0.2164.20110715/8192cu.ko /lib/modules/3.1.9+/kernel/drivers/net/wireless/
# depmod -a 
Now reboot the Raspberry Pi so that the new kernel can be loaded.

Using GPIO pins on Raspberry Pi

The small size of the RasPi means that it lends itself very well to home automation projects. As my first step in understanding how hardware interfaces with the computer, I decided to follow the examples given at
drogon.net.

I got myself a nice starter kit from skypang.co.uk. The kit contains a plastic case for the RasPi along with a breadboard. The kit also contained connecting wires, 2 switches, a few LED lights and resistors.

My first crack at using the GPIO pins on the Raspi was with implementing tuxx crossing. As soon as I set up the first LED, I realised I could recycle some of the components from Siddharth's broken toys. There was a sword which we bought for haloween about 2 years ago. It had a speaker built in which made the sound of clashing swords as the press of a button. In the last play fight Siddharth had with the sword, the plastic blade had snapped and the sword had lost all interest for Siddharth. The speakers I extracted from the sword turned out to be suitable for use with the RasPi.


The project consists of an executable which can set/unset a pin or also read from it. This was used in conjunction with a shell script to write a Traffic Crossing system.

Here is the system in action.


The speakers are a nice touch and the entire system now mimics a Pelican Crossing quiet accurately.

Wednesday, July 04, 2012

Building kernel modules on the Raspberry Pi

To enable wireless on my RaPi, I bought a Edimax wireless usb dongle. This is based on the Realtek chipset which unfortunately was not supported out of the box on the 2012-06-18-wheezy-beta image I was running.

I was following the instructions posted here to enable the wireless dongle but soon found that the binary driver posted doesn't match the kernel version(3.1.9+ #144) I was running on my RaPi.  This meant that I had to build the kernel module required to run the wireless USB dongle from sources. The kernel headers for the running kernel are not provided in the Debian repository or the Rapi firmware git repository. Instead, the kernel sources used to build the kernel have to be used to setup the build environment.

Given below are instructions to build the kernel module for the latest development kernel on the Rapi as well as cross compile on a Linux based laptop or desktop. The limited resources on the RaPi means that building the kernel on the RaPi will take a long time. For this reason, I recommend that you cross compile on your desktop and then copy over the results to the RaPi.

Building on the RaPi.

1) Install git. Also make sure gcc and make are available on your Rapi.

# apt-get update
# apt-get install git make gcc

2) Clone the RaPi kernel git repository

# git clone --branch rpi-patches --depth 1 https://github.com/raspberrypi/linux.git rapi-linux

In my case, I cloned the branch on another machine and copied the resulting directory rapi-linux over to the RaPi at the location /root/rapi-linux.

3) Create a symlink to the kernel build directory used by the build process

# cd /lib/modules/3.1.9+/
# ln -s /root/rapi-linux/ build

4) Copy over the config file and prepare the sources

# cd /root/rapi-linux
# make mrproper
# zcat /proc/config.gz > .config
# make oldconfig
# make modules_prepare

You can build your kernel module at this stage but will find that the build complains about Module.symvers being missing. Attempting to load the resulting module fails with the error "Error: could not insert module ./8192cu.ko: Invalid module format" and the following line in dmesg "no symbol version for module_layout".

To complete the build environment, you will have to generate a Module.symvers file by building a kernel. To do this, run the command

# make vmlinux


This will take some time to build.


To build the module on the RaPi, simply change in to the module sources directory and run

# make -C /lib/modules/`uname -r`/build/ M=`pwd`


OR

Cross-compiling on a x86 based environment.

If you have a Linux based system, you could cross compile on your laptop and copy the result to the Rapi.

The following commands work for Fedora. You will need to adjust to get it working for your distribution


1) Install git, gcc, make and  gcc-arm-linux-gnu required to cross compile the kernel


# yum install -y git make gcc  gcc-arm-linux-gnu

2) Clone the RaPi kernel git repository

# git clone --branch rpi-patches --depth 1 https://github.com/raspberrypi/linux.git rapi-linux

3) Copy over the config file from the RaPi and prepare the sources

On the RaPi
zcat /proc/config.gz > /tmp/config


Copy over /tmp/config on the RaPi to your own system. Now copy it over to the git repo you just cloned.


On the Laptop/Desktop
# cd rapi-linux
# cp /tmp/config .config
# make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnu- oldconfig
# make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnu- vmlinux

At this point, your build environment is complete.


To build a module on the linux desktop, change into the module sources and run

make ARCH=arm CROSS_COMPILE=/usr/bin/arm-linux-gnu- -C ../rapi-linux/ M=`pwd`

Replace ../rapi-linux/ with the location to your own RaPi kernel sources.



Setting a frost alarm on Home assistant

One of the issues with winter is the possibility of ice covering your windscreen which needs to be cleared before you can drive. Clearing ou...