Home Artists Posts Import Register

Content

A lot of things have happened behind closed curtains since the initial GPD XD 8.1 Beta #1 proof of concept release 2½ weeks ago. Way more than I thought possible actually, and today's the day I will try to de-mystify the on-goings as much as possible, as well as elaborate how all of this was achieved in the first place (for those of you that are technically inclined).

As with all of my work, its never a question of whether it can be done, but more of a "Is there enough time to make it good?" type of thing, and up until now the original GPD XD had to wait in line because there's only so much time available in my schedule to work on these things.

With GPD XD+ having reached Android 11 and it being pretty stable (sans secure lockscreen support, which I'll revisit in the future), it was time to give its older sibling the same treatment.

The biggest issue I've faced in doing so was the lack of drivers I could "borrow" from other devices, the RK3288 SoC used in the original GPD XD has been pretty much abandoned for a while now, and with nothing but ancient out of date drivers to pick from bringing this device up in a meaningful way would have been quite a time-consuming task, even more than it already is.

Enter the RK3399 SoC, to be more specific, the Firefly-RK3399 breadboard. We got quite lucky there, as the people over there leaked a set of RK3288-compatible binary drivers with that SDK, which allowed me to fast-track the GPD XD bring-up by a good bunch.

But don't misunderstand me here, this leak didn't mean we were handed a fully working system on a silver plate, it just gave us some essential puzzle pieces to build around. It's comparable to buying a Star Wars Lego set on eBay and then realizing its missing half the pieces, but those pieces can be replaced by hand-crafted alternatives, which is exactly what I've done.

Ever since then I've been filling the gaps, taking bits and pieces from all over the place, re-writing code to match the GPD XD hardware and overall just polishing things to present all of you with the best possible software to go along with your GPD XD's hardware.

There's been many hurdles on the way, and countless hours have been sunk into overcoming them. This section of the newsletter will explain some of the more tricky ones I've encountered and how I've solved them.

Getting the foot in the door

It's been years since I last actively developed for a Rockchip-based SoC, that was way back when these chipsets first rose to popularity in HDMI smart-dongles for "Dumb-TVs". My memories at that point were pretty much a blur of what they used to be, but I had a pretty good idea where to start at least.

I still remembered all the basic things. I remembered that the boot images were split into a gzipped-ramdisk, a shared kernel and a separate, split off resource image containing the device-tree-binary and early-boot images. I also remembered that the boot images (and several other images) needed a MKRNL / MKPARM style signature to boot and that the boot process was split between a MiniLoader and uboot bootloader.

After getting my work environment all set up it was time to do some reconnaissance work, so I went through all the existing resources out there, took a dive into LegacyROM and the previously released 7.1 alpha by phhusson, and started investigating the kernel image for any info that could be of use.

I took notes of the partition layout the device shipped with, the device names and their mapped memory regions, and started work on a 8.1+ compatible kernel, cherry-picking all the required drivers and patches to make booting 8.1+ a possibility.

It took long enough, and I don't want to bore you with any additional details here, as its essentially just me spending countless trial and error hours in my man-cave until, at last, I made it to the Android 8.1 homescreen.

At that stage nothing else worked yet, no sound, no gamepad input, and pressing the power button or closing the lid crashed the system, but it was a start.

The hurdles I've encountered (and still do)

At this point in time I started taking notes of everything I could find. I curated a list of everything that was broken (in one way or another) and ordered the points from most severe down to the smallest infractions I could find.

I spent a lot of time, slowly ticking off one point on my to-do list after another, and as I went along, I was able to see it all come together into what I have in front of me right now. (I hope I can get it all packed up and ready for you guys soon!)

There's been countless hurdles, and to go in depth with each and every one of them would take way too much time, but here's a list of some of the bigger ones I can remember off the top of my head.

Offline charging

Those using the recently released Beta #1 build will know that it can be quite tricky to get the unit up and running again after the battery has been flat-lined, aka, fully driven down to 0%.

This is because the newer MiniLoader + uboot required for Android 8.1 doesn't support offline charging out-of-box, which means, every time you plug a USB cable in, it will automatically try to boot into full-blown Android, which is quite difficult to do if your battery is completely flat.

It took some time, but I managed to build a custom MiniLoader + uboot from source which restored this lost functionality in its entirety, bringing back the traditional battery charging screen, allowing you to charge the device up enough to make booting Android a possibility.

This would, of course, also work without offline charging, but only if enough juice is provided, we're talking 5v@2a here. With offline charging though, a mere 5v@500ma should be able to do the job, making Android 8.1 a lot more accessible to the average user.

Sound output (still WIP)

The way sound output works in Android is by having a top layer (Android) access a bottom layer (the kernel driver) through a myriad of additional wrapping layers in the middle (usually a audio HAL wrapping a PCM/ALSA interface).

This was the exact same here, but we had no existing audio HAL we could use here, so again, I had no choice but to make my own from scratch.

It ain't perfect yet (HDMI audio output doesn't work, in fact, it crashes HDMI output at the moment if you try) but it works "good enough" for the time being.

I based the audio HAL off a RT5640-based one and patched all the routes to match what the RT5631 soundcard in the GPD XD expects.

It's definitely one of those parts I will have to revisit in the future.

Sleep mode / suspend (still WIP)

This one is one of the biggest issues plaguing me right now, getting this build to be more battery efficient. While active use screen time is pretty good, standby battery consumption is pretty much identical to active use screen time right now, which makes it look pretty shabby when compared to something like LegacyROM.

This is because a lot has changed in the Linux kernel since the time the GPD XD has been in its prime. Back then suspend and resume code was handled by a very device specific suspend and resume binary which was mostly written in machine code. The upstream Linux kernel has moved far far away from this implementation over the last few years, heavily favoring a more recent suspend rewrite that uses something called a global power switch to toggle in and out of deep sleep mode.

This new implementation requires an additional GPIO pin to be wired on the motherboard though, so using this new implementation is pretty much a no-go, as I can't expect you, my audience, to get a soldering iron out and start reworking your GPD XD motherboard. And for those that say, yes I could, trust me, I can't... its quite a bit more in-depth than you guys might think.

Which left me with two options: Either roll back all my work and fall back to a way older ancient Linux kernel to get the older suspend code back up and running, or go the opposite direction and backport a bunch of Linux kernel 5.x patches to get us proper s2idle support baked in.

For those wondering what s2idle support means, its essentially a semi-suspend-sleep-mode introduced with newer Linux kernels which is hardware-agnostic, which means it works on pretty much every chipset and doesn't require OEM-specific code to function.

I've decided to go with this route, as it allows us to move forward rather than be forever stuck with outdated code. It will take some more time to work this one out fully though.

The GPD XD touchscreen mapper / gamepad driver

Getting the gamepad buttons mapped to the gpio-input driver was easy enough, and for me personally, that would have been enough already (as I never really use GPD's touchscreen mapper), but I knew that this feature is a fan-favorite, along with the option to toggle the gamepad between several modes, so I took some time out of my schedule, added a few after-work hours and ported the driver, the overlay, and the CleanROM menu over, essentially fully restoring this feature.

What else can I say?

It works now, and the upcoming Beta #2 build will bring it to all of you soon enough.

All things summed up

We're making big strides here, but not everything's quite ready yet, so I beg all of you to be patient for just a while longer as I work out the issues mentioned above (and several others that didn't make the cut for this newsletter).

I expect the next build to be ready in a week or two (the latter being more likely), and while a lot of things are already working fully there's still a handful of things I want to polish some more before handing them off to all of you.

I will see all of you then, and as always, I will keep you guys posted!

- Black-Seraph

Files

Comments

Anonymous

Very good work done to the GPD-XD+! Thanks a lot for the Investigation in the deep! It is much fun to read and of course interesting to understand how difficult things are built and interfere one to another. So thanks a lot one more and keep the good work going. I'm glad to the future of our loved device.