Embedded Linux system for Raspberry Pi with Yocto Project

Yocto Project, and OpenEmbedded, have been making news lately as the toolchain to build custom embedded Linux systems. I decided to try and get a working Linux system up and running on a Raspberry Pi.

The procedure that follows uses the meta-raspberrypi BSP in tandem with Yocto Project poky.

Initialize the build by executing the following commands. I use an Ubuntu 14.04 VM with Parallels.

git clone http://git.yoctoproject.org/git/poky
git clone http://git.yoctoproject.org/git/meta-raspberrypi
git clone https://github.com/dv1/meta-gstreamer1.0.git
source poky/oe-init-build-env rpi-build

Append meta-raspberrypi and meta-gstreamer1.0 layers to BBLAYERS in conf/bblayers.conf. For example

  /home/parallels/yocto/poky/meta \
  /home/parallels/yocto/poky/meta-yocto \
  /home/parallels/yocto/poky/meta-yocto-bsp \
  /home/parallels/yocto/meta-gstreamer1.0 \
  /home/parallels/yocto/meta-raspberrypi \

Set MACHINE to raspberrypi in conf/local.conf.

Complete the build by executing

bitbake rpi-hwup-image

That will take a while.

After the build is complete, create an SD card with the following command. Remember to change /dev/sdb to the proper device name.

dd if=tmp/deploy/images/raspberrypi/rpi-hwup-image-raspberrypi.rpi-sdimg of=/dev/sdb

Boot Pi using the SD card. Command line output appears on the HDMI display, or the serial port on the expansion header. Login is root, with an empty password.


Linux NAT routing on Raspberry Pi with Buildroot

This post documents the kernel modules and other packages required to build an embedded Linux NAT router using buildroot, for Raspberry Pi.

Modify Linux kernel configuration

Invoke make linux-menuconfig in buildroot folder to initiate kernel configuration utility. Select modules shown in the figures below.

Networking Options

Network packet filtering framework

Ensure that the following is enabled under Networking Options

  • Network packet filtering framework (Netfilter)

Core Netfilter Configuration

Ensure that the following are enabled under Core Netfilter Configuration

  • Netfilter connection tracking support
  • Netfilter Xtables support (required for ip_tables)
  • “conntrack” connection tracking match support
  • “state” match support

IP: Netfilter Configuration

Ensure following is enabled under Network packet filtering framework (Netfilter)

  • Advanced netfilter configuration

IPv4 packet filtering and NAT

Ensure the following modules are selected under IP: Netfilter Configuration

  • IPv4 connection tracking support (required for NAT)
  • IP tables support (required for filtering/masq/NAT)
  • Packet filtering
  • IPv4 NAT
    • MASQUERADE target support
    • NETMAP target support
    • REDIRECT target support

Enable other targets if you want to do sophisticated filtering.

Modify Buildroot Configuration

Include iptables utility package shown in the figure below, using the configuration utility invoked by executing make menuconfig. Include tcpdump if you want to sniff network data.

Buildroot iptables

Now, just execute make to build the system, and copy the kernel image and root file system to SD card.

Perform NAT routing

I use the following commands to bring up the network interfaces and setup NAT forwarding. Any packets received on interface eth0 are forwarded to usb0. Only packets for connections already established are forwarded back to eth0. usb0 is a USB CDC ethernet interface of the kind seen in modems.

ifconfig usb0 up
ifconfig eth0 up
echo 1 > /proc/sys/net/ipv4/ip_forward
iptables -t nat -A POSTROUTING -o usb0 -j MASQUERADE
iptables -A FORWARD -i usb0 -o eth0 -m conntrack --ctstate ESTABLISHED,RELATED -j ACCEPT
iptables -A FORWARD -i eth0 -o usb0 -j ACCEPT

If you get any of the following error messages with iptables, you are probably missing one of the kernel modules mentioned above

iptables v1.4.21: can't initialize iptables table `nat': Table does not exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.
iptables v1.4.21: can't initialize iptables table `filter': Table does not exist (do you need to insmod?)
Perhaps iptables or your kernel needs to be upgraded.
iptables: No chain/target/match by that name.

If the NAT router is not the default gateway on downstream hosts and routers, you’ll have to setup static routes to relay packets upstream. This can be done using a command such as the following on Mac OS X

sudo route -n add -net

Or, on Linux

route add -net gw

Finally, a couple of useful commands to troubleshoot IP routing and forwarding.

List all rules in iptables

iptables -L -v

Flush all rules in iptables

iptables --flush

A basic packet sniffer

tcpdump -A -i usb0

List all routes

netstat -nr

Network Connection Bridging on Raspberry Pi with Buildroot

This post shows how I add network connection bridging to my custom embedded Linux system for Raspberry Pi. This allows me to experiment with bridging network connections for internet sharing, robustness testing, packet capture, and so on.

Modify Linux kernel configuration

Execute the following in the buildroot folder to get Linux Kernel configuration menu

make linux-menuconfig

Select the 802.1d Ethernet Bridging module shown in the following screenshot

Ethernet Bridging

Modify Buildroot configuration

Execute the following in the buildroot folder to get the configuration menu

make menuconfig

Select the bridge-utils package, shown in the screenshot below. This package contains the brctl utility required to configure bridging.


Then, just execute make to build the system. Once that is done, copy the new kernel image and root file system over to the SD card.

Perform bridging

These are the sequence of commands I typically use to bring up the bridge manually. I use a regular ethernet interface and a USB CDC ethernet interface for testing.

ifconfig eth0 promisc up
ifconfig usb0 promisc up
brctl addbr br0
brctl addif br0 eth0 usb0
ifconfig br0 up

If you need the bridge interface to have an IP address, you can assign one manually, or by invoking the DHCP client daemon as shown below. This is useful if you need to have access to your Pi over the network.

dhcpcd br0

To wrap it up, here’s how you can tear everything down.

ifconfig eth0 down
ifconfig usb0 down
ifconfig br0 down
brctl delbr br0