In this post, I will try to install linux on a q8 (Allwinner A13 based) tablet. Multiple people have already succeeded in running debian/arch on the tablet, so it must be possible.

The q8 tablet

The q8 tablet is a cheap chinese android tablet that runs Android 4.1.

The q8 tablet, starting Android 4.1

Looking at a page on linux-sunxi.org, I believe I have the q88 variant of the tablet. I’m not sure about this though. This blogpost will use the terms q8 and q88 interchangeably.

The “about tablet” section in Android

There are tablets that look similar, but have a different Allwinner SoC. The one I have, happens to have an Allwinner A13 SoC inside it:

The insides of the tablet

The battery looked like it was about to explode, so I removed it. Just imagine a battery being next to the board.

The process

To create a new linux OS for the tablet, I followed a checklist:

  • Is there a crosstool-ng defconfig for the CPU/SoC? There seems to be, arm-cortex_a8-linux-gnueabi exists.
  • Is there a mainline u-boot defconfig for it? Is it even supported by u-boot? It seems to be supported, q8_a13_tablet_defconfig exists.
  • Is there a mainline linux defconfig for it? It is even supported by linux? It seems to be supported, sunxi_defconfig exists.
    • If yes, does the linux source provide a .dtb file after I built the kernel?
  • Is there a buildroot defconfig for it? No, buildroot doesn’t seem to support this anchient piece of technology.
    • If yes, does it provide me with an .img file after it’s done building? No.

Creating a cross compiler toolchain

Just like in some of my previous posts, I will once again build a cross compiler toolchain.

Getting crosstool-NG

git clone https://github.com/crosstool-ng/crosstool-ng
./bootstrap # crosstool-NG is cloned from github
./configure --enable-local
make

Creating a toolchain for the Allwinner A13

The Allwinner A13 uses a Cortex A8, so the toolchain will have to support that processor type. Luckily, there is one.

To build the toolchain for the Allwinner A13 Soc:

./ct-ng arm-cortex_a8-linux-gnueabi
./ct-ng build

The folder /home/$USER/x-tools/arm-cortex_a8-linux-gnueabi/ should now exist. To verify this:

$ ls ~/x-tools/
arm-cortex_a8-linux-gnueabi

Building u-boot

In this post, the mainline u-boot will be used.

Getting u-boot

If it works, mainline u-boot will be used. It will be downloaded directly from github:

git clone https://github.com/u-boot/u-boot.git

Building u-boot for the q8 tablet:

cd u-boot
export ARCH=arm
export CROSS_COMPILE=/home/$USER/x-tools/arm-cortex_a8-linux-gnueabi/bin/arm-cortex_a8-linux-gnueabi-
make q8_a13_tablet_defconfig
make menuconfig # to change the boot timeout, if desired
make

The u-boot folder should now contain some more files. To verify:

$ ls u-boot | grep u-boot
u-boot
u-boot.bin
u-boot.cfg
u-boot.dtb
u-boot-dtb.bin
u-boot-dtb.img
u-boot.dtb.out
u-boot.img
u-boot.lds
u-boot.map
u-boot-nodtb.bin
u-boot.srec
u-boot-sunxi-with-spl.bin
u-boot-sunxi-with-spl.map
u-boot.sym

Building linux

Getting linux

To obtain linux, I download the latest available version from the releases page at github (v6.4 at time of writing):

wget https://github.com/torvalds/linux/archive/refs/tags/v6.4.tar.gz
tar -xvf v6.4.tar.gz

Building linux for the q8 tablet

Building linux for the tablet is very straightforward and doesn’t take very long:

cd linux-6.4
export ARCH=arm
export CROSS_COMPILE=/home/$USER/x-tools/arm-cortex_a8-linux-gnueabi/bin/arm-cortex_a8-linux-gnueabi-
make sunxi_defconfig
make menuconfig # for any desired changes
make -j`nproc`

The folder arch/arm/boot should now containe a file called zImage. To verify:

$ ls arch/arm/boot/ | grep Image
Image
zImage

Both Image and zImage… Nice!

Another file that needs to be present, is the .dtb file. This file contains a list of hardware inside the tablet.

To verify:

$ ls arch/arm/boot/dts | grep a13-q8
sun5i-a13-q8-tablet.dtb # The file I'm looking for, a .dtb file
sun5i-a13-q8-tablet.dts

Creating a minimal SD-card image

If I read this mailing list correctly, the Allwinner A13 can boot from an SD-card. For that to happen, u-boot needs to be flashed to an SD card in the correct way.

Instead of flashing directly to an SD card, an SD card image will be created. That image will then be flashed onto an SD card. To create an SD card image, I will use an existing genimage config from buildroot and edit it, so it works for the q8 tablet.

Genimage config

The genimage config file (genimage.cfg) looks as follows:

image boot.vfat {
	vfat {
		files = {
			"zImage",
			"sun5i-a13-q8-tablet.dtb",
		}
	}

	size = 8M
}

image sdcard.img {
	hdimage {
	}

	partition u-boot {
		in-partition-table = "no"
		image = "u-boot-sunxi-with-spl.bin"
		offset = 8K
		size = 530K # file is 525KB in size (measured in KB, not KiB)
	}

	partition boot {
		partition-type = 0xC
		bootable = "true"
		image = "boot.vfat"
	}

	# The rootfs partition will be configured later
    partition rootfs {
		partition-type = 0x83
		image = "rootfs.ext4"
		size = 0
	}
}

To build the image, I copy over all the required files and start genimage:

$ genimage --help
genimage: command not found
$ sudo apt install genimage
...
E: Unable to locate package genimage
# What? Debian unstable seems to have `genimage` in it's repo's,
# why not Ubuntu?

Getting genimage

Genimage is not in the package repositories of ubuntu yet? Building it is straightforward enough:

git clone https://github.com/pengutronix/genimage
cd genimage
./autogen.sh
./configure
make
# DO NOT EXECUTE `sudo make install`,
# IT WILL CURSE YOUR GNU/Linux INSTALLATION!
cd ..

# To use genimage, execute the local file.
./genimage/genimage --help

Building the image using genimage (attempt #2)

First, copy the required files into a separate folder:

mkdir genimage_input
cp u-boot/u-boot-sunxi-with-spl.bin genimage_input
cp linux-6.4/arch/arm/boot/zImage genimage_input
cp linux-6.4/arch/arm/boot/dts/sun5i-a13-q8-tablet.dtb genimage_input
touch genimage_input/rootfs.ext4 # create an empty rootfs file for now

Then, tell genimage where to find everything and where to export everything to (this builds the actual image):

mkdir genimage_output
./genimage/genimage --config genimage.cfg --rootpath genimage_output --inputpath genimage_input

Genimage should have created a folder called images. This folder will contain a file called sdcard.img. To verify:

$ ls images/
boot.vfat  sdcard.img

Writing the image to an SD card

Writing this image to an SD card is no different from the way Raspberry Pi users would do this. Use your favourite tool for this. In another blog post I have already explained how this process works.

Booting the tablet

Because the tablet has an Allwinner SoC, it boots just like a PinePhone (non-pro edition): Just insert the SD card and turn it on!

After the tablet was powered on, u-boot immediately showed up on the screen:

First boot of the new OS

This tells me a few things:

  • It has 512MiB RAM.
  • It boots from an SD card, just like a Raspberry Pi/PinePhone does. If the card is removed, it boots android again (as if nothing happened).
  • The screen works.
  • U-boot knows where the boot partition is located: it seeks it’s environment config (uboot.env) in mmc0:1. No changes needed there.
  • The power and volume keys don’t stop the u-boot autoboot.

Configuring u-boot

U-boot does not load linux yet, because it says it’s missing a file called uboot.env. U-boot will not do anything if it cannot find it’s configuration.

To fix uboot.env not being present, let’s create a file called boot.scr.

U-boot goes through a few stages when booting:

  • It gives some hardware information.
  • It looks for uboot.env (which doesn’t exist in this case).
  • It looks for boot.scr, a boot script (which doesn’t yet exist in this case).
  • It tries to boot from a network.
  • It says it failed and hangs forever.

Because I have no idea where the UART-pins are yet, I cannot interact with u-boot. So, I cannot create uboot.env. So, boot.scr will be created instead.

Creating boot.scr

To create a boot script for U-boot, a text file with some script text needs to be converted.

For this project, a file called boot.txt is created, with the following contents:

setenv bootargs root=/dev/mmcblk0p2 rootwait panic=10 console=/dev/ttyS0,115200 console=tty0
load mmc 0:1 $kernel_addr_r zImage
load mmc 0:1 $fdt_addr_r sun5i-a13-q8-tablet.dtb
bootz $kernel_addr_r - $fdt_addr_r

It is then converted to boot.scr using the following command:

mkimage -C none -A arm -T script -d boot.txt boot.scr

After copying boot.scr to the SD card, u-boot knew what to do and stopped complaining about missing files. It then started booting linux:

U-boot loading linux

Linux! Or not.

But after that, nothing. No kernel output, no logs, nothing. Just an empty screen.

Expecting linux? Too bad!

In fact, the whole tablet just turned off.

Even with external power applied (faking the presence of a battery), the device turns off. This happens after about 1 second after linux is loaded.

Expecting linux with external power? Too bad!

This variant of the q8 tablet has it’s wifi chip wired differently. So, as soon as the wifi chip gets powered, the tablet turns off.

Someone else figured out a solution to this problem. Maybe that will work? The post speaks of disabling LDO3 (and thus disabling wifi and usb). To test this, the LDO3 entries in u-boot/arch/arm/dts/sun5i-reference-design-tablet.dtsi were removed (make sure to make a backup!).

After that, a new .dtb file was created:

make dtbs # with u-boot source as $PWD

After booting, it turns out the user was onto something. The tablet doesn’t immediately turn off anymore. Instead, the screen only displays white lines, after which the tablet reboots.

Expecting image? Too bad!

Switching to linux-sunxi

Many years ago, there was a linux-fork called linux-sunxi and a u-boot fork called u-boot-sunxi. These forks still exist and are widely used today. In recent years, most of the the linux-sunxi drivers have been merged into the mainline linux kernel.

As seen earlier, the mainline version of u-boot supports the Allwinner A13 SoC now. The mainline linux version however, still crashes (the screen?) when it boots.

So, there is a chance that linux-sunxi works. After downloading release version 5.8 (latest version at time of writing) and repeating exactly the same steps as before, it worked! The linux kernel logs were shown:

Linux logs being displayed on the screen!

Can Linux mount a rootfs and start an init?

Linux now starts and prints logs to the tablet’s display, but it panics. This was expected, since the genimage.cfg does not yet contain a rootfs configuration.

To test if any rootfs can be mounted at all, a second partition was added to the SD card, containing a rootfs from the A13 OLinuXino board. Although the rootfs is not made for this tablet, it displayed the Debian CLI login:

Debian CLI login being shown

The same trick worked for Arch as well:

Arch CLI login being shown

A rootfs with a GUI

All of these CLI logins are fun and all, but how about something with graphics?

Ubuntu MATE has a 32-bit armhf image, meant for Raspberry Pi’s. Merging Ubuntu MATE’s userland and linux-sunxi, reveals that the tablet can run a desktop.

Ubuntu MATE loading

Although the tablet is slow, it eventually (after about 4 to 5 minutes) started the Ubuntu MATE setup:

Ubuntu MATE welcome

Why does this work?

Why does an OS, created for the Raspberry Pi, work on this tablet? The tablet and the Raspberry Pi 2 share a similar architecture: ARMv7. So, both SoC’s are able to run 32 bit ARM code.

Also, the copypasta is correct:

What you’re referring to as Linux, is in fact, GNU/Linux. Many computer users run a modified version of the GNU system every day, without realizing it. Through a peculiar turn of events, the version of GNU which is widely used today is often called “Linux”, and many of its users are not aware that it is basically the GNU system, developed by the GNU Project.

Linux is just a kernel. When people talk about “linux”, they really mean the (GNU) userland binaries that they are interacting with.

You can get away with a lot of “ugly” solutions to create an OS (like the one described in this post), because “Linux” is not an entire OS. This project uses linux-sunxi instead of raspberrypi/linux, but the userland binaries remain the same. They will work with many versions of linux (the kernel!).

However, this method should not be used in production. In a production environment, just use yocto or buildroot to create a fully compatible image for the hardware.

The touchscreen doesn’t work

The tablet did not respond to the touch screen when clicked or dragged. Looking at u-boot/arch/arm/dts/sun5i-reference-design-tablet.dtsi, it quickly became clear why this is the case:

The touchscreen is disabled

The touch screen is disabled, because these tablets often have different types of touch screens. The tablet I have says FYX00109 the cable.

Figuring out which touch screen the tablet has

To figure out which screen the tablet uses, Android 4.1 was started again.

Inside an adb shell, lsmod will give a list of active linux modules:

root@android:/ # lsmod
8188eu 784805 0 - Live 0xbf160000
sun4i_vibrator 2459 0 - Live 0xbf15c000
rtl8150 10305 0 - Live 0xbf155000
mcs7830 7581 0 - Live 0xbf14f000
qf9700 9152 0 - Live 0xbf148000
asix 24601 0 - Live 0xbf13c000
cedarx 9351 0 - Live 0xbf135000
mali 151260 4 - Live 0xbf103000
da311 29089 0 - Live 0xbf0f6000
ump 49518 9 mali, Live 0xbf0e2000
gslX680 94888 0 - Live 0xbf0c5000
sun5i_csi0 30454 0 - Live 0xbf0b8000
gc0329 18132 0 - Live 0xbf09e000
gc0309 17436 0 - Live 0xbf095000
siv121du 18993 0 - Live 0xbf08c000
siv121d 14194 0 - Live 0xbf084000
gc0308 18464 0 - Live 0xbf07b000
camera_auto_detect 14914 7 sun5i_csi0,gc0329,gc0309,siv121du,siv121d,gc0308, Live 0xbf04f000
videobuf_dma_contig 6251 1 sun5i_csi0, Live 0xbf04a000
videobuf_core 20242 2 sun5i_csi0,videobuf_dma_contig, Live 0xbf040000
nand 225024 10 - Live 0xbf000000

To figure out which driver is responsible for the touch screen, I started to unload modules (using rmmod) until the touch screen didn’t respond anymore. In this tablet, it was the gslX680 module. This means, according to the linux-sunxi.org website, that this tablet has a Silead gsl1680 touch screen.

According to the datasheet for the touch screen, the reg entry in de .dts files has to be set to 0x40. Let’s edit u-boot/arch/arm/dts/sun5i-reference-design-tablet.dtsi again, to enable the gsl1680 driver:

The touchscreen is enabled

A compatible entry was added to tell linux that the gsl1680 driver will work with the touch screen in the tablet. Also, the status was changed from disabled to okay. The rest of the .dts file was left as-is.

Also, a kernel module was enabled (as a module, not built into the kernel!):

The touchscreen driver is enabled

And sure enough, in the linux logs, the driver can find the touch screen (please excuse the poor camera image, I still haven’t taken the time to find the UART pins on this thing):

The touchscreen is found

However, as seen in the logs, it requires a file called silead/gsl1680.fw. The original android OS uses a similar firmware file. Luckily, the firmware for this touch screen can be found on github. Renaming this firmware file to gsl1680.fw and placing it in <sdcard>/lib/firmware/silead/ resulted in the driver being loaded correctly. After that, the cursor moved!

The cursor moved when the screen was touched

The cursor only seems to stay in the upper left corner though, so some sort of calibration must be applied before it’s usable.

Calibrating the screen

To manually calibrate the touch screen, a transformation matrix can be applied to the touch screen input. This is usually done by creating an X.org configuration file. On the internet, people specify names of their input devices. But, I have no idea what this touch screen is called. So, this config file just calibrates all touch screens.

The <SD card rootfs>/etc/X11/xorg.conf.d/99-touchscreen.conf file contains the following configuration:

Section "InputClass"
	Identifier "evdev touchscreen catchall"
	MatchIsTouchscreen "on"
	MatchDevicePath "/dev/input/event*"
	Driver "evdev"
	Option "TransformationMatrix" "4 0 0 0 7 0 0 0 1"
EndSection

Distro-hopping

Ubuntu MATE

After the touch screen was calibrated, the Ubuntu MATE installer would go to the next page. The setup process went fine, until a username had to be entered. Ubuntu MATE doesn’t have a pop-up keyboard, like android does. So, this became an impossible task:

Expecting keyboard? Too bad!

It seems that in this version of Ubuntu MATE, it is impossible to enable the on screen keyboard during setup.

Raspberry Pi OS

As much as I would have liked to run Ubuntu MATE on the tablet, the OS would not let itself be configured, not even when booted from a Raspberry Pi 3 (X.org did not start for whatever reason). Raspberry Pi OS might work better, since it’s pre-configured. This way, the OS is already configured by rpi-imager. It should boot straight to the desktop.

And so it does, but something is off:

Expecting menu bar? Too bad!

The top bar, along with the application menu is missing. It appeared, then crashed and disappeared forever.

The only application can be started is the file manager:

At least the file manager works

Maybe another userland works better…

Kali linux

As much as I would have liked to run Ubuntu MATE or Raspberry Pi OS on the tablet, both desktops are not usable. So, the next userland is kali linux. Maybe this GUI is usable.

And so it is! Finally, an OS that understands my needs! It has an option for an on screen keyboard everywhere!

Login screen

Kali linux login screen with on screen keyboard

Desktop

Kali linux desktop

Screenshots from the device itself

Notepad and keyboard

With the convinience of an on screen keyboard, screenshots can be made on the device!

Kali linux desktop

Firefox

Starting firefox slows the tablet down very much, to the point where it’s almost unusable.

Firefox on a q8 tablet

Task manager

As seen in task manager, the SoC has some troubles with a “modern” OS. The task manager program used around 30% of the CPU. Another 20% of the CPU was used by the screenshot program.

~30% cpu usage, only by opening task manager

I did not expect it to use so little memory. Nowadays, RAM quickly goes up to 1GiB or more.

Video playback

To see how well the tablet can play a video file, I downloaded a 360p version of the famous music video. Below is a gif of how that went (the tablet did it’s best):

I tried so hard, and got so far, but in the end, it doesn’t even matter!

Conclusion

It is possible to run linux(-sunxi) and a graphical desktop on an old Allwinner A13 tablet, but it’s very slow.

Also, this tablet variant has a problem where it shuts down as soon as the wifi card is enabled. In the future I might try to fix this issue. But, seeing how slow the tablet is, I think it’s not really worth the effort.

Attachments

I will not share any SD card images, but I will leave the genimage.cfg config file and the create_image.sh script here. Richt clicking the links and choosing save as will probably work. All the (other) required input files will not be shared.