Building a Linux Kernel for the Asus UX305C

Update: Read to the end before doing this. There's a caveat.

I bought an Asus UX305C recently - see this entry for the initial Ubuntu installation. The most blatant problem I was left with was a non-working touchpad, and that's a standing problem that may not be solved for a couple months. So I followed the advice here https://florisvanvugt.wordpress.com/2015/12/26/making-asus-ux305ca-touchpad-work-in-ubuntu/ , which led to Ubuntu's very straightforward instructions on how to build your own kernel: https://wiki.ubuntu.com/KernelTeam/GitKernelBuild . If you have a UX305C, do NOT bypass Floris van Vugt's blog post and go straight to Ubuntu: his entry includes a critical patch to the kernel that you have to apply before you compile. Or you can follow my instructions below, but you're probably better off going back to the source.

I remember compiling kernels a decade ago and it was kind of a nightmare. In hindsight, that was mostly because I didn't propogate the .config file and accept the configuration defaults, I kept trying to make the kernels smaller by removing unneeded stuff (and removing stuff that was actually needed). If you follow the instructions, it's fairly easy.

As I'd only created a 7.2G / partition, the first step for me was a lot of apt-get purge ... commands, removing useless stuff like old kernels and GNOME. Next up, the huge toolchain install:

# apt-get install git build-essential kernel-package fakeroot libncurses5-dev libssl-dev ccache

I didn't have much in the way of build tools installed yet, so that required a rather impressive 1256 MB of disc space. Although a huge portion of it appeared to be taken up with TeX documents I'll never look at (~200 MB?). Next:

# git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
# cd linux
# cp /boot/config-`uname -r` .config

This last is hugely helpful: it grabs the current Ubuntu configuration of the kernel so there are immensely less setup decisions for you to make.

# make oldconfig

The Ubuntu page suggestion - which I should have followed, but I was curious - was, instead of running make oldconfig that you should instead run yes '' | make oldconfig" . make oldconfig asks any questions not already answered by the .config file. The questions are related to any devices, drivers, or kernel changes that have occurred since your previous kernel. As it turns out, that's quite a few. And I just kept hitting enter to accept the defaults (which the "yes" command could have done for me).

Now to apply the patch: in drivers/i2c/busses/i2c-designware-platdrv.c, find this block of code:

static int dw_i2c_acpi_configure(struct platform_device *pdev)
    dw_i2c_acpi_params(pdev, "SSCN", &dev->ss_hcnt, &dev->ss_lcnt, NULL);
    dw_i2c_acpi_params(pdev, "FMCN", &dev->fs_hcnt, &dev->fs_lcnt,
                       &dev->sda_hold_time);

    return 0;
}

Look for the latter two dw_i2c_acpi_params lines in particular. This is the code borrowed from Floris' page, it wasn't an exact match to what's in the kernel now, but the code remains the same. After the two dw_i2c_acpi_params, add another line that says "dev->sda_hold_time = 30;" (no quotes).

Next up - compiling.

# make clean
# time make -j `getconf _NPROCESSORS_ONLN` deb-pkg LOCALVERSION=-custom

The time part isn't necessary, but I wanted to know how long it took. And next time, instead of "-custom" for the LOCALVERSION value, I'll use something more descriptive like "-ux305ctouch". The getconf _NPROCESSORS_ONLN is a nice touch: it chooses the number of threads to run based on how many threads your processor supports. This is of course the point at which you go to bed for the night, because the output of time looked like this:

real    120m29.138s
user    320m24.132s
sys     17m31.204s

5 hours and 20 minutes. This was compiled on the UX305C itself, which has a Intel Core m3-6Y30 - great on battery power, but not a powerhouse number cruncher. But now you're in the home stretch:

# cd ..
# sudo dpkg -i linux-image-4.4.0-rc8-custom_4.4.0-rc8-custom-1_amd64.deb
# sudo dpkg -i linux-headers-4.4.0-rc8-custom_4.4.0-rc8-custom-1_amd64.deb

Reboot, and I have a working touchpad! Thanks Floris!

Update

Up until now, the machine has been quite stable. I suspend-to-RAM simply by closing the lid. The day after the kernel rebuild, around the fourth time I opened the machine, I found it crashed (power light on, caps lock flashing, screen black, body warm). I suspect it attempted to suspend, failed, and kept trying to suspend. In any case, I'm now back to using the stock kernel and carrying a mouse.

I suppose it could be related to my excising a huge chunk of the OS to make room for the toolchain to build the kernel ... I'll find that out over time.

Points for Consideration

  • kernel compile can and probably should be done as a user
  • if you had another machine with the same OS (I don't - my desktop has an older Ubuntu install, which might or might not work) you could probably build the kernel there. Given that this is a relatively slow processor, if you had a recent i7 or Xeon available it would definitely be worth considering.