Wednesday, November 7, 2012

wxPerl on Raspbian

Edited 14 November 2012 to add use of qcow2 images and add kernel I compiled.

Following my initial post about wxPerl and Raspberry Pi, I thought I had better retrace the steps I took to create my environment and post a howto. So, read on only if that interest you.

This is to get Rasbian, the debian based distro for Rasberry Pi working under Qemu on Windows, and then to install a custom Perl and wxPerl. I should point out that as far as can recall this is my first serious venture into using Qemu so it is very much a beginner's approach.

First you need Qemu for Windows. I downloaded the latest pre-built binary zip Qemu-1.2.0-windows.zip from  http://lassauge.free.fr/qemu/ .

For convenience I just put everything into a single folder - C:\RaspberryPi. So you need to extract the contents of Qemu-1.2.0-windows.zip to C:\RaspberryPi so that you have, amongst other things, C:\RaspberryPi\qemu-system-armw.exe.

Next you need a suitable qemu kernel. I used the instructions at http://xecdesign.com/compiling-a-kernel/ to help in compiling my own kernel that can be downloaded at qemu-arm-kernel.zip. I did not follow the instructions quite to the letter - I extracted a config from a working qemu / Raspberry kernel to use as a starting point.

Extract the contents of qemu-arm-kernel.zip (both kernel file and 'modules' sub-folder ) to your C:\RaspberryPi folder.

And finally for downloads, we need the base Raspbian image. Get the 2012-10-28-wheezy-raspbian.zip from the Raspberry Pi download page - or you can use this direct link to the file : 2012-10-28-wheezy-raspbian.zip. Extract the single file in that zip ( 2012-10-28-wheezy-raspbian.img ) to your C:\RaspberryPi folder.

Time for a bit of explanation of the steps that follow. The 2012-10-28-wheezy-raspbian.img file is a 2GB raw disk image that is intended to be written to an SD card or other device - and then have the root partition resized to fit the SD card. The image provides a fully working environment - there just isn't much free space if you don't resize it.

To resize our image, we are going to create a copy then rather cheekily we are going to load the first image under Qemu to give us simple tools to resize the copied image. The copied image is the one we will use to play with. There is probably a more efficient way to do this with some other ported tools and there are certainly easier ways working in a Linux environment. But the following way just uses the things you need anyway to run a Raspbian image under Qemu.

Open a Command Prompt. In the command prompt we'll make our copy of the Raspbian image in the qcow2 format. We'll use the qcow2 format because the file size on disk will only increase as we use sectors. A 32GB raw format image would use 32GB on our hard disk even if 30GB are empty.

cd C:\RaspberryPi
qemu-img convert 2012-10-28-wheezy-raspbian.img -O 
    qcow2 myraspbian.qcow2

Next we'll resize the new image. I've chosen to add 32GB to it, but the choice is yours.

qemu-img resize myraspbian.qcow2 + 32G

Now we are ready to launch the original raspbian image and use it to expand the filesystem on the second.

qemu-system-armw -M versatilepb -cpu arm1176 
  -hda 2012-10-28-wheezy-raspbian.img -hdb myraspbian.qcow2 
  -kernel qemu-arm-kernel -m 256 -append "root=/dev/sda2"

You can probably figure out what the params are doing, but 'versatilepb' is the board that Qemu will emulate and works OK for the Raspbian images,  arm1176 is the type of CPU in a Raspberry Pi and '-m 256' tells Qemu the amount of RAM to allocate. There is no point specifying a higher number for RAM even if a Rasberry Pi board can support 512mb. The number 256 is the maximum that the Versatile board can support (and Qemu emulates ).   The two raspbian images specified as -hda and -hdb will appear as devices /dev/sda and /dev/sdb to the versatilepb emulation. The OS will be loaded from /dev/sda2 and we can then go about resizing the /dev/sdb2 partition on our expanded myraspbian.qcow2.

Having issued the qemu-system-armw command above, you should get the Raspberry Pi startup menu which is intended for first time use on a real Raspberry Pi. There is nothing we can usefully do on here for our purposes so you can just select 'finish' that should get you to a command prompt. At this stage, reboot to complete Raspbian's initial setup:

sudo shutdown -r now

After reboot, you should end up at a login prompt. The default user / password combination for the raspbian images is
  • username   pi
  • password  raspberry
Use this to login. We'll use the GNOME Partition Editor to fix up our new image so we need to install it.

sudo apt-get update
sudo apt-get install gparted

Start the LXDE graphical environment

startx

The GNOME Partition Editor is listed under 'Other' in the application menu. By default the GUI will load details for /dev/sda. We want to alter /dev/sdb (which is our myraspbian.qcow2 ) so change to that using the dropdown at the top right of the GUI. Select /dev/sdb2 and selecting 'Partition' from the menu, you can select 'Resize/Move' to resize /dev/sdb2. You can just drag the bars in the GUI to resize to fit the free space on the 15GB image. Apply your changes ( your selections are just 'queued' to begin with) and when this is complete you can close  the Editor. Log out of the LXDE graphical environment and shutdown the machine.

sudo shutdown - h now

When shutdown is complete you can close the Qemu Window.

Now we are ready to boot our new resized raspbian image.

qemu-system-armw -M versatilepb -cpu arm1176 -hda myraspbian.qcow2
 -kernel qemu-arm-kernel -m 256 -append "root=/dev/sda2"

At first startup you will get some error messages ( which result because of the resize we just did ) and be dumped to a rescue prompt. You can fix the filesystem, as suggested by the error messages, with

sudo fsck /dev/sda2

and reboot the system

sudo shutdown -r now

When the system has rebooted, you will be presented with the Raspbian startup menu. This time you may wish to make some selections for your keyboard and locale. After you exit the setup you will be logged in as user 'pi'.

The first thing to do is setup your X configuration so that you get the maximum resolution supported in the Qemu emulation. This appears to be 800x600. (A real Raspberry Pi board supports much higher resolutions). You will need to add an xorg.conf file to your configuration. I've provided one that works for me for a simple install

cd /etc/X11
sudo wget http://www.citrusperl.com/raspbian/xorg.conf

and for this to have any effect we will have to reboot

sudo shutdown -r now

After reboot you will have to login as user pi with password raspberry.

Now you are ready to build wxPerl.  I never use the system Perl for development as your stuff and the system stuff will always fall into conflict so the first thing to do is to build a Perl. Building from source on a Qemu emulated ARM environment takes a very very long time. To save you the effort if you wish, I have uploaded a complete tarball of the Perl and wxPerl that I built that you can install.

I installed my Perl to /var/local/xperl and for the download simply gzipped a tar of the xperl directory for distribution.

But first thing is first. You will need a development environment whether you use the download tar.gz or build yourself. The default gcc in Debian Wheezy is 4.6.3 but this has a bug on the ARM architecture that causes the compilation of Perl to fail. You need to install a gcc-4.7 based environment.

sudo apt-get update
sudo apt-get install make
sudo apt-get install gcc-4.7
sudo apt-get install g++-4.7

To install a pre-built Perl and wxPerl

cd /var/local
sudo wget  http://www.citrusperl.com/raspbian/raspbixperl.tar.gz
sudo tar xzf raspbixperl.tar.gz

While the rest of this post is concerned with running Raspbian under Qemu, you could also install the above Perl / wxPerl to Raspbian on a real Raspberry Pi.

To run wxPerl we need to be in a graphical environment so

startx

Open an LXTerminal, prepend  the custom Perl to your path, and run the Wx::Demo

export PATH=/var/local/xperl/site/bin:/var/local/xperl/bin:$PATH
wxperl_demo.pl

And that's it.

If you really want to build Perl 5.16.2 and Wx yourself then my configure for Perl was:


export RASPBPREFIX=/var/local/xperl
export FLG1="-DUSE_SITECUSTOMIZE -D_FORTIFY_SOURCE=2 -g -O2 "
export FLG2="-fstack-protector --param=ssp-buffer-size=4"
export FLG3="-Wformat -Werror=format-security"
./Configure -des -Dcc=gcc-4.7 -Uinstallusrbinperl \
    -Ulocincpth= -Uloclibpth= -Uafs -Ud_csh -Ud_ualarm \
    -Uusesfio -Uusenm  -Ui_libutil \
    -Dccflags="${FLG1} ${FLG2} ${FLG3}" \
    -Dldflags=" -Wl,-z,relro" \
    -Dlddlflags="-shared -Wl,-z,relro" -Dcccdlflags="-fPIC" \
    -Darchname=arm-linux-gnueabihf  -Duseithreads \
    -Dusethreads -Duselargefiles -Dusesitecustomize \
    -Duse64bitint -Doptimize=-O2 -DDEBUGGING=-g \
    -Dprefix=${RASPBPREFIX} -Dprivlib=${RASPBPREFIX}/lib \
    -Darchlib=${RASPBPREFIX}/lib \
    -Dsiteprefix=${RASPBPREFIX}/site \
    -Dsitelib=${RASPBPREFIX}/site/lib \
    -Dsitearch=${RASPBPREFIX}/site/lib \
    -Dvendorprefix=${RASPBPREFIX}/vendor \
    -Dvendorlib=${RASPBPREFIX}/vendor/lib \
    -Dvendorarch=${RASPBPREFIX}/vendor/lib -Dsed=/bin/sed \
    -Dpager=/usr/bin/sensible-pager -Duseshrplib 

I added some basic CPAN modules

export PATH=/var/local/xperl/site/bin:/var/local/xperl/bin:$PATH
cpan -i LWP::UserAgent
cpan -i ExtUtils::XSpp

Then I needed the development libraries required to build  wxWidgets.

sudo apt-get install libgtk2.0-dev libgstreamer0.10-dev \
    libgstreamer-plugins-base0.10-dev libglu1-mesa-dev \
    libexpat1-dev libtiff4-dev libpng12-dev \
    libjpeg-dev libcairo2-dev libxmu-dev

I'm not sure if it matters, but I wanted wxWidgets built with the same gcc as Perl uses so I downloaded the Alien::wxWidgets tarball and built with

perl Build.PL \
   --wxWidgets-extraflags="CC=gcc-4.7 CXX=g++-4.7 LD=g++-4.7"

Requested a download and build of wxWidgets 2.9.4 when prompted.

Then it was back to the cpan client in a graphical environment  for the Wx builds.

startx

Open an LXTerminal and

export PATH=/var/local/xperl/site/bin:/var/local/xperl/bin:$PATH
cpan -i Wx
cpan -i Wx::Demo

I hope it all helps anyone interested to get started.

Tuesday, November 6, 2012

Fun Things Still Happen

At the end of last week I came across the Raspberry Pi project. The Raspberry Pi Foundation developed this little device to encourage people to learn to tinker with computing, both in software and hardware. The exciting bit from a hardware point of view is that the board has 26 GPIO pins. ( Pins that can be programmed to do stuff. ). The boards cost around $35.

The foundation is supporting Python as the official educational language. It looked like too much fun to be left to Python to me, so I did some preliminary investigation about support for Perl. If this thing turns out to be popular it would be nice if educational users were exposed to Perl on it.

The first thing to check was that programming the GPIO is possible in Perl and sure enough , Device::BCM2835 is available on CPAN.

The board is an ARM based device with 512mb of RAM using SD cards for storage. But how can I have a play before actually purchasing a board?

The Raspberry Pi foundation provides a 2gb disk image of 'Raspbian' - a Debian - Wheezy based Linux distribution compiled for the Raspberry Pi. The idea is that you download the image and write it to an SD card. The Raspberry Pi supports a 32GB SD card so I would guess that in practice you would write the image to that and resize the partitions to take up the additional space.

I wanted to find out if I could run Raspbian in a Qemu emulated ARM environment on Windows to do some initial playing around with. It turns out that you can. Some Googling and use of virtual disk tools on Linux got me a 32GB Raspbian image that I can load as the root partition of a Qemu ARM environment on Windows with 256mb of RAM. As the memory of a real 512mb Raspberry Pi doesn't all go to the ARM processor, this environment seems a reasonable emulation for some initial playing.

This is screenshot of the Wx::Demo for wxPerl running in my Raspbian on Qemu.



So now I await delivery of a board whilst dreaming about what to do via those GPIO pins. ( in Perl, of course )