Linux on Lenovo Yoga C740

I just bought a Lenovo Yoga C740, the one with an Intel Core i7 with 16GB RAM and 1TB SSD. I like it so far, but it needs to run Linux of course…

So this is what I want to have:

  • Dual-boot Ubuntu & Windows 10
  • Everything working (at least) as smoothly as in Windows

That didn’t go as smooth as hoped though, so this post is a work-in-progress for people who would like to achieve the same thing, and for myself in case I need to redo it later…

TL;DR: the following are working:

  • Touchpad
    • Works like a charm, including two-finger scrolling
  • Touchscreen
    • Works as a mouse in most cases (i.e. selects text instead of scrolling)
    • Does work for scrolling in Firefox
  • Tablet mode (on-screen keyboard, auto-rotate)
    • Not perfect, sometimes screen doesn’t pop up
  • WiFi
    • Works like a charm
  • Bluetooth (mouse)
    • Very laggy in combination with MX Anywhere 2S
  • USB-C (power, display)
    • Works
  • Suspend & Hibernate
    • Works, but hibernate requires disabling UEFI Secure Boot

Things still on the TODO:

  • Make Gnome 3 look more like Unity
    • e.g. remove useless empty lock screen, smaller title bars
  • Dim keyboard backlight when idle (esp when screen itself turns off)
  • Fingerprint reader
    • Driver not supported by fprintd (some kind of Synaptics device)

Please do post any improvements you have found yourself in the comments, below!

Dual-boot Ubuntu / Windows 10

First, I shrunk my C:-drive by 750GB using Windows Storage Manager to leave it at ~250GB.

Warning: the C:-drive is encrypted using BitLocker, and it’s likely that you’ll taint its security check in the process. Make sure you know where to find the BitLocker Recovery Key. Apparently, it’s automatically stored in your Microsoft account, in case you entered that during initial set up.

I created an Ubuntu Live CD (19.04, the current Ubuntu stable), and continuously pressed F12 during boot to boot into that.

That worked, but WiFi, touchpad and touchscreen didn’t work. After a bit of Googling, it appeared that many of the drivers were located in newer kernels, so I opted to go for 19.10 instead (it’s already in feature freeze, so should be fine).

With Ubuntu 19.10, most things started working out-of-the-box. Nice! Wifi, touchpad, touchscreen now all work.

I then set out to install it to my drive. I chose the following:

  • Create 1GB partition for /boot (unencrypted, ext4)
    • Seems modern Grub can also boot from a kernel inside a LUKS volume, but I didn’t know at the time, and don’t bother changing it right now.
  • One big 750GB partition for / and swap (LUKS encrypted, BTRFS)
    • Inside that partition the installer defaults to create just one big partition. I initially tried to remove that, and manually create swap and root partitions, but the installer then crashes later with a message like “cannot mount /target” or something.
    • On the next try, I marked it as one big BTRFS volume.
    • By default, Ubuntu will create BTRFS sub-volumes for /, /swapfile and /home (as I noticed after the installation).

I left UEFI Secure Boot enabled throughout the process. That didn’t go very smooth: both the on-disk installation and live-CD failed to boot afterwards. Probably something to do with enrollment of custom signing keys for third-party kernel drivers (which in the end, I didn’t appear to need so far). I did get into the MOKManager at some point and enrolled a key, but not sure that was actually the right one (given that my install failed a few times at initial attempts).

Temporarily disabling Secure Boot resolved these issues, and I could actually work with Secure Boot enabled for a while (until I wanted to have hibernation working).

Hibernation

I want hibernation to work for the occasional escape to Windows (and back), and in case I run out of battery on the road, but don’t want to shut down completely.

It appears that nowadays, swapfiles are the default, and they are just as efficient as ‘old-school’ swap partitions, due to the kernel just using the raw disk offset / size directly, bypassing any filesystem layers.

Creating a swapfile

  • Create a subvolume for your swapfile: btrfs subvolume create /swap
  • Create a swapfile (20GB in my case: 16GB to store all RAM, 4GB actual swap space):
truncate -s 0 /swap/swapfile
chattr +C /swap/swapfile
fallocate -l 20G /swap/swapfile
chmod 0600 /swap/swapfile
mkswap /swap/swapfile
swapon /swap/swapfile
btrfs property set /swap/swapfile compression ""
  • Change the existing /swap entry in /etc/fstab to:
    /swap/swapfile none swap sw 0 0
  • Remove the ubuntu-default swap: rm /swapfile (wasn’t actually used in my case somehow, otherwise, do a swapoff /swap first)

If you take a look at e.g. top, you should now see your swap being in-use.

Hibernate to swapfile

We’ll need to tell the kernel where to resume from, in this case our swapfile. It lives inside our encrypted volume, and starts at a certain offset within that. Run blkid /swap/swapfile to obtain the UUID, and filefrag -v /swap/swapfile to obtain the offset. (Note: for some people, filefrag apparently returns the wrong offset. It was already correct in my case, though.) For example:

root@yoga:/# blkid /swap/swapfile 
/swap/swapfile: UUID="bd84f05a-45e9-42af-a7a1-fbc89fdeb117" TYPE="swap"
root@yoga:/# filefrag -v /swap/swapfile 
Filesystem type is: 9123683e
File size of /swap/swapfile is 21474836480 (5242880 blocks of 4096 bytes)
 ext:     logical_offset:        physical_offset: length:   expected: flags:
   0:        0..       0:    2364672..   2364672:      1:            
   1:        1.. 5242879:    2364673..   7607551: 5242879:             last,unwritten,eof
/swap/swapfile: 1 extent found

Make note of the UUID and the first physical_offset. Then, edit /etc/default/grub, and change the GRUB_CMDLINE_LINUX_DEFAULT variable to include resume and resume_offset, like so (don’t forget the UUID=):

GRUB_CMDLINE_LINUX_DEFAULT="quiet splash resume=UUID=bae3e4da-c406-49f0-bb23-3bdea0e50a87 resume_offset=2364672"

Run update-grub.

Some people noted that initramfs also needs to be updated, so I created /etc/initramfs-tools/conf.d/resume to look like this:

root@yoga:/# cat /etc/initramfs-tools/conf.d/resume 
RESUME=UUID=bae3e4da-c406-49f0-bb23-3bdea0e50a87

Run update-initramfs -u to rebuild, and reboot your system.

At this stage, I needed to turn off Secure Boot, because newer kernels don’t allow booting from a hibernate image, as these aren’t signed. Otherwise, suspend to disk is disabled.

To do that, reboot and keep pressing F2 until you enter the BIOS. Disable Secure Boot in the Security menu. Press F10 to Save & Exit, then reboot back to Linux. Check that hibernate should work:

root@yoga:/# cat /sys/power/disk 
[platform] shutdown reboot suspend test_resume

Now, test whether it actually works:

root@yoga:/# echo disk > /sys/power/state

This should hibernate and turn off your PC. When turning on, it should first ask for your passphrase, then show a message that it’s resuming from a hibernated image. Hurray!

Enabling hibernate options in GNOME 3

TODO, didn’t figure this out yet. There are some extensions, but none actually work.

Touch screen (tablet mode)

To get Firefox to scroll instead of selecting text, add the following line to /etc/security/pam_env.conf, then reboot and start Firefox.

MOZ_USE_XINPUT2 DEFAULT=1

Go to https://extensions.gnome.org/ and follow their instructions to enable installing GNOME extensions. Then, enable the following extensions:

  • Right-click For Touch Screen: converts long-press to right-click for touch screens. NOTE: follow the instructions in the comments to make it work with the latest GNOME.
  • Onboard integration: adds a much better on-screen keyboard in tablet-mode

Bluetooth mouse

After connecting my Logitech Anywhere 2S, mouse movements were very laggy (a bit like working across a long-latency remote desktop).

To fix, unpair your mouse, then:

echo 6 > /sys/kernel/debug/bluetooth/hci0/conn_min_interval

Then pair again et voilĂ .

However, now suspend to RAM is broken, apparently due to a recent bug. I temporarily worked around it by running tail /sys/bus/usb/devices/*/power/wakeup, and then echo disabled > /sys/bus/usb/devices/1-10/power/wakeup (where 1-10 is the device ID that showed “enabled” in the previous tail command). This is not remembered across reboots, so if I get annoyed by this, I’ll fix it properly some way.

Other tweaks

Go to https://extensions.gnome.org/ and follow their instructions to enable installing GNOME extensions. Then, enable the following extensions:

  • Unite: makes your top bar look more like Unity: removes title bar on maximized windows, rearranges icons in the top bar, moves the date/time to the right. Very nice!
  • CpuFreq: adds CPU speed indicator to your panel, and a way to change the CPU profile (powersave / balance / performance)

Conclusion

I’m quite happy with the system so far, but there’s quite a bit to tweak. I’ll update this post as I make further improvements.

Please post your tips, tricks or a simple thank-you in the comments below!

4 Comments

  1. I’m sorry but where did you found Ubuntu 19.10 for Intel architecture?

    I also recently bought C740 same as yours, just with a 500 GB hard disc. Not one unix release I’ve tried so far worked. Well, they work, except WiFi and touchpad, wich makes C740 laptop with unix OS unusable for everyday work. I’ve struggled to instal WiFi drivers on it but it seems to be more of the mission impossible without ethernet connection.

    Reply
    • Sorry for the late response…

      I simply downloaded it from http://releases.ubuntu.com/19.10/ and used the standard installation instructions to ‘burn’ it to an SD card, which I then mounted using a USB-SD-reader.

      Reply
  2. Have any of these issues been resolved?

    I’d like to switch but not unless everything works. I really need it to work in tablet mode for note taking. One of the reasons I bought it.

    Reply
    • Well, as a ‘normal’ laptop it works fine now, but the tablet mode still is far from ideal.

      Though it’s trivial to just flash Ubuntu on a USB stick and boot it, if you want to try it out for yourself.

      Reply

Leave a Reply

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

This site uses Akismet to reduce spam. Learn how your comment data is processed.