User:WillWare/Angstrom and Beagleboard

Topics and color codes
This page, which I originally compiled in 2010, contains information on a few different topics: the Beagleboard (the system I work on these days uses the same processor but is mostly different otherwise), the Angstrom Linux distribution, the opkg package distribution system (Angstrom's equivalent to apt-get or yum), and Bitbake, a build tool for embedded systems.

The language is a little muddy here because Yocto/Poky has become a sort of hazy umbrella project. While Angstrom is clearly a Linux distribution, Yocto seems like one but also includes other things in a way that seems almost deliberately ambiguous. So I haven't worked too hard to pick apart Angstrom versus Yocto since they seem to be chunks of the same tradition maintained by the same people, and an apples-to-apples comparison probably doesn't make sense anyway.

Most vendors have stopped selling the Beagleboard in favor of newer boards such as the Raspberry Pi or the Beaglebone Black. The Beagleboard uses an OMAP processor, which has been discontinued for practical purposes, a more modern alternative being the Sitara ARM Processor such as the AM335x used on the Beaglebone Black.

I've tried to start to differentiate these topics by background color. This is a work in progress, don't rely on this blindly. Stuff that is mostly Beagleboard-specific has a light orange background. Stuff that is mostly Angstrom-specific will have a light green background. I'm not sure if I'll actually use this color, since Angstrom seems very similar to the more recent Yocto project, so the Angstrom stuff is not particularly misleading, as far as I can see.

The Beagleboard is a thing of beauty

 * Available at SparkFun, Digikey, Little Bird Electronics (for Australians), and elsewhere
 * The OMAP processor
 * BeagleBoard with OMAP 3530: website, manual (pdf), wiki, wikipedia
 * A genuinely intimidating 3500-page technical reference for the OMAP 3530. How could one ever take advantage of more than 2% of its capabilities?
 * http://dkc1.digikey.com/us/en/mkt/beagleboard.html -- Digikey's info page about BeagleBoard
 * https://github.com/wware/stuff/tree/master/angstrom-distro -- my own Angstrom-related code repository

What is Bitbake?
Bitbake is a build tool for embedded systems. It is oriented around packages in the same way that Ubuntu or CentOS is. You can use packages sourced by standard repositories, or create your own packages. The benefit of packages is the tracking of dependencies and compatible version numbers and all that.

Bitbake's final product is an image containing a bootloader and other Linux startup process stuff including a file system image and a kernel. Bitbake can also produce intermediate products such as packages. Bitbake can work with other embedded Linux distros such as Yocto.

It's possible to set up an autobuilder with a web interface which performs nightly builds and it can build customized images for you.

Getting started with Angstrom
Angstrom is a small Linux distribution for OMAP processors. I'm working in Ubuntu 10.04 and what follows will pertain to that platform. In your home directory do the following: sudo apt-get install expect diffstat cvs subversion gawk chrpath python-psyco texi2html lighttpd python-setuptools sudo easy_install ply sudo easy_install progressbar sudo rm /bin/sh  # first confirm it's a symbolic link to /bin/dash sudo ln -s /bin/bash /bin/sh git clone git://gitorious.org/angstrom/angstrom-setup-scripts.git in case above does not work or you are sitting behind a proxy use: git clone http://git.angstrom-distribution.org/cgi-bin/cgit.cgi/setup-scripts/ after appropriately setting http_proxy environment variable cd angstrom-setup-scripts/ MACHINE=beagleboard ./oebb.sh config beagleboard MACHINE=beagleboard ./oebb.sh update (cd sources/bitbake && python setup.py build && sudo python setup.py install) MACHINE=beagleboard ./oebb.sh bitbake virtual/kernel console-image
 * 1) Let this last command run overnight. It will take several hours but will
 * 2) prepare your machine for quicker builds in the future. It will help if you're
 * 3) on a fast wired internet connection.

One way to build an Angstrom image to run on a Beagleboard is to use the Narcissus online image builder at http://narcissus.angstrom-distribution.org/. If you want to build an image locally on your own machine, which will allow you to write your own packages, you'll need to install the bitbake tool developed by the OpenEmbedded folks. You have a couple of different options for this.
 * http://www.angstrom-distribution.org/building-angstrom - this is the procedure I followed
 * http://wiki.openembedded.net/index.php/Getting_started
 * and I'm sure there are other web pages with other slight variations

An Angstrom build is initiated by a bitbake command, which specifies a target, for instance: bitbake helloworld-image There is a list of several useful targets at http://docs.openembedded.org/usermanual/html/gettingoe_building_software.html. As with Ubuntu, Angstrom can have meta-packages containing no files, existing only to specify dependencies on a group of other packages. The helloworld-image target refers to the example at http://docs.openembedded.org/usermanual/html/recipes_examples.html. The inputs to a bitbake operation are recipe files with *.bb filenames like the two recipes below.

While one of these targets specifies an entire runnable Linux disk image, bitbake is a sort of make equivalent and a bitbake command can be given for a single package. The result of building a package (analogous to building a Debian or Ubuntu package) is a *.ipk file.

Another example recipe file is found here, and many more in the Angstrom distribution in the sources/openembedded/recipes directory tree.

wware-image.bb
This file specifies a small complete Linux distribution. require console-base-image.bb DEPENDS += "task-base-extended \          " IMAGE_INSTALL += "task-base-extended \       python \        helloworld \        quux-module \            " export IMAGE_BASENAME = "wware-image" IMAGE_INSTALL is the list of packages you want to include. Some of the files resulting from bitbaking an image, found in the  directory, are
 * , a compressed file system image that will be unpacked onto the SD card a little later.
 * which lists the files you should expect to find in the disk image. This file will be helpful when you start to develop your own Angstrom modules, and want to make sure that they were installed correctly in an image.
 * which lists the *.ipk files used to create the disk image.

helloworld_1.0.0.bb
This file specifies an example package. Many recipes involve downloading a tarball, and in that case they carry MD5 and SHA256 checksums to verify the tarball's authenticity. When I build modules myself, I find it handy to write a script that automatically computes the checksums and appends them to the earlier part of the recipe file. DESCRIPTION = "Minimal statically compiled Hello world!" LICENSE = "GPL" PR = "r1" S = "${WORKDIR}" SRC_URI = "http://127.0.0.1:8181/helloworld-1.0.0.tar.bz2 \          " do_install { install -d ${D}${bindir} ${D}${sysconfdir}/rc5.d       install -m 0755 helloworld ${D}${bindir}/ ln -s ../../${bindir}/helloworld ${D}${sysconfdir}/rc5.d/S52helloworld } SRC_URI[md5sum] = "74d43696d6a4f7eed77ee98f325dad73" SRC_URI[sha256sum] = "1186aa89f0ee1e5619d82bdac452e5fb3ce8ce49d5588f9064e13d125fefab55" In this case, I've set up a little HTTP server on the same machine and bitbake is fetching a tarball with the sources. I could have included a  function with instructions for building the module. If no  is defined, bitbake will try to run "make", assuming that the makefile in the tarball will build the included C source file.

Yow! It's working!!
You'll need a serial port connection. I'm using a USB-to-serial adapter which connects to the 10-pin connector between the power socket and the SD card socket. Use a power supply that gives five volts ONLY -- more will damage the board! Connect the pins between the male DB9 end of the adapter and the board's 10-pin ribbon cable connector as follows. Male DB9   Beagleboard 2          3 3           2 5           5 and set up minicom or CoolTerm or screen or some other terminal emulator with 115.2 kbaud, 8N1, no flow control.

Use GParted to partition your SD card. First partition is 50 or 100 MBytes, VFAT32. Second partition is the rest of the card and it must be ext3. It will not work with ext2. I labelled my partitions "boot" and "Angstrom" respectively. When I plug the card in with a USB adapter, it automounts as /media/boot and /media/Angstrom. Now it's time to copy files to the boot partition with a little renaming. export BBDIR=build/tmp-angstrom_2008_1/deploy/glibc/images/beagleboard cp $BBDIR/u-boot-beagleboard.bin /media/boot/u-boot.bin cp $BBDIR/uImage-beagleboard.bin /media/boot/uImage cp $BBDIR/MLO-beagleboard /media/boot/MLO I think the boot partition will work for most of the images; only thing likely to change is the Linux kernel, uImage. The next part is a bit trickier. After building several images overnight, I found all the files still present on my machine, so I chose console-image since it's unlikely to run into any weird hardware dependencies and it's easy to test. This shell command will unpack the file system image onto the SD card's second partition. bunzip2 < $BBDIR/Angstrom-console-image-glibc-ipk-2011.03-beagleboard.rootfs.tar.bz2 \ | (cd /media/Angstrom/; sudo tar xvf -) Just for yucks I confirmed that md5sum gave the same checksums for /media/boot/uImage and /media/Angstrom/boot/uImage.bin. Then I plugged it in, and CRAP, it just started working.

Putting the board on a network
Get a USB hub with an ethernet connection. Put in an SD card with a standard console-image build. Plug the hub into the Beagleboard and connect an ethernet cable to a subnet, and networking should work on reset, and then you can ssh into the board as "root" with no password. Now type opkg update; opkg install guile and VOILA, you have Guile Scheme. It is an amazing thing to behold.

Like Ubuntu or other modern Linux distributions, an Angstrom image is built out of packages, each being a set of files, and there are dependencies between packages. The package management tool for Angstrom is opkg. It installs prebuilt packages which end up on the SD card so they survive a power cycle. After running "sync" you can pop out the SD card and save it, so you can build up the image you want that way, and you can later say "opkg list-installed" to see what you've got.

Your own little opkg repository
If you want to set up an opkg repository for your own packages, you'll need to hunt through anstrom-setup-scripts/build/tmp-angstrom_2008_1 to find your *.ipk files. Each package will produce three, with names like these, and you won't need the "-dbg" or "-dev" versions. helloworld-dbg_1.0.0-r1.6_armv7a.ipk helloworld-dev_1.0.0-r1.6_armv7a.ipk helloworld_1.0.0-r1.6_armv7a.ipk I found my two packages in these places. I don't know why they ended up in two different destinations. angstrom-setup-scripts/build/tmp-angstrom_2008_1/deploy/glibc/ipk/beagleboard/quux-module_1.0.0-r100.6_beagleboard.ipk angstrom-setup-scripts/build/tmp-angstrom_2008_1/deploy/glibc/ipk/armv7a/helloworld_1.0.0-r1.6_armv7a.ipk In the same directory where you find each *.ipk file, find the Packages file, a large text file containing machine-readable package descriptions. Copy the descriptions for your ipks into a Packages file in your repository directory and gzip the result to produce a Packages.gz file. Configure lighttpd (see below) so that the directory is available on your subnet. Confirm the URL for reaching your Packages.gz file. On my subnet, it's http://10.10.228.138:8181/Packages.gz.

On your Beagleboard, create a file /etc/opkg/mystuff-feed.conf following this example. I think as long as it ends in ".conf", the actual name may not be crucial. src/gz mystuff http://10.10.228.138:8181 When that's all set up, try opkg update ; opkg install my-package Be sure to use the actual name of your package. Anyway, assuming that works, you never need to build a complete image again, you can do everything with console-image and opkg. Remember that when you install a package it gets copied to your SD card. This process doesn't happen immediately, but you can force it to happen right away by typing "sync".

Running a lighttpd server
You can easily set up a little lighttpd server on the subnet connecting your development machine and Beagleboard. This is useful for two things. First type, then start the server with the command  , using the following config file. server.document-root = "/path/to/angstrom/package/tarballs" server.port = 8181 mimetype.assign = (  ".gz" => "text/plain",   ".bz2" => "text/plain", ) To build a couple of example modules for use by bitbake, I have a shell script that automates a few steps for me. The sources for my BB recipe files (1, 2) have everything except the checksums, which are appended automatically by this script, and then the script kicks off the lighttpd server.
 * Bitbake (running on your development machine) wants to fetch tar.gz or tar.bz2 files from a HTTP server.
 * The Beagleboard's opkg command wants to pull IPK modules off a repository, and theoretically you can run one.

Kernel modules
If you've primarily worked with 8-bit controllers, you're accustomed to the idea that you GPIO pins and other peripherals are easy to read or write at any point in your code. On a 32-bit controller, Linux makes a distinction between user space where your code is running and kernel space, and the kernel mediates access to peripherals thru device drivers (which are a particular sort of kernel module), which make peripherals look like files that you read and write (since everything in Unix is a file). When the file analogy breaks down, Unix offers a back door called ioctl which gives you fairly arbitrary ways to communicate with the peripheral. The reason for all this complexity is because Unix is running many different processes simultaneously which might bump into one another, and some shouldn't be allowed access to peripherals at all for security reasons.

http://tldp.org/HOWTO/Module-HOWTO/ provides background on Linux kernel modules. It's not too hard to write a vanilla package for the Beagleboard, but a kernel module is a bit trickier. The best lead I've come across is a lab session from a university course using Beagleboard. Their source code is pretty simple (see below). They like this textbook so maybe I should pick up a copy myself. static int __init hello_init(void) {    printk(KERN_INFO "Hello Example Init\n"); return 0; } static void __exit hello_exit(void) {    printk(KERN_INFO "Hello Example Exit\n"); } module_init(hello_init); module_exit(hello_exit); MODULE_AUTHOR("Chris Hallinan"); MODULE_DESCRIPTION("Hello World Example"); MODULE_LICENSE("GPL");
 * 1) include 

To build it, I use this one-line Makefile: obj-m := hello.o and this build script: export SYSROOTS=${HOME}/angstrom-setup-scripts/build/tmp-angstrom_2008_1/sysroots export PATH=${PATH}:${SYSROOTS}/i686-linux/usr/armv7a/bin export ARCH=arm export CROSS_COMPILE=arm-angstrom-linux-gnueabi- export KERNELDIR=${SYSROOTS}/beagleboard-angstrom-linux-gnueabi/kernel make -C ${KERNELDIR} M=$(pwd) modules and that happily builds hello.ko, the kernel module. Next I copy it to the /home/root directory of my SD card and boot the Beagleboard, and voila: [ 239.257354] Hello Example Init Module                 Size  Used by hello                    573  0 rfcomm                33484  0 ipv6                 249063  8 hidp                  11193  0 l2cap                 30104  4 rfcomm,hidp bluetooth             49221  3 rfcomm,hidp,l2cap rfkill                14838  1 bluetooth [ 246.670227] Hello Example Exit Now copy hello.ko into the proper place for kernel modules. modprobe is preferable to insmod because it's better integrated into how the kernel module system usually works. People don't usually manually insmod modules.
 * 1) !/bin/bash
 * 1) insmod hello.ko
 * 1) lsmod
 * 1) rmmod hello
 * 1) mkdir -p /lib/modules/2.6.32/kernel/drivers/char/examples/
 * 2) cp hello.ko /lib/modules/2.6.32/kernel/drivers/char/examples/
 * 3) depmod
 * 4) modprobe hello

Kernel module as an Angstrom package
Having found it difficult to get bitbake to build the kernel module, I used it only to install a prebuilt hello.ko file. So hello.ko and a shell script are now the only things in my tar.bz2 archive. After banging my head on this for several days, I was finally able to write a kernel driver that creates a simple character device. Installing the module in your Angstrom build will put the file quux.ko in your /lib/modules tree, and this shell script will be found in your /home/root directory. modprobe quux || echo Ouch MAJOR=$(dmesg | grep 'quux major' | tail -1 | sed 's/.*=//') mknod /dev/quux c ${MAJOR} 0 cat /dev/quux cat /dev/quux cat /dev/quux cat /dev/quux cat /dev/quux When you run tryit.sh, you see this:: [  37.023468] quux major=249 [  37.026611] Try: mknod /dev/quux c 249 0 Kernel module says: Hello world! I already told you 1 times Hello world! I already told you 2 times Hello world! I already told you 3 times Hello world! I already told you 4 times Hello world! A lot of the information I needed came from the Linux Kernel Module Programming Guide, highly recommended. Section 4 of this deals with drivers for character devices. More cool info in the O'Reilly book.
 * 1) !/bin/sh

Next I just need to wire up the driver to some real hardware.

Access to peripherals
There are some pushbuttons and LEDs on the Beagleboard. How can we get access to them? There is a magic region of the file system called Sysfs built right into the Linux kernel, so we don't need to write or find some special kernel module to enable this. Sysfs is a "virtual filesystem" which presents a simple file-like interface for dealing with what would otherwise be complex and mysterious hardware bits. Remember the scary 3500-page technical manual? Sysfs helps defer the day you need to read it.

The region of interest is, and its usage looks like this. Similar things can be done in C, Perl, Python, etc. There are other regions that are also useful but I haven't read the docs (1, 2) thoroughly enough yet to discuss them intelligently. LED=/sys/class/leds/beagleboard::usr0 BUTTON=/sys/class/gpio/gpio7 echo none > $LED/trigger echo 7 > /sys/class/gpio/export echo in > $BUTTON/direction finished { # restore things to previous state and quit echo heartbeat > $LED/trigger echo 7 > /sys/class/gpio/unexport echo exit 0 } echo Press the user button and watch the LED trap finished SIGINT  # finish when user hits control-C while true; do    # read the pushbutton and turn the LED on and off cp $BUTTON/value $LED/brightness done
 * 1) !/bin/sh
 * 1) take control of an LED. first stop triggering it with the heartbeat.
 * 1) grab the user pushbutton on GPIO7, creating /sys/class/gpio/gpio7 dir.
 * 1) make sure the button GPIO is an input.

The kernel source file that performs all this magic is board-omap3beagle.c. As of this writing I haven't wrapped my head around what's going on in there. The I/O code for the OMAP is more complicated than I feel like thinking about right now.

GPIO pins are available on the expansion connection J3 which appears on sheet 8 of the schematic. GPIO #7 discussed here appears in the lower right corner of sheet 4. Some of the other convenient GPIOs are #132 thru #139, respectively on odd-numbered pins 17, 15, 13... 3 on J3, and pins 27 and 28 are ground, and pin 2 provides +5 volts while pin 1 provides +1.8 volts. Because the GPIO lines connect directly to the OMAP chip with no buffering, they all run at 1.8 volts as well, which is slightly inconvenient in a world of predominantly either 3.3v or 5v.

In one case where I needed to drive some 3.3 volt logic from the Beagleboard, I put 3.3K pull-ups from the outputs to the 3.3 volt rail and that seemed to work fine without damaging the Beagleboard. I also had one input pin operating at 3.3 volts and I fed it directly to the Beagleboard with no voltage limiting, and again it appears to have done no damage. I can't recommend reckless behavior as a general rule but it seemed OK in this instance. I haven't looked at the OMAP datasheet recently to remember whether they comment on that approach.

Useful books

 * Embedded Linux Primer, Second Edition by Christopher Hallinan, published by Prentice-Hall. Excellent.
 * Linux Device Drivers, Third Edition by Jonathan Corbet, Alessandro Rubini and Greg Kroah-Hartman, published by O'Reilly Media.
 * The Linux Kernel Module Programming Guide by Peter Jay Salzman, Michael Burian, and Ori Pomerantz, published by CreateSpace. This is also freely available online, but a paper copy can sometimes be convenient.

Useful URLs
Time permitting, I will filter these better for usefulness. Here is an online manual for OpenEmbedded, but that is subtly different from Angstrom, the exact relationship between them is unclear. So not sure that's useful, but it deals with a lot of the tools.
 * Angstrom-distribution.org
 * http://www.angstrom-distribution.org/
 * http://www.angstrom-distribution.org/building-angstrom
 * http://www.angstrom-distribution.org/demo/beagleboard/
 * http://narcissus.angstrom-distribution.org/ -- Narcissus is the online distribution builder
 * Beagleboard.org
 * http://beagleboard.org/demo/angstrom/
 * http://beagleboard.org/demo/esc -- a bunch of presentations given at Embedded Systems Conference 2008, the "hardware lessons learned" slideshow is enlightening
 * http://beagleboard.org/hardware-xM -- a Beagleboard with 512MB of RAM
 * Google Code, Google Groups
 * http://code.google.com/p/beagleboard/w/list -- many useful wiki pages with various Beagleboard info
 * http://code.google.com/p/beagleboard/wiki/HowToGetAngstromRunning
 * http://code.google.com/p/beagleboard/wiki/BeagleBootHwSetup
 * http://code.google.com/p/beagleboard/wiki/BeagleboardRevC3Validation
 * http://code.google.com/p/beagleboard/wiki/LinuxBootDiskFormat -- formatting/partitioning your SD card
 * http://code.google.com/p/beagleboard/wiki/BeagleBoardDiagnosticsNext -- more booting-into-Linux stuff
 * http://groups.google.com/group/beagleboard/browse_thread/thread/3156ba8903dac3f4 -- How newbie got Ångström demo working
 * http://groups.google.com/group/beagleboard/browse_thread/thread/dd9e7cd7645e2142/13c9ab88acc785a8 -- cross compiling a kernel module for angstrom beagleboard
 * http://groups.google.com/group/openkinect/browse_thread/thread/a04910c5050c3d5f -- OpenKinect and Beagle Board running Angstrom
 * eLinux.org
 * http://elinux.org/BeagleBoard
 * http://elinux.org/BeagleBoardBeginners
 * http://elinux.org/BeagleBoardAndOpenEmbeddedGit
 * Videos
 * http://www.youtube.com/watch?v=FuVwh_VrIxk -- mute the irritating music!
 * http://www.youtube.com/watch?v=zymOmduNWyI -- shows use of GParted to partition SD card
 * Other stuff that is probably useful
 * http://groups.google.com/group/beagleboard/msg/c623a16637625685?hl=en -- some information about Beagleboard GPIO, not as complete as I wish
 * http://www.mulix.org/lectures/intro_to_linux_device_drivers/intro_linux_device_drivers.pdf
 * http://www.mjmwired.net/kernel/Documentation/ -- documents on various aspects of the Linux kernel
 * http://www.win.tue.nl/~aeb/linux/lk/lk.html -- more good Linux kernel stuff
 * http://wiki.openembedded.org/index.php/Getting_Started -- this is probably important
 * http://gigamegatech.com/2010/12/09/beagleboard-xm-and-angstrom-getting-the-big-dog-to-run-at-full-speed/ -- Article by Dan Watts
 * http://www.facebook.com/note.php?note_id=493556979361&comments&ref=mf -- Another Dan Watts article, Beagleboard XM / Angstrom Next Steps: Assigning a Static IP
 * http://www.openismus.com/documents/linux/embedded/beagleboard_getting_started -- Yet another getting-started thing, light on software, but more info never hurts
 * http://processors.wiki.ti.com/index.php/Main_Page -- Texas Instruments has a wiki for their processors
 * http://www.electronsonradio.com/?p=43 -- a little more information
 * http://elinux.org/BeagleBoardBeginners
 * http://code.google.com/p/rowboat/ -- (Android, not Linux)
 * http://www.ibm.com/developerworks/linux/library/l-beagle-board/ -- this has a comfortingly authoritative look to it
 * http://www.tincantools.com/product.php?productid=16134 -- The Flyswatter is a compact USB to JTAG in-circuit debugger and programmer designed for ARM cores. It can be used with all ARM processors that are supported by OpenOCD.  It connects via USB to the host PC.  The Flyswatter provides a standard 14-pin JTAG interface as well as a standard RS232 port with support for full modem signals.
 * http://www.openismus.com/documents/linux/embedded/beagleboard_getting_started
 * http://www.linuxuser.co.uk/features/an-introduction-to-embedded-linux-beagleboard-its-linux-kernel-port/
 * http://code.google.com/p/beagleboard/wiki/BootingBeagleBoard -- looks like some sort of bootloader for BeagleBoard?? Didn't end up using this, afaik