Craig CLP281: Devuan Almost Saves the Day

craig arm-based netbook running debian

This is a follow on article for (Almost) Modern Debian on a Craig CLP281 Netbook — V1

Only Available Kernel Limits Age of Linux that Can Be Used

As mentioned, the only available kernel (due to proprietary drivers for which no source code was released) is a 2.6 series kernel. That is incompatible with core operating software known as glibc (at least as low as) 2.4. In addition a common software component known as ‘systemd’ requires features not in the 2.6 series kernel. Because of that the newest Debian that can run on these devices is Debian 7 (Wheezy), without extensive patching.

We can get to a slightly newer version of Linux that is based on Debian using a distribution that uses much of Debian, but has diverged from Debian over concerns with the ‘systemd’ requirement. That distribution is known as Devuan (Dev 1).

Using Devuan one can get one additional distribution ‘generation’ closer to current. That version of Linux is known as Devuan ‘Jessie’ and is based on Debian Jessie (ca. 2018).

This article is the last in the series for the Craig CLP281 as it is clearly a dead end, and I would not trust a kernel getting no security updates while using a ‘userspace’ that is also getting no security (or any other) updates to do anything real.

No only that that but the Craig CLP281 is not exactly the most powerful and useful hardware, even from 2011. If the makers of this device had made the source code available, and the support for the hardware in the device worked with newer kernels there would be at least some value in continuing to tinker with the device (in that case it would be a useful platform for trying out techniques for doing ‘modern’ things with very little computing power, including ‘debloating’ and improving things like very lightweight graphical desktops).

So, for completeness sake, here is how to get Devuan Jessie running on a Craig CLP281. (Note that the article Replace Android with Debian on a Craig CLP281 Netbook can be applied to the Devuan situation with only minor changes, so I won’t be writing a followup of that article).

Booting from SD Card

The WonderMedia devices are generally configured to boot from an SD card if one is present. Different generations of devices look for a U-Boot script in different places. In the case of the Craig CLP281, if:

  1. An SD card is present on boot
  2. The first partition of the SD card is formatted as FAT32
  3. A U-Boot script named wmt_scriptcmd is present in the root of the first partition.

then that script will be executed on boot. This allows us to take over the boot process and boot Debian instead of Android. We can do this without modifying the firmware (the Android OS on the flash memory built into the device).

Partition an SD Card with a FAT16 Boot Partition

The first partition on the SD card needs to be a FAT16 partition. It doesn’t have to be very big — a 30MB partition is more than sufficient. The partition only needs to hold the U-boot script and a suitable linux kernel. Also note the partition table type needs to be msdos not GPT.

Other Partitions

The SD Card should also have a partition for the root filesystem and a partition for swap. For this guide we will assume swap on on partition 2 and the rootfs on partition 3.

An Example U-Boot Script for SD Card Booting

2020-11-26 02:01:10 EST: Corrected errors in wmt_scriptcmd.src

display init force
mmcinit 0
fatload mmc 0 0x0 uzImage.bin
setenv bootargs mem=${memtotal} root=/dev/mmcblk0p3 noinitrd rw rootfstype=ext4 console=tty1 console=ttyS0,115200n8 lpj=${lpj} ${platform_bootargs} init=/sbin/init quiet rootdelay=3
bootm 0x0

Assuming you are on a Debian system, and have u-boot-tools installed and this script is named wmt_scriptcmd.src then execute:

mkimage -A arm -O linux -T script -C none -n "Boot Debian" -a 0 -e 0 -d wmt_scriptcmd.src wmt_scriptcmd

Finally, copy wmt_scriptcmd to the root of the FAT32 partition on your SD card.

Build or Obtain a Suitable Kernel

I’ve covered that a number of times in this series so I won’t repeat here.

Build a Devuan Jessie Rootfs

To create your own rootfs, use the script below. Of course you should read the script and verify it won’t destroy the planet, your computer, or your data before executing it.

WARNING: Due to https://bugs.launchpad.net/qemu/+bug/1805913 images built on non-ARM hosts are broken on at least Debian Buster and at least one version of Ubuntu (other distros may also be broken for some versions). As a consequence this article assumes one is using an ARM HF Virtual Machine or a physical ARM system (such as a Raspberry Pi).

What the Script Does

Prerequisite

  1. Obtain Devuan version of debootstrap.
    1. git clone https://git.devuan.org/devuan/debootstrap.git
  2. Make sure the system can find it:
    1. export DEBOOTSTRAP_DIR=$(pwd)/debootstrap

Create the Base System

  1. mkdir -p clp281-root/root
  2. Copy the debian kernel package into clp281/root
  3. sudo debootstrap --arch=armel --foreign jessie "$(pwd)"/clp281-root http://archive.devuan.org/merged/ jessie
  4. export LANG=C.UTF-8
  5. Depending on what terminal you are using, you may need to also do: export TERM=xterm-color. (This is only required if your terminal is not supported by a default Devuan Jessie install).
  6. Enter the new root as a chroot
    1. sudo chroot clp281-root /bin/bash
  7. /debootstrap/deboostrap --second-stage
Prepare the Base System for First Boot

Assuming you are still in the chroot:

mount -t proc proc /proc

apt-get install makedev

cd /dev

MAKEDEV generic

Create /etc/fstab, for example:

# /etc/fstab: static file system information.
#
# file system    mount point   type    options                 dump pass
/dev/mmcblk0p3   /             ext2    defaults,relatime       0    1
/dev/mmcblk0p1   /boot         vfat    defaults,nosuid,nodev,relatime 1    2
/dev/mmcblk0p2   none          swap    sw                      0    0
proc             /proc         proc    defaults, relatime      0    0
  1. Create /etc/network/interfaces, for example:
######################################################################
# /etc/network/interfaces -- configuration file for ifup(8), ifdown(8)
# See the interfaces(5) manpage for information on what options are
# available.
######################################################################

# The loopback interface isn't really required any longer, but can be used
# if needed.
#
auto lo
iface lo inet loopback

# To use dhcp:
#
auto eth0
iface eth0 inet dhcp

# An example static IP setup: (network, broadcast and gateway are optional)
#
# auto eth0
# iface eth0 inet static
#     address 192.168.0.42
#     network 192.168.0.0
#     netmask 255.255.255.0
#     broadcast 192.168.0.255
#     gateway 192.168.0.1

# Include files from /etc/network/interfaces.d:
source-directory /etc/network/interfaces.d
  1. Install package for better handling of dns resolver configuration
    1. apt-get install resolvconf
  2. Set the system hostname
    1. echo dev1jessie-clp281 > /etc/hostname
  3. Add more available packages and make sure we’re up to date:
    1. Update /etc/apt/sources.list. For example:

      deb http://archive.devuan.org/merged jessie main contrib non-free
    2. apt-get update && apt-get upgrade
  4. Handle some basic configuration:
    1. apt-get install locales && dpkg-reconfigure locales
    2. apt-get install console-setup && dpkg-reconfigure keyboard-configuration
    3. passwd root (repeat until successfully set; it can fail if you don’t type the password identically both times).
  5. Add a new user with administrative access (i.e. root)
    1. apt-get install sudo
    2. adduser clp281
    3. adduser clp281 sudo
  6. Make sure we start with the full set of standard packages for a Debian minimal install (no desktop).
    1. tasksel install standard
  7. Install and configure the kernel:
    1. dpkg -i root/linux-image-*.deb (there should be only one .deb)
    2. depmod [your-kernel-version]
    3. rm -f root/linux-image-*.deb
  8. Do some clean up:
    • apt-get clean
  9. Clear mounts and exit
    1. umount /proc
    2. exit

Using a Script

NB: The script is interactive and you will be prompted at some points. If you’re looking for complete automation you will need to modify the script appropriately.

  1. Change out of the kernel build directory and create and enter a new clp281-root directory.
  2. Copy the script below to create-jd1-armel-clp281.sh in that directory.
  3. Copy the appropriate linux-image-*.deb to that directory as well, and make sure there is only one linux-image-*.deb there.
  4. sudo bash -c create-jd1-armel-clp281.sh
#!/bin/bash

DEBOOTSTRAP_DIR="$(pwd)/debootstrap"
export DEBOOTSTRAP_DIR
mkdir -p clp281-root/root
cp linux-image-*.deb clp281-root/root/
debootstrap --arch=armel --foreign jessie "$(pwd)"/clp281-root http://archive.devuan.org/merged/ jessie
cat >clp281-root/root/prepare-debian-rootfs.sh <<EOF
#!/bin/bash

export LANG=C.UTF-8
export TERM=xterm-color
unset DEBOOTSTRAP_DIR
export DEBOOTSTRAP_DIR
/debootstrap/debootstrap --second-stage
mount -t proc proc /proc
cd /dev
apt-get -y install makedev
MAKEDEV generic

cat >/etc/fstab <<FSTABEOF
# /etc/fstab: static file system information.
#
# file system    mount point   type    options                 dump pass
/dev/mmcblk0p3   /             ext2    defaults,relatime       0    1
/dev/mmcblk0p1   /boot         vfat    defaults,nosuid,nodev,relatime 1    2
/dev/mmcblk0p2   none          swap    sw                      0    0
proc             /proc         proc    defaults, relatime      0    0
FSTABEOF

cat >/etc/network/interfaces <<IFACEEOF
######################################################################
# /etc/network/interfaces -- configuration file for ifup(8), ifdown(8)
# See the interfaces(5) manpage for information on what options are
# available.
######################################################################

# The loopback interface is not really required any longer, but can be used
# if needed.
#
auto lo
iface lo inet loopback

# To use dhcp:
#
auto eth0
iface eth0 inet dhcp

# An example static IP setup: (network, broadcast and gateway are optional)
#
# auto eth0
# iface eth0 inet static
#     address 192.168.0.42
#     network 192.168.0.0
#     netmask 255.255.255.0
#     broadcast 192.168.0.255
#     gateway 192.168.0.1

# Include files from /etc/network/interfaces.d:
source-directory /etc/network/interfaces.d
IFACEEOF

apt-get -y install resolvconf
echo wheezy-clp281 >/etc/hostname

cat >/etc/apt/sources.list <<SRCEOF
deb http://archive.devuan.org/merged jessie main contrib non-free
SRCEOF

RET=1
while [ "\$RET" != "0" ]; do
        passwd root; RET="$?"
done
apt-get update && apt-get -y upgrade
apt-get -y install locales && dpkg-reconfigure locales
apt-get -y install console-setup && dpkg-reconfigure keyboard-configuration
apt-get -y install sudo
tasksel install standard
dpkg -i /root/linux-image-*.deb
# This only works because we are starting with a fresh rootfs
kver="\$(cd /lib/modules && ls -A | head -n1)"
depmod "\$kver"
rm -f /root/linux-image-*.deb
apt-get clean
umount /proc
EOF

chmod 755 clp281-root/root/prepare-debian-rootfs.sh
PATH=/bin:/sbin:/usr/bin:/usr/sbin /sbin/chroot clp281-root /bin/bash -c /root/prepare-debian-rootfs.sh || {
  echo "Failed to chroot; can't create rootfs"
  exit 1
}

echo "Done. Created rootfs."

Add Additional Packages

  1. sudo /sbin/chroot clp281-root /bin/bash
  2. mount -t proc proc /proc
  3. Use apt-get and/or tasksel to install more packages (for example, a desktop environment).
  4. Perform any other pre-boot configuration.
  5. exit

Copy the Rootfs to the SD Card

Create an Empty Filesystem on the Rootfs Partition

  1. sudo /sbin/chroot clp281-root /bin/bash
  2. mount -t proc proc /proc
  3. If your SD card is mounted on /dev/mmcblk0 and you are using swap on partition 2 and rootfs on partition 3, then:
    1. mkswap /dev/mmcblk0p2
    2. mkfs.ext4 -L ROOT /dev/mmcblk0p3
  4. umount /proc
  5. exit

Copy the Rootfs you created to the Rootfs Partition

  1. sudo mount /dev/mmcblk0p3 /mnt
  2. sudo mount /dev/mmcblk0p1 /mnt/boot
  3. sudo rsync -arDltx --info=progress2 clp281-root/ /mnt/ && sync

Final Steps

  1. sudo umount /mnt/boot
  2. sudo umount /mnt
  3. Remove SD Card from you computer and place it in the CLP281 SD card slot.
  4. Boot the CLP281 with Debian Wheezy for the first time.
  5. If you are using the prebuilt root filesystem then the root password is password. CHANGE THE PASSWORD ASAP.
  6. Configure Debian with a desktop and desired software, etc.
  7. Enjoy!

Useful information

Original Sources for the Kernel Git Repositories

Older projectgus WonderMedia 8650 GPLTarball — incomplete or Local copy of older projectgus WonderMedia 8650 GPL tarball — Incomplete

Newer Android WonderMedia 8650 GPL source or Local copy of newer Android WonderMedia 8650 GPL tarball

Linux Backports 3.18.1-1 tarball or Local copy of Linux Backport 3.18.1-1 tarball

You need to make sure the patches you apply and the base kernel source are using the same line endings by using a tool such as dos2unix or unix2dos as the source files have a mix of line endings.

Neither tarball is the exact kernel source for the binary that shipped with the CLP281 but the newer one is close enough to get the job done. For the tarball based on slightly older Android, not all drivers are working (e.g. sound and battery, at least, are broken).

Patches From Various Sources

In order to run Debian 7 (Wheezy), the following patches to the provided kernel are required (patches use Unix style line endings (LF) unless otherwise noted):

  1. Patch the kernel so the the kernel build creates modules.builtin. (See https://patchwork.kernel.org/patch/50131/raw/ or Local copy of make kernel build generate modules.builtin)
  2. Patch various drivers (bug fixes). (See https://download943.mediafire.com/p33g2o6n2isg/28xor4fr7ws1c11/wm8650_netbook.patch or Local copy of WM8650 GPL Tarball Driver Bug Fixes). Note the local copy uses Unix line endings (LF) but the patch on mediafire uses Windows line endings (CRLF).
  3. Patch to add sys_accept4() (required for udev). See Local copy of backport: wire up sys_accept4() on ARM, or (but needs adjustment to work with this version of the kernel) backport: wire up sys_accept4() on ARM.
  4. Patch to create /sys/fs/cgroup mountpoint. (See https://github.com/kelvinlawson/meta-kirkwood/blob/master/recipes-kernel/linux/files/0001-cgroupfs-create-sys-fs-cgroup-to-mount-cgroupfs-on.patch) or Local copy of cgroupsfs: create /sys/fs cgroup to mount cgroupfs on
  5. There are a number of patches only found in the v2.6.39/standard/wm8650-cshore branch of the Git repository located at https://git.danielfdickinson.ca/linux-kernel/torvalds-linux.
  6. The build system from the GPL reference tarball above has been modified and stored in the https://git.danielfdickinson.ca/linux-kernel/wm8650-2.6-reference-kernel-build.git.
  7. A working configuration for the kernel and backports is located in the git repository at https://git.danielfdickinson.ca/linux-kernel/linux-2.6-wm8650-configs.

By Daniel F. Dickinson

Daniel Dickinson has been using and exploring computer and electronic technologies for over three decades. He is proficient with various flavours of Linux (including varieties of desktop, server, and embedded systems) as well as modern Windows. Daniel still enjoys software and firmware development, but prefers integration and extending existing open source solutions to quickly achieve desired goals. Fo more details see https://www.wildtechgarden.com/about/about-daniel-f

Leave a comment

Your email address will not be published. Required fields are marked *