Unaligned access on modern Arm systems

Recently I was asked if it was OK that an Armv7 compiler will generate unaligned 32-bit reads… even when it is “obvious” to the compiler that the read the Arm compiler generates 32-bit unaligned reads. That led to my writing a simple test program to use to explore the compiler options:

#include <assert.h>
#include <stdalign.h>
#include <stddef.h>

struct A {
short s1, s2;
} a;

struct B {
short s;
struct A a;
} b;

void c(void) {
static_assert(alignof(a) == 2);
static_assert(sizeof(a) == 4);
static_assert(alignof(b) == 2);

static_assert(offsetof(B, a) == 2);
static_assert(sizeof(b) == 6);
a = b.a;
}

I added a bunch of static asserts to assist the reader in understanding the structure layout. Once we’ve been through the linking process (which aligns the global) then a = b.a will essentially copy an unaligned 32-bit structure (b.a) into an aligned 32-bit structure. The compiler will use a simple ldr instruction to load the value:

        ldr     r0, [r3, #6]      @ unaligned

… and this is an absolutely fine default for an Armv7 compiler since all Armv7 devices can be configured to support misaligned access in hardware. The only time this should ever be a problem is if you are writing bare-metal code and have forgotten to enable this feature in the bootstrap code… and if that’s you then there the -mno-unaligned-access compiler option to get you out of trouble!

To play more with this idea the just first up the Compiler Explorer and have a poke about.

Share

xpdf is a PDF viewer for GNU/Linux that supports layers

To be honest the title more or less covers it but if you are interested in the back story…

My wife recently picked up a couple of sewing patterns online. In order to cope with the fact that humans do not come in well defined standardized sizing the sewing pattern used a seldom used PDF feature called layers to allow one PDF to contain the outlines for 10 different sizes at the same time.

On the other hand the eventual recipient of the garment in question comes in one excellently defined size making it convenient to disable the unwanted layers and make it easier to cut out the pattern pieces.

Hence we started to look for a PDF reader for GNU/Linux that allows the layers to be enabled and disabled… and the search engines let us down. They either led us down blind alleys of no longer supported editors (together with warnings that they might not support printing) through to Adobe Reader being packaged alongside Wine on an app store in a manner that works (just about) until one tried to print.

We came very close to giving up and asking someone to do it from windows… but then I discovered that the venerable xpdf is still maintained and actively making releases. I knew that xpdf is based on a different PDF library to many of the newer viewers and that it has always had a pretty comprehensive feature set. “It’s a long shot but it might just work” and it did. All that was left to do was churn out a blog post alongside a pithy title that seeks to reeducate the search engines.

xpdf is a PDF viewer for GNU/Linux that supports layers… and has (at least on Fedora 31) a working print button!

Share

Casey Jones the Union Scab

These conversations seem to follow a familiar pattern. Jenny looks up from her tea in order to inform me that someone on the internet needs to know what the tune is for Casey Jones the Union Scab and whether we could help?

Happy to oblige!

I’ve spent a good deal of time over the last 30 years arond campfires singing that “I dreamed I saw Joe Hill last night”. What makes “Casey Jones” to special is that the lyrics were written by Joe Hill himself, parodying “The Ballad of Casey Jones” and reimagining Casey as suffering his misfortune due to his strike breaking.

Arguably the song is not a critique of Casey Jones himself. Even in 1912, only twelve years after his death, other railway engineers were often refered as a “Casey Jones”. The real Casey Jones was in fact a member of two unions and his widow received life insurance payouts from both!

Share

Why Have You Stolen Our Earth

Today thousands of young people walked out their lessons to protest at political inaction over the climate change crisis engulfing us.

It is shameful to hear our politicians blame the students “bunking off” in order to raise awareness of those politicians own failure to act. Anyhow as part of the discussion someone asked us what the tune was for a song called Why Have You Stolen Our Earth because the lyrics seem particular appropriate given today’s news.

Update: This is a song that I’ve only ever heard it passed around at campfires and I wasn’t really sure where it came from. Having posted this I’ve discovered that to listen to the original track then you should track down an album called The Wild Side of Town by the Albion Band with Chris Baines.

Share

Why I spent my Christmas Day building native Arm compilers

My day job involves, among a fairly wide variety of other things, rebuilding compilers. So why did I find myself doing the same thing on my day off?

What I did in my holidays

By Daniel Thompson, aged 40

I had been looking forward to Christmas more then usual this year. In November we bought some drawers with frosted glass fronts and I had been designing a custom lighting system for them in my mind during long hours washing up through most of the pre-Christmas period.

On Christmas day I finally got the chance to hook up my strings of WS2812 LEDs and start hacking. With many LEDs carefully wrapped around and paper clipped a bog roll and with probes dangling off everywhere I decided it was far too fragile to hook up my laptop so I grabbed a spare Dragonboard 410C before carefully balancing everything and connecting it up to my longstanding Cortex-M3 based microcontroller board of choice.

It was only when I tried to do the initial flashing that I realised there was no arm-none-eabi-gdb in Debian Buster/arm64. There’s a cross-compiler but no debugger. Without a second thought I rocked over to download the Arm embedded toolchain from the Arm website but found the cupboard was bare, or as least there were no AArch64 compiler binaries I could use.

After a brief detour of downloading the source code on the DB410C before deciding that building a complex multilib toolchain on a four-core A53 system (with a tiny 8G eMMC) was insane. Shortly afterwards I went upstairs and woke my Developerbox from it’s Christmas afternoon nap (actually it had been napping since I stopped work a few days earlier).​

After wrangling LXC to create the Ubuntu 14.04 container needed for the build I set about trying to recompile the toolchain. Arm’s instructions were awesome and even mentioned how to prevent any attempt to build using mingw32 (which would have been doomed to fail when building on AArch64).

After that there was just enough time for a nice game of Good News, Bad News to complete the holiday period.

Good news: Arm’s instructions worked perfectly and a brand new toolchain emerged from the other end of the sausage grinder.

Bad news: It took my Developerbox over 8 hours to grind through all the builds and as a result I didn’t get to play with my new toys until Boxing Day.

Good news: (Some of) my software worked first time.

Bad news: Except for some apparent toolchain bugs that I haven’t yet had the chance to check (during working hours) to find out if they are AArch64 specific ;-).


Just another day in the life of an Arm-on-Arm developer!

Share

Experimenting with 64k pages for AArch32 code

Someone asked me about 64K pages and the AArch32 ABI again recently. It’s a question that has passed across my desk multiple times and even followed me through multiple companies. Given that long history, and the changes made to the Arm toolchains to ensure freshly built ELF binaries can be loaded, I was interested to see whether Debian 9 (Stretch) armhf userspace would on a machine with 64K pages. I also had access to a Developerbox to help me indulge my curiosity. The short answer is that it is *not* possible to boot Debian Stretch armhf container on a machine with 64k pages because the kernel cannot map the init process… but is only half the story; it really was very close to working!

Continue reading “Experimenting with 64k pages for AArch32 code”

Share

Running an ISO installer image for arm64 (AArch64) using QEMU and KVM

Scattered across myriad blogs around the internet you will find many different ways to boot GNU/Linux for arm64 (a.k.a. AArch64) using QEMU with or without KVM. However, when I recently wanted to quickly spin up a KVM VM on my Developerbox using the Debian Installer ISO images, I couldn’t find any end-to-end instructions. There is lots of great information out there but I had to assemble the fragments myself. Having done that I thought I would share the results…

Continue reading “Running an ISO installer image for arm64 (AArch64) using QEMU and KVM”

Share

Super-cheap replacement bed for a K40 laser cutter

I recently bought a (comparatively) cheap K40 laser engravercutter and am slowly getting to know it, whilst also getting ready to heavily mod it. I have plans to improve (slightly) the cutting area, to add air assist, to replace the controller board and upgrade the bed (pretty much all the usual stuff) and I plan to blog about it as I go.

Laser beams... Laser... Laser... Laser... Yay!

However here at the very beginning of the journey my machine is freshly calibrated and almost, but not quite stock. The bed was causing a few problems, not least that, when cutting large sheet material, the lip of the clamp brought the material too close to the laser. That was easily remedied by unscrewing the clamp and dropping it into the bottom of the machine (its metal, it will be quite safe down there). However the means the cut pieces drop to the bottom of the machine where they are at risk of damage from the laser working overhead… and small pieces can be hard to find because some idiot left a big metal clamp down there.

The solution turned out be a very cheap anti-splater guard for a frying pan. It cost me £1 (since Brexit that’s dropped to about $1.20) from a local discount store and for now I’ve just gaffer taped it to the underside of the existing bed. Since it’s working so well I’m thinking of driving a couple of self tapping screws into a couple of cable clips to hold the frame in place without any sticky residue.

An alternative bed for my K40! It's an anti-splater guard for a frying pan and came from my local pound shop (or, for an international audience my local $1.20 shop). For some basic testing I just taped it to the underside of the existing bed!

This is working great for small items, catching any components that are cut from the middle of the bed and with absolutely no signs of backscatter. Amoung other things I’ve used this simple bed to build a case for my Carbon board (a 96Boards IoT edition micro-controller board) and the results are, I think, pretty awesome.

Laser cut acrylic case for 96Boards IoT edition

So a very, very simple mod but more than enough to allow the whole family to have a bit of fun with our new toy. Whilst its not quite as much fun just to watch I would still invite you to watch the video below showing the cutter creating the case for the Carbon. I find it oddly hypnotic!

Share

Getting started with GStreamer 1.0 and Python 3.x

Way back in the mists of time (or a little over nine years ago if you prefer). Jono Bacon wrote a very detailed blog post describing how to use GStreamer with Python.

Getting started with GStreamer with Python

Mr. Bacon went into a lot of detail, so much so that now, almost ten years later it is still widely credited in other blog posts and remains highly ranked by search engines.

However both Python and GStreamer have moved on a bit over the last decade. The bindings too have moved on a lot as they now use the almost unspeakably awesome PyGObject to automatically generate most of the bindings by introspection.

In short, Jono’s code doesn’t work any more. However it doesn’t take much work to massage the first example until it does.

#!/usr/bin/env python3

import gi
gi.require_version('Gst', '1.0')
gi.require_version('GstBase', '1.0')
gi.require_version('Gtk', '3.0')
from gi.repository import GObject, Gst, GstBase, Gtk, GObject

class Main:
 def __init__(self):
 Gst.init(None)

 self.pipeline = Gst.Pipeline("mypipeline")

 self.audiotestsrc = Gst.ElementFactory.make("audiotestsrc", "audio")
 self.pipeline.add(self.audiotestsrc)

 self.sink = Gst.ElementFactory.make("autoaudiosink", "sink")
 self.pipeline.add(self.sink)

 self.audiotestsrc.link(self.sink)

 self.pipeline.set_state(Gst.State.PLAYING)

start=Main()
Gtk.main()

Roughly speaking “all” we have had to do to update this example:

  1. Update the imports to gather everything we need from the gi module.
  2. Add: Gst.init(None) (this should probably be Gst.init(sys.argv) but that’s not how the original code behaves so it’s not in this port either)
  3. Replace the lowercase g with an uppercase G in both Gst and Gtk.
  4. Tweak the Gst.ElementFactory and Gst.State calls; these were in a flatter namespace in the older PyGst bindings.
  5. Replace alsasink with autoaudiosink. Strictly speaking this is not required; alsasink will still work just fine. However autoaudiosink can adopt pulseaudio when available. Something else that has changed since this code was originally written.

… and that’s it. Not much to it really. Hopefully its enough to set you on your way if you want to grab ideas from old tutorials and blog posts into your own shiny new GStreamer application.

Happy hacking!

Share

How to make a Dragonboard 410c run “headless”

The Dragonboard 410c is a great platform but currently there is a problem with the wireless driver that makes it very hard to run it headless and connect to services running on the board via wifi.

At present the board does not respond correctly to broadcast packets. This results in a number of issues but by far the most significant is that the board cannot reply to ARP requests and this prevents other devices from opening connections to it. From the client machines point of view it knows the board is there, and it can look it up using DNS, but it can’t take the final steps needed to communicate with the board.

In the example below we have a client machine, birch.lan, unable to access dragonboard.lan, because it cannot find the right MAC address.

birch# arp -e
Address         HWtype HWaddress
router.lan      ether  40:ba:fa:xx:xx:xx
dragonboard.lan        (incomplete)
wychelm.lan     ether  fc:aa:14:xx:xx:xx

If only we could get the MAC address into birch’s ARP cache then there would be no problem doing basic network activity like connecting an SSH server. Thankfully there is a fairly easy way to automate this…

Get the Dragonboard to do a nmap ping-sweep of the subnet.

To be clear this is a hack of such huge proportions that it deserves more than just those four letters! It is a bodge, a sticking plaster, a nasty solution stuck together with sticky tape and glue, it does not make me feel warm and snuggly inside… however… it does work.

Not only does it work but it can also be trivially hooked up to systemd so that the device can periodically shout out its presence.

Firstly we need to create a simple service to launch the ping sweep (actually it will be much more like an arping sweep):

#
# /etc/systemd/system/share-mac.service
#
# Running an nmap ARP ping sweep will encourage other
# devices to cache this boards MAC address. This
# works around a problem where the Dragonboard
# 410c does not correctly respond to ARP
# requests.
#
# Note that although nmap's port scanning is
# disabled it remains possible that the host
# discovery protocol (which is not *actually*
# as simple as a ping sweep) may still trigger
# an IDS if run on a corporate network.
# Take care!
#

[Unit]
Description=Send our MAC address to other devices

[Service]
Type=simple
# Change the IP address range as needed...
ExecStart=/usr/bin/nmap -PR -sn -n -e wlan0 192.168.1.1-254

The above service runs just once and it would be enough to get the board noticed after it boots but eventually the other devices would evict the ‘410c from their ARP caches and it would fall off the network again. To solve this we can use a systemd timer to ensure we always keep poking the other devices:

#
# /etc/systemd/system/share-mac.timer
#

[Unit]
Description=Repeatedly send out our MAC address
 
[Timer]
OnBootSec=30
OnUnitActiveSec=3m
Unit=share-mac.service
 
[Install]
WantedBy=multi-user.target

Finally we need to run a few commands on the ‘410c to install nmap and ensure systemd runs the above files:

apt-get update
apt-get install nmap
systemctl enable share-mac.timer
systemctl start share-mac.timer

With these changes in place the ‘410c should announce its existence to all hosts on the network shortly (~30 seconds) after booting and it will repeat the sweep every 5 minutes to ensure the ARP caches stay nice and hot going forward.

The results of the above scripts showed up straight away in birch.lan‘s ARP cache:

birch# arp -e
Address         HWtype HWaddress
router.lan      ether  40:b0:fa:xx:xx:xx
dragonboard.lan ether  02:00:7d:xx:xx:xx
wychelm.lan     ether  fc:aa:14:xx:xx:xx

Share and enjoy!

Update #1 (2016-01-15):  Updated the nmap command with -PR (ensure pure ARP ping sweep), -n (no reverse DNS lookup) and -e wlan0 (only deploy workaround on a specific network interface). Reduced the interval between sweeps from 5 mins to 3 mins to better handle congested networks (10 minutes ARP cache timeouts are common). Thanks to snowbird and ldts-jro for their feedback with this.

Share