On why open source is great

FOSS Article

~ Caleb Connolly

Phones are amazing things, helping connect us to the people we care about - and those we don’t. If it wasn’t obvious by now, they enable a great deal of the things that make up modern society, and yet they’re increasingly powered by closed source, propretary software, putting us at the mercy of the massive corporations that built out devices.

Mobile computerised devices have a long and exciting history; from gems like the early brick phones, to nuggets like the Nokia N900, it’s been a wild ride. The two biggest players at the minute are Apple and Google (just in case you’ve been asleep for the last 15 years), with Android and IOS being the dominant players in the mobile OS space. We’ll be leaving IOS alone for the purposes of this article, instead focusing on the much more interesting Android story.

Android started out as a comparitively small independant company, but after some initial success they were quickly consumed by Google. Since then it’s grown into the largest (by user) Mobile OS in the world. And, fortunately for us, it’s open source.

Open what

For those that don’t know, open source software has its source code freely available, and usually in a format such that you can go edit and built it yourself. There’s a few awesome examples you’ve probably heard of such as Firefox, VLC media player and more recently Microsoft’s Visual Studio Code. The open source movement is growing and, simultaneously, it’s vital (and getting harder) to ensure that you can protect your privacy in the digital age.

All things considered, aiming to open source your stuff where possible sets a good example to the industry, and lets you directly contribute to society by producing useful software that anybody else can come across and use.

A great open source project

By far the most ubiquitous piece of open source software is the Linux Kernel; not only is it a well loved base for many desktop distributions, it also powers lots of crap you don’t even think about, from IP cameras and McDonald’s menu screens, to smart cars and home media devices. Most importantly, it’s the foundation for Android, and you can see this for yourself if you own an Android phone. Simply navigate to settings, about phone, android version, and look for Kernel Version. You’ll most likely see something like 4.9, 4.14 or perhaps something older. These are all Linux kernel versions.

To add some context to those numbers, at the time of writing the latest Linux version is 5.10, released in December of 2020. There’s a new Linux release about once every 6-8 weeks. Linux 4.9 came out in December 2016! That’s OLD with a capital D, and leads us to our next and final point, and the purpose of this article.

The problem with Linux

I suppose ‘problem’ is not the most logical term, but anyway… Linux is licensed under GPLv2, according to tldrlegal:

You may copy, distribute and modify the software as long as you track changes/dates in source files. Any modifications to or software including (via compiler) GPL-licensed code must also be made available under the GPL along with build & install instructions.

Essentially, you can use it for anything, including commercial products, but you have to release the source code and instructions for whatever product you eventually ship. Most of you will have realised by now that this means the software on your Android phone is almost entirely open source, and you’d be right, you wonderful intelligent human. Except for one small caveat: not all of it actually is…

As an operating system, Linux is pretty great. It runs on a large selection of architectures, SOCs and devices, it’s pretty speedy, and it offers a great platform to build your product on (hence its ubiquity). SOC and device manufacturers have to add support for their new devices to the kernel, so that their device can run Android. Which takes us to our next issue…

The issue with SOC and device manufacturers is that they like to protect their intellectual property. Intuitively, this makes sense, until you consider that, like I said earlier, there will always be someone smarter than you. The uh, ‘problem’ I referred to previously, is exemplified in the case of Qualcomm’s Adreno graphics driver. Rather than writing the driver in the kernel, where they would be forced to release it as open source code, Qualcomm chose the more complicated approach of writing a minimal kernel driver to initialise the hardware and then simply expose it to userspace as a character device. The majority of the driver is then written to run in userspace as propriatery blobs.

The thing is, despite all the trouble Qualcomm have gone to to protect their Intellectual Property, people simply reverse engineered it. The Freedreno driver has been, in my opinion, one of the best examples of how pointless it is to keep this kind of software closed source; sure it doesn’t perform quite as well as the propratery driver, but considering it’s entirely a reverse engineering effort by volunteering developers, I’d say it’s done a damn good job. Without it we wouldn’t have Linux booting with full hardware accelerated graphics on devices like the Pocophone F1 and OnePlus 6.

Bringing Phones Upstream

Android device kernels are absolutely full of unsustainable code… By the time a device ships the number of changes by vendors throughout the manufacturing chain will be massive, and as an end user you’re depending on vendors to maintain all of that code for your device, a tall order for them. We often see Android devices having support dropped after only a few short years (although Google have been pushing to change that for some time now). However if you compare to a device like the Nokia N900, which despite being over a decade old, is supported by the mainline Linux kernel and therefore receives all the benefits of every other Linux device, including regular updates, optimisations, security patches and support!

In the winter of 2019, I first learnt about postmarketOS and, having recently ported SailfishOS to the OnePlus 6 I thought surely booting mainline wouldn’t be too much of a stretch… Boy was I in for a journey.

I prepared some initial changes, creating a devicetree with a framebuffer initialised by the bootloader and tried to boot it. But absolutely nothing happened! A few days of headscratching later and eventually figuring out that the bootloader tries to append it’s own device tree blobs from a partition, sure enough erasing the partition worked! And I was greeted with about 2 seconds of boot logs before the phone promptly crashed…

The following is designed to be a rough overview of the bringup and porting process of a device like the OnePlus 6, culminating in patches being merged upstream for the device!

Booting up

After some debugging, and asking the wonderful people in ##linux-msm, the problem appeared to be MMU related, disabling the SMMU allowed the device to boot with the display up! And some tweaking later gave us USB gadget mode and UFS storage. With that we’re into postmarketOS!

The next steps

With the initial bringup done, we could now boot into a rootfs and control the device through SSH, but that hardly makes for a usable phone… Now it was time to get some more hardware working, and the most obvious candidate was the touchscreen. Luckily for me the OnePlus 6 uses a Synaptics touch screen, that should work just fine with the existing rmi4 driver on mainline! My friend had recently got it up and running on the OnePlus 5 too, so with wide eyes I booted up, and it didn’t work. The driver didn’t even try and probe.

A little lost and confused I retreated for a few days. Eventually I got the guts to sift through the downstream kernel and driver, eventually I spotted a suspicious looking line in the devicetree, it turns out the OnePlus 6 touch screen is somehow powered via a GPIO (either directly or through a regulator), and that gpio needs to be pulled high! And with that done the touchscreen probed successfully.

The modem and display followed, with similar hiccups, the modem would cause the device to crash as soon as it got booted, this turned out to be yet more OnePlus quirks, moving the reserved memory for the modem to a different address, the display required some tweaking after using a useful driver generator tool to convert the downstream devicetree node for the display panel into a drive compatible with mainline.

So now what?

At this point, the OnePlus 6 is up and running with wifi, bluetooth, hardware accelerated graphics and a rudimentary battery driver, not quite enough for a usable phone, but certainly a start. The next steps are to get the speakers, haptics and perhaps some other sensors working. And with any luck some work in progress ModemManager patches will give us proper modem support for phone calls and maybe even mobile data! It seems we’re impressively close to a fully open source experience, and on a phone that’s not even 3 years old.

As of 17/01/2021 the OnePlus 6 has had both display panel drivers accepted, and most recently initial device support merged, which will mean as of Linux 5.12(?) it will be possible to build and boot the kernel on the device with NO extra patches!

You can check out more info on the device here: https://wiki.postmarketos.org/wiki/OnePlus_6_(oneplus-enchilada)

And follow along with kernel development here: https://gitlab.com/sdm845-mainline/sdm845-linux/-/tree/op6-working

postmarketOS are “Aiming for a 10 year life-cycle for smartphones”, by getting them upstream and allowing phones to get the same update and security benefits that all upstream Linux devices do, we make it possible for them to be supported for basically as long as the kernel supports them. However if it takes 4+ years to get a new device actually usable and upstream, that’s a pretty significant chunk. By encouraging vendors to be more open to open sourcing and upstreaming their devices, we can reduce that time, as well as taking some load of OEMs to maintain their SoCs on top of the kernel themselves.