David Madore's WebLog: More mess: after the GuruPlug, the DreamPlug

Index of all entries / Index de toutes les entréesXML (RSS 1.0) • Recent comments / Commentaires récents

Entry #2016 [older|newer] / Entrée #2016 [précédente|suivante]:

(Sunday)

More mess: after the GuruPlug, the DreamPlug

One of my recurring, probably never-to-be-achieved, dreams, is to own a small, completely noiseless PC that I could leave running 24/7/365 for use as a router, Wifi access point, and server for some basic services (such as NTP and DNS), so as to turn off—or at least, suspend—my main desktop PC at night. The current fad in this area is currently the Raspberry Pi, which is undoubtedly a wonderful gadget, and I'll probably get one eventually, but it doesn't quite match my criteria. (As a matter of fact, there are zillions of similar embedded devices which come quite close to what I want, but never actually there. One of my more outrageous demands is that I want two gigabit Ethernet connectors plus Wifi, and that's where mostly everything fails, except for a few things which are build for use as switches but then they don't satisfy me for other reasons.)

My last attempt at substantiating this dream came in the form of the GuruPlug by GlobalScale Technologies. But I was pretty pissed off when it turned out that the gadget, while it matched my more difficult criteria (dual gigabit Ethernet plus Wifi, eSATA, yada yada) utterly failed in the simple but crucial condition of being silent. Seems it was a design error: they had hoped to make it fanless, but it was found to overheat, and they added the fan ex post facto, making the dang thing pretty much pointless. So, I have two of these GuruPlugs Server ExtraNoisy Deluxe on my hands and I still haven't found any use for them.

Well, later GlobalScale came to realize the evil of its ways and amended them by releasing a new product, the DreamPlug. It differs from its older sibling in two important respects: (1) this time it is truly fanless, hence noiseless, and (2) the internal NAND memory used for permanent storage has been replaced by a removable µSD card, making the device easier to unbrick[#] in case something goes wrong. I resisted buying this DreamPlug for some time, because I was really annoyed by the fiasco of my previous purchase at GlobalScale, but in the end resistance was futile and I bought myself a pair of DreamPlugs. They were delivered to me on Monday.

Well, I have no gripes with the hardware, now: the DreamPlug is, indeed, completely silent, and from what I have seen so far, it seems to work well. No gripes apart from the general fact that the ARM architecture is a chaotic mess: there seem to be a zillion kinds of ARMs, each with a zillion subtypes and sub-subtypes. And as a consequence of this fragmentation, I ran into a number of software problems which I may or may not be able to solve (but which will probably solve themselves on their own: that's the nice thing about software problems as opposed to hardware ones).

The DreamPlug comes with a Linux distro which is essentially Debian with a custom kernel, including a number of custom drivers (essentially for Wifi), and a custom bootloader. And a number of hastily bundled scripts which were installed by raping the Debian package manager with gravel. Anyway. It works. But I hate badly customized distros and customized kernels, so I'd like to reinstall a fresh Debian (or Ubuntu) on the box. But it's not that simple.

The bootloader (also serving some kind of BIOS functions) used to boot Linux on the ARM architecture is something known as U-Boot. Now Marvell provides a specifically patched U-Boot for this device, which has some annoying limitations, such as not being able to load files from ext2 filesystems: so I thought I'd try a more recent U-Boot provided by Debian (u-boot_2011.12-2_armel.deb), and which is said to support the DreamPlug. Reflashing U-Boot is ridiculously complicated (one takes control of the machine through JTAG using the OpenOCD program, but unfortunately OpenOCD cannot directly flash the particular kind of nonvolatile memory used on the DreamPlug — as opposed to the GuruPlug — so one must go through a strange process of loading the new U-Boot to RAM, booting it there, and using U-Boot itself to reflash itself); but I managed it. However, (1) the U-Boot taken from Debian is incapable of booting the kernel provided by Marvell (it just gets stuck after Uncompressing Linux... done, booting the kernel.), and (2) the Debian kernels for Kirkwood apparently do not support the DreamPlug (as such, they refuse to boot, complaining that they don't know the machine identifier 0xdde; and if I try to trick them in using identifier 0xa63 which is that of the GuruPlug, they fail a bit later on).

So Marvell must have patched both their U-Boot bootloader and kernel in a way that each is compatible only with the other. The details escape me, though it is obviously must have something to do with the annoying mechanism of machine identifiers used by the ARM architecture. And whatever the excuse of ARM being fucked up in the first place, Marvell must have fucked it up some more for their Linux kernel to be unbootable by a standard U-Boot (conversely, their patched U-Boot is said to be able to boot standard kernels, but only with a special option mainlineLinux option and by fiddling with the machine identifier): what a mess! And the enormity of having to use a specific bootloader to load a specific kernel is such that it defeats the whole purpose of a bootloader, namely: to boot more than one kernel.

I thought I'd step out of the mess by avoiding any Marvell patches altogether and using a recent mainline kernel to boot with the standard U-Boot. And when I say recent, I mean essentially today's snapshot of the ARM SoC tree (merged with the 3.3.0-rc7 fixes from the Linux tree). It is supposed to support the DreamPlug, according to this commit (and a couple of later ones): I really don't know why support for a device that has been commercialized for well over a year has only begun finding its way in the kernel a few weeks ago; but unfortunately another problem is that said support is taking the form not of recognizing the infamous machine ID (0xdde) but using something known as a flattened device tree which is a kind of machine description file: only this requires an even newer U-Boot, and it seems I have entered a world of pain.

So in the end, I wasted more than five hours first creating an ARM cross-compiler[#2] and then tediously configuring the kernel (the number of choices to be made is frightening; and even by merging several known configurations it was still a pain in the ass) to get a kernel that simply does not boot and I have no idea why (the most useful message I elicited from it was: Kernel panic - not syncing: ERROR: Failed to allocate 0x1000 bytes below 0x0. — and that's with Marvell's U-Boot because with the standard one it didn't even get that far).

The moral of this is that I probably should have stuck with the working system provided by Marvell, but I still hate it and hate the idea that the system needs specific patches to function. And judging by the patch needed to provide master mode support on the Wifi chipset (which is so obviously a badly fangled port of a Windows driver), I'd like to stay clear of any code of this sort.

The dust will settle eventually, I guess, and maybe someday Linux will run correctly on a device that was, after all, specifically made to run Linux. But in the mean time, I can't say its performance has been brilliant.

[#] Remind me to rant someday about the fact that it ought never to be possible to brick an electronic device of any kind by purely software means.

[#2] In case it's of value to anyone, here's more or less what I did:

mkdir /opt/arm-linux-gnueabi
mkdir /opt/arm-linux-gnueabi-tools
dpkg-deb -x libc6_2.13-27_armel.deb /opt/arm-linux-gnueabi
dpkg-deb -x libc6-dev_2.13-27_armel.deb /opt/arm-linux-gnueabi
dpkg-deb -x linux-libc-dev_3.2.6-1_armel.deb /opt/arm-linux-gnueabi
(cd /opt/arm-linux-gnueabi/usr ; tar cf - *) | (cd /opt/arm-linux-gnueabi ; tar xf -)
rm -rf /opt/arm-linux-gnueabi/usr
ln -s . /opt/arm-linux-gnueabi/usr
cd /tmp ; apt-get source binutils
cd binutils-2.22
./debian/rules patch
mkdir /tmp/binutils-build
cd /tmp/binutils-build
/tmp/binutils-2.22/configure --target=arm-linux-gnueabi --prefix=/opt/arm-linux-gnueabi-tools --enable-shared --enable-plugins --with-sysroot=/opt/arm-linux-gnueabi
make -j4 && make install
cd /tmp ; apt-get source gcc-4.6
cd gcc-4.6-4.6.3
DEB_CROSS_NO_BIARCH=yes ./debian/rules patch
mkdir /tmp/gcc-build
cd /tmp/gcc-build
/tmp/gcc-4.6-4.6.3/src/configure --target=arm-linux-gnueabi --prefix=/opt/arm-linux-gnueabi-tools --with-sysroot=/opt/arm-linux-gnueabi --enable-languages=c
make -j4 && make install

↑Entry #2016 [older|newer] / ↑Entrée #2016 [précédente|suivante]

Recent entries / Entrées récentesIndex of all entries / Index de toutes les entrées