(Almost) Modern Debian on a Craig CLP281 Netbook — V1

Hardware

Assembled (normal usage)

Craig CLP281 top view, lid up
Craig CLP281 left side view, lid up
Craig CLP281 right side view, lid up
Craig CLP281 back view, lid up

Inventory

  • WonderMedia 8650 SoC
    • ARM 926T (v5) Processor
    • I2C, SPI, and SF interfaces
    • VT85xx-series Graphics
      • Raster Operations Acceleration
      • JPEG, MPEG2, MPEG4, H264 decode acceleration
      • JPEG encode acceleration
    • LCD Backlight
    • Power Management
    • ALSA Audio Codec (Via VT1609)
  • SF flash (8MB x 2)
  • Hynix HY27UBG8T2ATR NAND flash (2GB x 2)
  • 256 MB RAM
  • SD Card Reader
  • USB Keyboard (built-in)
  • USB Touchpad (built-in)
  • Speakers (2)
  • 800x480 pixel LCD display
  • USB 2.0 ports (x3)
  • Headphone and microphone jacks
  • MMA7660 Accelerometer (note that this is unsupported under Debian)
  • Note that built-in audio doesn’t work under Debian due to broken drivers (the GPL kernel tarballs don’t provide working drivers).

Requirements for Booting Debian

Booting from SD Card is the Easiest Option

Advanced users could modify the u-boot environment to boot an embedded operating system running directly from the 4GB NAND flash, but that is beyond what most users want to get into. Therefore we first describe booting from SD card which is less risky.

Only Available Kernel Too Old for New Debian (or other Linux)

The only available kernel (due to proprietary drivers for which no source code was released) is a 2.6 series kernel. That means the newest Debian that can run on these devices is Debian 7 (Wheezy), without extensive patching. Wheezy was the stable release three generations ago. (New Debian fails to boot, due to depending on systemd, and systemd depending on features not available in the 2.6 kernel). A future article may discuss using a newer version of Debian after applying most of patches from CentOS 6 (which is/was based on a 2.6.32 kernel).

Wheezy was EOL (End of Life) in April 2016, but had LTS (Long Term Service) updates until about May 2018. It has ELTS (Extra Long Term Service) until December 2019. This means means for some years only some packages have been getting updates, and soon there will be no updates at all. On the other hand the version of Android on this device is far older. For that reason I still consider a Wheezy install to be more secure (at least for userspace) than an Android firmware which was last updated in the 2011 to 2012 time frame. In my opinion Wheezy also has more features for a netbook device than Android.

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 parition 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 FAT32 Boot Partition

The first partition on the SD card needs to be a FAT32 parition. It doesn’t have to be very big — a 30MB partition is more than sufficient. The parition 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

display init force
mmcinit 0
fatload mmc 0 0x0 uzImage.bin
setenv bootargs mem=${memtotal} root=/dev/mmcblk0p2 noinitrd rw rootfstype=ext2 console=ttyS0,115200n8 console=tty1 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

For those who want to do a quick test I give you a prebuilt WonderMedia 8650 2.6 kernel and module tarball for the Craig CLP281 that ought to be Wheezy-ready or a prebuilt WonderMedia 8650 2.6 kernel and module debian package for the Craig CLP281 Really, you shouldn’t rely on a random kernel from a random stranger for your final system (and it is experimental and comes with no warranties of any kind either express or implied; if it eats your kittens, your children, or your data, it’s not my fault). Therefore I provide the following instructions on how to build the kernel yourself.

Obtain the Craig CLP281 Kernel Source Code and Build System

git clone -b wmcshore-1.0 --depth 1 --recurse-submodules https://github.com/cshoredaniel/wm8650-2.6-reference-kernel-build.git --shallow-submodules  wm8650-linux-2.6

Build the Kernel

Wheezy was the stable release three generations ago. (New Debian fai

  1. Set up your cross-compilation environment (e.g. Debian Jessie for Armel Cross-Compilation in a Docker Container) NB: This can’t be any newer than Debian Jessie because various tools (like Perl) have changed from the 2.6 kernel’s build system.
    1. You will likely need to set up a chroot, container, or full virtual machine in order to do the build.
    2. Since Debian Jessie doesn’t include cross-compilation toolchains, you will either need to get or build a toolchain (such as the Android NDK), or you will need to use some type of virtualization and build under an armel emulator.
  2. Enter the cross-compilation environment (if not already there). Here we use Debian Jessie for Armel Cross-Compilation in a Docker Container)
    1. Change to the directory in which you cloned the kernel source code, above (e.g. wm8650-linux-2.6)
    2. docker run -it -v $(pwd):/home/builder/Build jessie-cross-armel:latest bash. NB If you used a different username when building the suggested cross-compilation environment use that instead of builder.
  3. Make sure that your PATH is pointing to you cross-compilation tools and that they are prefixed with ‘arm-linux-gnueabi-’ (e.g. /path/to/your/toolchain/bin/arm-linux-gnueabi-gcc). If that is not the case you will need to set your PATH and supply the appropriate CROSS_COMPILATION=your-compiler-prefix make flag for all make commands below. For the suggested environment, this should already be true.
  4. Modify the config if you wish (but note that most configs won’t work and the released config which you got by cloning above is known to work).
    1. You can use make menuconfig and make backports-menuconfig to modify the kernel and backports modules (basically wireless).
  5. Build the kernel, modules, and create a debian package as well as a tarball containing the kernel and modules.
    1. make J=X all (make will automatically do as much parallelism as possible). On a fast machine this could be done in 3-4 minutes.
  6. Exit the cross-compilation environment.
  7. You should have linux-image-*.deb package in the, as well as linux-2.6.*.tar.bz2.

Build Or Obtain a Debian Wheezy Rootfs

For those who want to do a quick test I give you a prebuilt Debian Wheezy rootfs tarball (expects to be extracted to an ext4 format, preserving ownership and permissions, and needs a kernel) for the Craig CLP281. You really shouldn’t rely on a random rootfs from a random stranger for your final system though (and it is experimental and comes with no warranties of any kind either express or implied; if it eats your kittens, your children, or your data, it’s not my fault).

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.

What the Script Does

Create the Base System

  1. sudo apt-get install qemu-user-static
  2. mkdir -p clp281-root/root
  3. Copy the debian kernel package into clp281/root
  4. sudo debootstrap --arch=armel --foreign wheezy "$(pwd)"/clp281-root http://archive.debian.org/debian/
  5. cp /usr/bin/qemu-arm-static clp281-root/usr/bin
  6. sudo PATH=/bin:/sbin:/usr/bin:/usr/sbin /sbin/chroot clp281-root /usr/bin/qemu-arm-static /bin/bash
  7. export LANG=C.UTF-8
  8. 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 Debian Wheezy install).
  9. /debootstrap/deboostrap --second-stage
Prepare the Base System for First Boot

Assuming you are still in the chroot:

Follow the rest of the instructions at https://www.debian.org/releases/stable/armel/apds03.en.html#idm3769 (more details below).

  1. mount -t proc proc /proc

  2. apt-get install makedev

  3. cd /dev

  4. MAKEDEV generic

  5. Create /etc/fstab, for example (for virtualization):

    # /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
    
  6. 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
    
  7. Install package for better handling of dns resolver configuration

    1. apt-get install resolvconf
  8. Set the system hostname

    1. echo wheezy-clp281 > /etc/hostname
  9. Add more available packages and make sure we’re up to date:

    1. Update /etc/apt/sources.list. For example:

      deb http://archive.debian.org/debian wheezy main contrib non-free
      deb-src http://archive.debian.org/debian wheezy main contrib non-free
      deb http://archive.debian.org/debian-security wheezy/updates main contrib non-free
      deb-src http://archive.debian.org/debian-security wheezy/updates main contrib non-free
      deb http://archive.debian.org/debian wheezy-backports main contrib non-free
      deb-src http://archive.debian.org/debian wheezy-backports main contrib non-free
      
    2. apt-get update && apt-get upgrade

  10. 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).
  11. Add a new user with administrative access (i.e. root)

    1. apt-get install sudo
    2. adduser clp281
    3. adduser clp281 sudo
  12. Make sure we start with the full set of standard packages for a Debian minimal install (no desktop).

    1. tasksel install standard
  13. 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
  14. Do some clean up:

    1. apt-get clean
    2. Stop automatically started processes:
      1. /etc/init.d/rpcbind stop || true
      2. /etc/init.d/nfs-common stop || true
      3. /etc/init.d/rsyslog stop
      4. /etc/init.d/cron stop
      5. /etc/init.d/atd stop
      6. /etc/init.d/exim4 stop
      7. pkill -TERM rsyslogd
  15. 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 craig-clp281 directory.

  2. Copy the script below to create-wheezy-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-wheezy-armel-clp281.sh

    #!/bin/bash
    
    apt-get install qemu-user-static
    mkdir -p clp281-root/root
    cp linux-image-*.deb clp281-root/root/
    debootstrap --arch=armel --foreign wheezy "$(pwd)"/clp281-root http://archive.debian.org/debian/
    
    cat >clp281-root/root/prepare-debian-rootfs.sh <<EOF
    #!/bin/bash
    
    export LANG=C.UTF-8
    export TERM=xterm-color
    /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.debian.org/debian wheezy main contrib non-free
    deb-src http://archive.debian.org/debian wheezy main contrib non-free
    deb http://archive.debian.org/debian-security wheezy/updates main contrib non-free
    deb-src http://archive.debian.org/debian-security wheezy/updates main contrib non-free
    deb http://archive.debian.org/debian wheezy-backports main contrib non-free
    deb-src http://archive.debian.org/debian wheezy-backports 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
    /etc/init.d/rpcbind stop || true
    /etc/init.d/nfs-common stop || true
    /etc/init.d/rsyslog stop || true
    /etc/init.d/cron stop || true
    /etc/init.d/atd stop || true
    /etc/init.d/exim4 stop || true
    pkill -TERM rsyslogd || true
    sleep 2
    umount /proc
    EOF
    
    chmod 755 clp281-root/root/prepare-debian-rootfs.sh
    cp /usr/bin/qemu-arm-static clp281-root/usr/bin
    PATH=/bin:/sbin:/usr/bin:/usr/sbin /sbin/chroot clp281-root /usr/bin/qemu-arm-static /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 /usr/bin/qemu-arm-static /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 /usr/bin/qemu-arm-static /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 filessystem 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://github.com/cshoredaniel/torvalds-linux.
  6. The build system from the GPL reference tarball above has been modified and stored in the https://github.com/cshoredaniel/wm8650-2.6-reference-kernel-build.git.
  7. A working configuration for the kernel and backports is located in the git repository at https://github.com/cshoredaniel/linux-2.6-wm8650-configs.