Running Linux on Lenovo Miix 3-1030

Introduction

This page is about my onging efforts to get Linux running on a Lenovo Miix 3-1030 hybrid PC-tabled computer.

As of now, 2016-04-25, the essential hardware is working, making this a usable laptop and tablet, but most of the non-essential hardware is not, including the audio controller and efficient power management.

My distribution of choice is Debian. As I wrote this, Jessie had just been released, and therefore, Jessie, Stretch and sid were nearly identical. One year later, updates in the kernel for Stretch make it easier to get everything working.

Note: I am not interested in getting a “there's an app for that” tablet experience. The current usual tablet user interface tries to emulate what was seen ten years ago in sci-fi movies but is awful for a technically-oriented user.

Comments on the device

The short of it: it is crap.

The high-resolution screen is very good. End of positive comments.

There is only one USB socket, and it is micro-B despite being mostly useful as host. The necessary USB On-the-Go cable is not provided.

Charging is done through the USB socket, but only works with the official charger and short cable. With a third-party charger or even an USB extension it charges very slowly, or even not at all if on. And of course, the only USB socket is not usable at the same time.

The keyboard sleeve does not allow to adjust the screen angle and can fold suddenly.

The keyboard lacks the menu key, the home, end and numbered F keys require the special Fn key. Furthermore, the Fn key eats release events from other keys, making it tricky to do ctrl-home without leaving a phantom ctrl pressed.

The touchpad is sensitive even on the buttons area, making it impossible to click without moving the pointer. Furthermore, it appears only as an USB HID device, and therefore has only basic support.

The UEFI firmware is barely conforming, if even so.

Necessary accessories

To get anywhere, the following accessories are more or less necessary:

Making the OEM windows Linux-friendly

Microsoft has made a lot of progress since I completely stopped using their products sixteen years ago in terms of living together with the concurrents. I do not intend to use the OEM windows, but as long as I can not all the hardware working on Linux, I keep it on a corner of the hard drive to help diagnose.

Make a rescue USB drive. I do not remember how I found the menu, it was awfully translated.

The internal SSD comes with four GPT partitions: #1 is the EFI system partition; #2 is a Microsoft reserved partition (or “MSR”, don't ask), some kind of Windows equivalent of LVM that for some reason requires 128 megaoctets; #3 is the big partition with the system and user data; #4 contains the recovery images.

The big partition #3 with the system and user data is encrypted with BitLocker, even if the user did not set any password or key. Vanilla Linux can not read it. Windows can decrypt it for you: in the PC settings from the tablet-style interface, there is a menu for that. It takes some time. After that, the partition is normal NTFS that can be mounted, although I did not manage to get Windows to shutdown properly instead of hibernating, and therefore Linux refuses to mount it read-write. Note that decrypting the partition lowers the security; I do not care about the security of the OEM windows, I will not use it.

Windows tools can also be used to reduce the size of the partition. They can be found in the classic-style device manager, as something like “partition manager” (sorry, French translation on my version). I do not know if that would work with BitLocker still enabled.

Booting on USB

This computer has a UEFI firmware without legacy mode emulation (or disabled). To understand what that means, read that excellent article.

To access the UEFI settings and boot menu, start with a powered-down computer, press the volume-up button then press the power button; volume-up can be released once the Lenovo logo is on the screen.

It is also possible to get there by asking the OEM Windows to reboot that way, but it seems to hang if the dock keyboard is connected at the time.

In the UEFI, disable Secure Boot. Theoretically it makes the security weaker. In practice, Linux has its monthly security issues and Microsoft was the company that could fit three security flaws in the 512 octets of the Xbox ROM bootloader, and if that was not enough, I am very sensitive to rubber-hose cryptanalysis.

To make a bootable USB stick, format it in MBR format (GPT does not seem to work, which makes it non-UEFI compliant) with a single FAT32/LBA partition (type 0x0C) and put the bootloader as EFI/boot/bootia32.efi.

To generate the bootloader image, I used GRUB2 with the following commands (the shell is Zsh):

m=(
  acpi adler32 all_video bitmap bitmap_scale blocklist boot btrfs bufio
  cat chain configfile crypto datetime disk echo efi_gop efi_uga
  efifwsetup efinet ext2 extcmd fat file font fshelp gcry_sha512 gettext
  gfxmenu gfxterm gfxterm_background gzio halt help hfsplus http iso9660
  jpeg keystatus linux linuxefi loadenv ls lsefi lsefimmap lsefisystab
  lssal lzopio memdisk minicmd mmap net normal part_apple part_gpt
  part_msdos password_pbkdf2 pbkdf2 png priority_queue reboot relocator
  search search_fs_file search_fs_uuid search_label serial sleep terminal
  test tftp tr trig true video video_bochs video_cirrus video_colors
  video_fb
)
grub-mkimage -o /tmp/grubia32.efi -O i386-efi -p /boot/grub $m

(I got the list of modules by grepping the grubx86.efi file present on Ubuntu 15.04.) Copy manually the modules in boot/grub/i386-efi/.

The graphical driver for UEFI boot is efi_gop, probably already loaded by all_video. I strongly suggest to enable the GRUB video terminal using terminal_output gfxterm, because otherwise text scrolling is awfully slow.

Once GRUB boots, it is possible to start live ISO images the way I explained it. GRML 2014.11 hangs at boot, but Ubuntu 15.04 gets to the desktop.

Now we have a Linux running on the machine, we can start playing around.

Installing the bootloader on the internal SSD

The internal SSD is detected as /dev/mmblk0. The EFI system partition is therefore mmcblkp1. Mount it, copy the GRUB modules and other files in BOOT/grub/ and the bootloader image in EFI/grub/grubia32.efi. Then add it to the boot menu with:

efibootmgr -c -d /dev/mmcblk0 -l '\EFI\grub\grubia32.efi'

Note that depending on whether a USB stick was plugged at boot time or not, the internal SSD will appear as either hd1 or hd0. The root environment variable will point to the EFI system partition, hd1,gpt1 or hd0,gpt1, but to access other partitions, using the search command is necessary for a reliable configuration.

GRUB can be configured to chainload Windows using:

chainloader /efi/Microsoft/Boot/bootmgfw.efi

I have configured my GRUB to look for the Linux partition (currently: temporary, single partition in Brtfs) and source /boot/grub/grub.cfg on it, so I can change the GRUB configuration without mounting the EFI system partition.

Getting the system to work

Summary

With the previous operations, it is possible to get Debian booting and running. At the time I first wrote this, the available kernels were 3.16.7-ckt9 in Jessie/Stretch/Sid and 3.19.0-trunk and 4.0.0-trunk in experimental. The 4.0 kernel seems to have much less options enabled.

This hardware is very strange. Only a handful of internal devices appear on the usual PCI and USB bus listings. According to the OEM windows, they are accessed with ACPI and SDIO. I have no idea how that works with Linux, and there is no lsacpi command, there are a lot of links in /sys/bus/acpi/devices/ but no database to map the ids to a readable name, and even less for SDIO.

There are a few possible attempts I have not yet done. I am writing this as I am waiting for the PC to recharge since the only USB hub I have right now is not powerful enough and I have no male-male cable to boost it with a secondary power supply.

Update on 2016-04-25: the linux-image-4.5.0-1-amd64 package from Debian testing supports all the features I have managed to get working, except the wlan adapter that needs patches, and the non-working sound driver is disabled. See details below.

Quick-and-dirty method to recompile it: apt-get source linux; apply patches; import .config from the binary package; make menuconfig; disable DEBUG_INFO (or it will eat gigaoctets), enable SND_SOC_RT5640; nice make -j 4 EXTRAVERSION=-cig deb-pkg; install ../*.deb on the target.

Clock

With the 3.16 kernel, the system clock is twice as fast as real time and irregular. This is noticeable on the framebuffer text console: the cursor blinks at an increasing speed. If a key is pressed when the clock is way to fast, autorepeat kicks in immediately, making the keyboard unusable.

The clock can be fixed with clocksource=tsc on the kernel command line. It can also be set using /sys/devices/system/clocksource/clocksource0/current_clocksource, but I have not found a convenient config file with the default install.

The 4.0 kernel from Debian experimental selects the clocksource correctly by default but not vanilla 4.0.1.

Video

X.org starts normally at the native resolution. The 3.16 kernel oops when initing or unblanking the screen, but this is fixed in the 4.0. Accelerated 3D works. This is an Intel controller, it works with Free drivers.

Touchscreen

The touchscreen emits evdev events and is detected as a mouse by X.org. Multitouch up to ten fingers tested with this program.

Wlan (wifi) controller

Works with this third-party kernel module on top of a 4.5.1 kernel with the included patches (although I experienced one freeze possibly related). There is a discussion to include the patch in the official kernel.

Audio controller

Does not work. With kernel 4.5.1, the controller is detected by the snd-soc-rt5640 codec (kernel option SND_SOC_RT5640) but it fails doing anything, apparently timeouting while trying do load the firmware.

There are suggestions on the web to patch sound/soc/intel/common/sst-acpi.c to set sst_acpi_baytrail_desc.irqindex_host_ipc to 0 instead of 5, but it does change anything.

This mailing-list message that arrived precisely while I was updating this page seems interesting, though.

Webcam

Completely invisible. OEM Windows reports it as OV2722 connected by I2C. It seems there are a few i2c/ov2722.c in Android forks of the kernel on the web.

MMC card reader

Seem to work with some random kernel build option.

Power management

The battery level is visible with some kernel configuration. The relevant option seems to be AXP288_ADC.

Immediate suspend works with echo freeze > /sys/power/state, with a few caveats (USB Ethernet needs to be reset) and no support from high-level tools.

But neither freeze nor DPMS do blank the screen, which stays a big drain on the battery.