OpenBSD on the Xiaomi Mi Air 12.5"

The Xiaomi Mi Air 12.5" is a basic fanless 12.5" Ultrabook with good build quality and decent hardware specs, especially for the money: while it can usually be had for about $600, I got mine for $489 shipped to the US during a sale about a month ago.

Ars Technica just published a review of this laptop a week ago, so presumably these are becoming more popular.
Xiaomi offers this laptop in silver and gold. They also make a 13" version but it comes with an NVidia graphics chip.

Since these laptops are only sold in China, they come with a Chinese language version of Windows 10 and only one or two distributors that carry them ship to the US. Unfortunately that also means they come with practically no warranty or support.

Hardware
The Mi Air 12.5" has a fanless, 6th generation (Skylake) Intel Core m3 processor, 4Gb of soldered-on RAM, and a 128Gb SATA SSD (more on that later). It has a small footprint of 11.5" wide, 8" deep, and 0.5" thick, and weighs 2.3 pounds.

A single USB-C port on the right-hand side is used to charge the laptop and provide USB connectivity. A USB-C ethernet adapter I tried worked fine in OpenBSD. Whether intentional or not, a particular design touch I appreciated was that the USB-C port is placed directly to the right of the power button on the keyboard, so you don't have to look or feel around for the port when plugging in the power cable.

A single USB 3 type-A port is also available on the right side next to the USB-C port. A full-size HDMI port and a headphone jack are on the left-hand side.

It has a soldered-on Intel 8260 wireless adapter and Bluetooth. The webcam in the screen bezel attaches internally over USB.

The chassis is all aluminum and has sufficient rigidity in the keyboard area. The 12.5" 1920x1080 glossy IPS screen has a fairly small bezel and while its hinge is properly weighted to allow opening the lid with one hand (if you care about that kind of thing), the screen does have a bit of top-end wobble when open, especially when typing on another laptop on the same desk.

While I've seen a review where someone actually complained about it, I love that the lid has no logo on it. There is a "Mi" logo on the front in the center bottom of the screen bezel.
The keyboard has a roomy layout and a nice clicky tactile with good travel. It is backlit, but with only one backlight level. When enabled via Fn+F10 (which is handled by the EC, so no OpenBSD support required), it will automatically shut off after not typing for a short while, automatically turning back once a key is pressed.

The power button is located in the top right of the keyboard and has a white LED illuminating while powered on. While the button feels the same as the F1-F12 keys, it requires much more effort to press than the others, which prevents accidentally pressing it instead of reaching for the Delete key or Backspace.

The glass Synaptics multi-touch touchpad is connected via I2C. The tacile of the touchpad button is solid, with a medium click volume. There is very slight vertical play in the touchpad surface between its resting position and pressing the button. On other laptops I've been able to eliminate that play by adjusting a screw under the touchpad, but I haven't been able to access it on this laptop yet because it's under the battery.

Upgrades
An interesting feature of the Mi Air is that it comes with a 128Gb SATA SSD but also includes an open PCI-e slot ready to accept an NVMe SSD.

I upgraded mine with a Samsung PM961 256Gb NVMe SSD (left), and while it is possible to run with both drives in at the same time, I removed the Samsung CM871a 128Gb SATA (right) drive to save power.

The bottom case can be removed by removing the seven visible screws, in addition to the one under the foot in the middle back of the case, which just pries off. A spudger tool is needed to release all of the plastic attachment clips along the entire edge of the bottom cover.
Unfortunately this upgrade proved to be quite time consuming due to the combination of the limited UEFI firmware on the Mi Air and a bug in OpenBSD.

A Detour into UEFI Firmware Variables
Unlike a traditional BIOS where one can boot into a menu and configure the boot order as well as enabling and disabling options such as "USB Hard Drive", the InsydeH2O UEFI firmware on the Xiaomi Air only provides the ability to adjust the boot order of existing devices. Any change or addition of boot devices must be done from the operating system, which is not possible under OpenBSD. (I saw this same problem on the Samsung ATIV Book 9.)

I booted to a USB key with OpenBSD on it and manually partitioned the new NVME SSD, then rsynced all of the data over from the old drive, but the laptop would not boot to the new NVME drive, instead showing an error message that there was no bootable OS.

After many days of playing with Linux and Windows installations, various GPT partitioning tools, and reading documentation, I learned that the default UEFI boot variable was still pointing to the old SATA drive and was not just a generic "boot BOOTX64.EFI from the first hard drive available" entry. (If you ever install OpenBSD on a newer Windows laptop and it boots to a Windows rescue screen even though you deleted the Windows partition, this is why.)

Creating a new variable that pointed to BOOTX64.EFI on the new NVMe drive was only possible through Linux with the efibootmgr utility, but even then I kept running into the problem of new variables not saving and not showing up in the UEFI setup menu after a reboot. Just for documentation purposes, my current working boot variable looks like:

PciRoot(0x0)/Pci(0x1c,0x0)/Pci(0x0,0x0)/NVMe(0x1,00-25-38-B1-71-B3-A8-BC)/HD(1,GPT,6f23feda-f449-4a2f-9935-21f644af48ea,0x800,0x320000)RC

Eventually I figured out that the GPT table that OpenBSD created on the NVMe disk was wrong due to a one-off bug in the nvme driver which was causing the GPT table to be one sector too large, causing the backup GPT table to be written in the wrong location (and other utilities under Linux to write it over the OpenBSD area). I'm guessing the UEFI firmware would fail to read the bad GPT table on the disk that the boot variable pointed to, then declare that disk as missing, and then remove any variables that pointed to that disk.

After fixing the nvme driver, re-initializing the GPT partition table on the disk, and copying everything back over, I was finally up and running with OpenBSD booting from the NVMe disk.

OpenBSD Support
The Mi Air's soldered-on Intel 8260 wireless adapter is supported by OpenBSD's iwm driver, including 802.11n support. The Intel sound chip is recognized by the azalia driver.

The Synaptics touchpad is connected via I2C, but is not yet supported. I am actively hacking on my dwiic driver to make this work and the touchpad will hopefully operate as a Windows Precision Touchpad via imt so I don't have to write an entirely new Synaptics driver.

Unfortunately since OpenBSD's inteldrm support that is ported from Linux is lagging quite a bit behind, there is no kernel support for Skylake and Kaby Lake video chips. Xorg works at 1920x1080 through efifb so the machine is at least usable, but X is not very fast and there is a noticeable delay when doing certain redrawing operations in xterm. Screen backlight can be adjusted through my OpenBSD port of intel_backlight. Since there is no hardware graphics support, this also means that suspend and resume do not work because nothing is available to re-POST the video after resume. Having to use efifb also makes it impossible to adjust the screen gamma, so for me, I can't use redshift for comfortable night-time hacking.

Since the nvme driver does not yet have a side-effect-free codepath available, there is also no hibernation support. Using the stock SATA drive with the ahci driver should work with hibernation, however.

Flaws
Especially taking into account the cheap price of the laptop, it's hard to find faults with the design. One minor gripe is that the edges of the case along the bottom are quite sharp, so when carrying the closed laptop, it can feel uncomfortable in one's hands.

For some reason USB (type-A) devices stick out quite a few extra millimeters compared to every other laptop I've used, although it doesn't seem to affect functionality.
While all of those things could be overlooked, unfortunately there is also a critical flaw in the rollover support in the keyboard/EC on the laptop. When typing certain combinations of keys quickly, such as holding Shift and typing "NULL", one's fingers may actually hold down the Shift, N, and U keys at the same time for a very brief moment before releasing N. Normally the keyboard/EC would recognize U being pressed after N is already down and send an interrupt for the U key. Unfortunately on this laptop, particular combinations of three keys do not interrupt for the third key at all until the second key is lifted, usually causing the third key not to register at all if typed quickly.

I've been able to reproduce this problem in OpenBSD, Linux, and Windows, with the combinations of at least Shift+N+U and Shift+D+F. Holding Shift and typing the two characters in sequence quickly enough will usually fail to register the final character. Trying the combinations without Shift, using Control or Alt instead of Shift, or other character pairs does not trigger the problem.

This might be a problem in the firmware on the Embedded Controller, or a defect in the keyboard circuitry itself. As I mentioned at the beginning, getting technical support for this machine is difficult because it's only sold in China. I e-mailed Xiaomi's US support address, and got this in return:
I understand your concern and regret the inconvenience you have experienced. I would like to inform you that we are not selling or shipping Mi Air in US region, so we do not have any update regarding the same and we regret to inform you that we would not be able to provide you any assurance for the device. Hence would request you to get in touch with the vendor/website from where the device was bought for support.
via jcs

Post a Comment

Previous Post Next Post