Skip to content

Releases: vahiru/gaokun-android

v1.0.0-rc.2 (release candidate)

Pre-release

Choose a tag to compare

@vahiru vahiru released this 25 Oct 09:31

Android 16 (crDroid) for the Huawei MateBook E Go (Snapdragon 8cx Gen 3 /
SC8280XP) on a mainline Linux kernel, with hardware Vulkan on the Adreno 690.

The second release candidate for 1.0. Compared with 1.0.0-rc.1: the
M-Pencil stylus has a driver
, palm rejection in the touch driver,
Wi-Fi stays connected in standby and recovers from firmware crashes,
lower standby power (the audio DSP can sleep now), a lower-latency audio
path for rhythm games
, the USB-C port next to the power button is back to
USB 3 with several role-switching fixes and file transfer over USB,
there is a switch between game and everyday touch feel, and Wild Rift
no longer closes at launch. To get past some games' environment checks, the kernel now
reports a disguised version string — see below.

Talk to us: Telegram · QQ group 920133252

⚠️ Release candidate — now offered by System update

Everyone on v0.7.1-alpha or 1.0.0-rc.1 is offered this build in System
update
, and the graphical installer downloads it over the network. It is
still a release candidate: if you depend on the machine every day, you can
stay where you are by not installing the update.

Back up before updating from v0.7.1-alpha. The step from 0.7.x to 1.0
changes a lot at once: it puts the new boot entry on the EFI partition,
switches SELinux to enforcing and moves to a release build (no root over
adb). This path has not been rehearsed on real hardware. If the updated
system does not start, choose the previous Android entry in the boot menu
(needs a keyboard) or reinstall with the graphical installer. Coming from
rc.1, the update has not been tried either, so back up anyway.

A fresh install erases the internal disk (unless you use the graphical
installer's dual-boot mode), and no image of the factory state exists anywhere.
You should be comfortable recovering a machine that will not boot. No warranty.
Any BIOS version works. Secure Boot must be off.
Instructions: docs/INSTALL.md
(中文) ·
Before installing, read what does not work ·
FAQ

How to install it. Already on v0.7.1-alpha or rc.1: Settings → System →
System update
. Otherwise start the graphical installer (from a USB stick, or
from Windows with the Windows package — see INSTALL) and choose Reinstall
Android
if Android is already on the disk (it wipes your data by default;
tick Keep user data to keep it), or Erase the whole disk / Keep the
current system
(dual boot) for a fresh install. The USB image
gaokun3-installer-0.2.0-rc.2-usb.img.xz carries this build and installs
without a network; the Windows package downloads it.

Feedback: open an issue with the
issue forms.
Write v1.0.0-rc.2 as the release and paste the build stamp the form asks for.
Reports that something works are useful too — many items below say "not
tested on hardware yet".

How this candidate was tested

Installed on the developer's machine on 2026-10-25 (an update over the
previous candidate build, not a fresh install). On this exact build: release
acceptance (A tier: 47 passed, 0 failed, 1 warning, 1 skipped); the new
touch-feel switch, both ways (the driver settings follow it at once). The
warning lists SELinux denials: the two known ones, plus third-party apps
installed on that machine probing the system and being refused, as they
should be. Not run on this build: the stylus and palm rejection with a real
pen and hand; USB file transfer, tethering and MIDI; USB-C role switching with
peripherals; standby with Wi-Fi (checked on the previous candidate build); the
rhythm-game latency measurement; fresh installs with the installer on real
hardware; dual boot with Windows; the 0.7.x → 1.0 update.

Stylus and touch

  • The Huawei M-Pencil works (pressure, hover, tilt, side double-tap) — it
    is sensed by the touch screen's second controller chip, which now has a
    driver, plus a small service that handles the pen's charging/pairing
    controller. Tested by the contributor on their own machine with the same
    code; not tested on this build with a real pen yet.
  • Palm rejection: a palm or the side of a hand on the screen is now
    recognised, and touches that turned out to be part of it are withdrawn (apps
    see a cancel, not a tap). The game touch preset turns this off so that a
    thumb near the edge is not swallowed. Tested by the contributor; not on this
    build yet.
  • Touch feel switch: Settings → System → Touch feel (and a Game touch
    quick settings tile) switches between the game preset (default: no coordinate
    smoothing, no palm rejection, about 25 ms less lag) and the everyday preset
    (smoother lines, palm rejection on). It applies immediately and survives
    restarts; before, this needed an adb command with root. Tested on this build.

Wi-Fi and standby

  • Wi-Fi stays connected in standby. Before, every standby disconnected
    Wi-Fi and powered the chip off, and it reconnected on every wake. Messages
    still arrive only when the system wakes up on its own — data from the network
    cannot wake the machine yet (see Known issues). Tested on this build.
  • If the connection drops during standby, the tablet now reconnects with the
    screen off
    ; before, it stayed offline until the screen came on. When the
    Wi-Fi firmware occasionally declines to go into its standby mode, that
    standby is retried a moment later instead of dropping the connection.
    Tested by the contributor; not on this build yet.
  • Wi-Fi firmware crashes are recovered from, also when they happen during
    standby. Before, a crash could take the kernel down or leave Wi-Fi dead
    until the next cold boot. Tested by the contributor (with injected crashes).
  • The audio DSP can sleep, so standby uses less power: the audio codecs
    no longer keep it awake. Tested on this build (the DSP's sleep counter now
    moves; it stayed at 0 before). How much battery this saves has not been
    measured on this build; the contributor measured about 0.63 W in standby
    with this and the Wi-Fi changes, against about 0.74 W before.

Audio

  • Lower output latency for games: a game asking for low latency now gets
    Android's fast mixer path; measured output latency went from about 317 ms to
    about 110 ms on the development build. Not re-measured on this build.
Read more

v1.0.0-rc.1 (release candidate)

Pre-release

Choose a tag to compare

@vahiru vahiru released this 06 Oct 12:52

Android 16 (crDroid) for the Huawei MateBook E Go (Snapdragon 8cx Gen 3 /
SC8280XP) on a mainline Linux kernel, with hardware Vulkan on the Adreno 690.

The first release candidate for 1.0. Compared with v0.7.1-alpha: release
builds no longer open adb to the network
, SELinux is enforcing, the
machine has its own boot entry that rolls back a failed update by itself
and a fastboot mode, the kernel moves to 7.2.9 stable, and Wi-Fi keeps
the same MAC address across reboots.

Talk to us: Telegram · QQ group 920133252

⚠️ Release candidate — for people who want to help test

This build is for testers. It is not offered by System update — the
update server still points at v0.7.1-alpha — so nobody gets it by accident,
and you install it by hand (below). If you depend on the machine every day,
wait for 1.0.

A fresh install erases the internal disk (unless you use the graphical
installer's dual-boot mode), and no image of the factory state exists anywhere.
You should be comfortable recovering a machine that will not boot. No warranty.
Any BIOS version works. Secure Boot must be off.
Instructions: docs/INSTALL.md
(中文) ·
Before installing, read what does not work ·
FAQ

How to install it. Start the graphical installer attached to this
pre-release (from a USB stick, or from Windows with the Windows package — see
INSTALL) and choose:

  • Reinstall Android, if Android is already on the disk. It wipes your data
    by default; tick Keep user data to keep it.
  • Erase the whole disk or Keep the current system (dual boot) for a
    fresh install.

Use this installer (version 0.2.0-rc.1). Over Wi-Fi an installer
downloads the latest published release, which is still v0.7.1-alpha — and
so would the gaokun3 installer entry left on your disk by an earlier
install, which runs the older installer. So:

  • USB stick: gaokun3-installer-0.2.0-rc.1-usb.img.xz carries the rc.1
    system (that is why it is 1.6 GB) and installs it without a network.
  • Windows package: it does not carry the system. Before running
    gaokun3-setup.cmd, put boot.img, super.img.zst and
    install-artifacts.sha256 from this release into a folder named payload
    next to it (INSTALL, "Offline install"); otherwise you get v0.7.1-alpha.

Coming from v0.7.1 or earlier: back up first. Neither way up from 0.7.x
has been rehearsed on real hardware yet — not the update path that 1.0 will
use, and not reinstalling over v0.7.1 with Keep user data. Copy off what
you cannot lose. Going back to an older version afterwards is not supported
with your data kept.

Feedback: open an issue with the
issue forms
(Bug report, Install / boot failure, Hardware feature report). Write
v1.0.0-rc.1 as the release and paste the build stamp the form asks for.
Reports that something works are useful too — many items below say "not
tested on hardware yet".

How this candidate was tested

Every "tested on the machine" below was checked on the 1.0 development builds
(1.0.0-dev.1 to dev.10) on the developer's machine; which build is noted in the
source of these notes. rc.1 is dev.10 plus the fixes listed under Chinese
input
and SELinux. Results for rc.1 itself: ⬜ to be added after its
acceptance run.

Security advisory: network adb on v0.7.1 and earlier

v0.7.1-alpha and every earlier release let anyone on the same network take
over the machine.
Those images listened for adb on TCP port 5555 on every
network interface — your hotspot included — accepted connections without
the "Allow USB debugging?" prompt, were debuggable (so adb root gave a root
shell), and carried the maintainer's adb public key.

This build, like every 1.0 release build:

  • does not listen on port 5555, and adb is off until you turn it on in
    Developer options;
  • asks you to authorize every computer (ro.adb.secure=1);
  • is not debuggable (ro.debuggable=0), so adb root no longer exists;
  • carries no maintainer key.

Nothing to do when you install it: the old port-5555 setting was a built-in
default of the image, and Android does not save those defaults to /data.
The exception is anyone who ran setprop persist.adb.tcp.port …
themselves
— that value is stored on /data and survives a reinstall with
Keep user data. How to clear it will be added to the known-limitations page
(⬜ not yet verified on hardware).

If you use adb:

  • After installing, adb over the network stops working until you set up
    Wireless debugging (pairing code) or authorize a computer over USB.
  • An authorized computer still gets a root shell: root (KernelSU /
    ReSukiSU) is built in, and adb shell runs as root through it even though the
    build is not debuggable. Only authorize computers you trust.
  • USB debugging switches itself back off at every reboot (⬜ not yet confirmed
    on hardware).

SELinux is enforcing

v0.7.1 and earlier ran SELinux in permissive mode: it only logged what its
rules did not allow. From this build it is enforcing — it blocks those
things, so an app that finds a vulnerability can do much less than before.

Tested on the machine with SELinux enforcing: display, touch, Wi-Fi, sensors,
audio, hardware video decoding (15/15), front and rear cameras, standby and
wake 11/11 (including USB role switching and replugging), and installing a
system update. Two kinds of denials remain in the log, both from stock Android
components (reading the keyboard's country, and a cache of the secure-element
service); they broke nothing in these tests.

If you partitioned the disk by hand: under enforcing, Android can only open
the EFI partition when its G...

Read more

v0.7.1-alpha — Standby no longer hangs, Wi-Fi hotspot, USB apps, rhythm games in sync

Choose a tag to compare

@vahiru vahiru released this 04 Oct 07:35

Android 16 (crDroid) for the Huawei MateBook E Go (Snapdragon 8cx Gen 3 /
SC8280XP) on a mainline Linux kernel, with hardware Vulkan on the Adreno 690.

A bug-fix release: standby no longer hangs the machine, the Wi-Fi hotspot
works
, apps that use USB stop crashing, and rhythm games stay in sync with
their music.

Talk to us: Telegram · QQ group 920133252

⚠️ Alpha

A fresh install erases the internal disk (unless you use the graphical
installer's dual-boot mode), and no image of the factory state exists anywhere.
You should be comfortable recovering a machine that will not boot. No warranty.

Any BIOS version works. Secure Boot must be off.
Instructions: docs/INSTALL.md

Coming from v0.2.x – v0.7.0: update in Settings, nothing else to do.

Standby

Waking from standby could hang the machine for good — black screen, only a
long press of the power button helped (#16,
thanks to @niceboat0 for the complete crash log). Three things lined up:

  • On every wake the Wi-Fi chip is powered back up and its firmware reloaded,
    which needs several large blocks of contiguous memory below 4 GB — and memory
    cannot be defragmented while the machine is waking. After a long uptime those
    blocks were sometimes not there, and Wi-Fi failed to start.
  • A debugging setting had been left in the kernel: if any device took more than
    10 seconds to wake, the kernel gave up and crashed on purpose. A Wi-Fi chip
    that failed to start triggered exactly that.
  • After a crash, the kernel waited forever instead of restarting.

All three are fixed. The Wi-Fi driver now keeps its firmware buffers through
standby instead of giving them up and asking again, and the memory pool reserved
for exactly this kind of request (CMA) — which the device tree had placed above
4 GB, out of reach of the Wi-Fi chip — now sits below 4 GB. Over three wakes,
the number of such large memory requests went from 69 to 0. The watchdog is back
to its default 120 seconds, and if the kernel ever does crash it now restarts
after 10 seconds instead of hanging (the crash log is still saved).

Tested on this build: 10 standby/wake cycles, Wi-Fi back within about 2 seconds
each time. The original hang took about 14 hours of uptime to show up, so
reports from long-running machines are very welcome.

Wi-Fi

  • The hotspot works (#11,
    thanks to @niceboat0). The hotspot service (hostapd) had never been
    included. Turning on the hotspot disconnects the machine from Wi-Fi: the chip
    runs either as a hotspot or as a client, not both.
  • Routers in WPA2/WPA3 mixed mode should connect. Android upgrades a saved
    WPA2 network to WPA3 when the router offers both, and on such routers the
    connection was rejected. That upgrade is now off; pure WPA3 networks still use
    WPA3. Not tested here (we have no mixed-mode router) — please tell us if it
    works for you.

Audio

Rhythm games stay in sync. Under load the audio driver could skip a whole
block of music (about 85 ms) whenever the game delivered audio a little late,
and it told apps where playback was from what they had sent rather than from what
was actually playing. Games that time notes against the audio clock (Arcaea,
Phigros) saw an offset that was large and kept jumping. Playback is now paced by
the sound hardware itself, nothing is dropped, and the reported position is the
real one. Measured in Arcaea: 7 skipped blocks → 0; with a speaker-to-microphone
loopback the reported timing is about 30 ms more accurate, and after a stall the
very next sound is back in place (before: about 8 seconds of misplaced sounds).
If you calibrated a game's audio offset on an earlier release, calibrate it again.

USB

Apps that use USB no longer crash on start (#13,
thanks to @niceboat0). Android's USB service was never started, so asking
for it returned nothing; apps that did not expect that — the China Telecom cloud
desktop (天翼云电脑) among them — crashed immediately. Apps should now also be able to
use USB devices plugged into the machine (with the usual permission prompt). We
checked that the service runs and lists connected devices; we have not run the
cloud desktop app itself.

Smaller things

  • System updates on dual-boot or hand-partitioned disks: when the disk has
    both a Windows boot partition and a separately named one for Android, the
    update could pick the wrong one. It now checks which one actually holds the
    Android boot entries. (Not yet tested on a real dual-boot machine.)
  • SELinux: another round of rules and labels towards enforcing. Disks set up by
    the graphical installer now get correct partition labels, and the camera works
    in an enforcing trial. The system still runs permissive.

Known issues

  • SELinux is still permissive.
  • League of Legends: Wild Rift closes right after launch (reported, no log
    yet). If you can, send adb logcat -b crash from right after it closes.
  • No auto-brightness. The light sensor answers on the bus, but activating it
    crashes the sensor DSP, so it stays off.
  • Erase all data (factory reset) in Settings does not work — this machine has
    no working recovery. Use the graphical installer's Reinstall Android instead.
  • Audio (and Bluetooth) can deadlock after long uptime; a watchdog records the
    evidence under /data/vendor/gaokun3/hangdump-* — please attach it if you hit
    this.
  • A palm resting on the screen fragments into several touches.
  • Rear camera image quality is not tuned yet: no colour calibration, dim scenes
    are noisy, flash shots overexpose; autofocus in the dark is slow.
  • Hardware video encoding is still off.
  • After replugging, the USB-C port can stop working (no USB adb, no USB
    devices) until a reboot. Unchanged from v0.7.0.
  • Wi-Fi gets a new MAC address on every boot, so routers see a "new device"
    each time.

Files

The in-system updater will offer this build; nothing here is needed for a normal
update. For a fresh install you want super.img.zst and boot.img.

File What
crDroidAndroid-16.0-20261003-gaokun3-v12.11.zip (1.26 GiB) OTA package, also what the in-system updater downloads
super.img.zst (1.20 GiB) system / system_ext / product / vendor, for a fresh install
boot.img (27.5 MiB) kernel + device tree + first-stage ramdisk
install-artifacts.sha256 checksums of the three files above
gaokun3.json the updater manifest for this build

Build stamp 1791053208, incremental 20261003184648. The checks above were run
on a machine running exactly this build. Not run on it: a phone actually joining
the hotspot, a WPA2/WPA3 mixed-mode router, the cloud desktop app, and a real
dual-boot disk.

The graphical installer is unchanged — use 0.1.0-preview from
v0.7.0-alpha.

v0.7.0-alpha — New video decoder driver, working microphone, rear-camera autofocus, installer preview

Choose a tag to compare

@vahiru vahiru released this 28 Sep 17:06

Android 16 (crDroid) for the Huawei MateBook E Go (Snapdragon 8cx Gen 3 /
SC8280XP) on a mainline Linux kernel, with hardware Vulkan on the Adreno 690.

This release brings a new hardware video decoder driver that handles stopping,
seeking and replaying reliably, a working built-in microphone, the rear camera's
autofocus, a speaker enhancement you can switch on — and the first preview
of a graphical installer that can install next to Windows.

Talk to us: Telegram · QQ group 920133252

⚠️ Alpha

The command-line installer (and the graphical one's Erase the whole disk)
erases the internal disk, Windows included, and no image of the factory
state exists anywhere. You should be comfortable recovering a machine
that will not boot. No warranty.

Any BIOS version works (the 2.16-only rule has been lifted). Secure Boot must be off.
Instructions: docs/INSTALL.md

Coming from v0.2.x – v0.6.2: update in Settings, nothing else to do.
(v0.6.3 was never released; everything planned for it is in this release.)

Video

Hardware video decoding moved from qcom-venus to qcom-iris, the upstream
driver that now supports this chip. Out of the box it hung or crashed this
machine's (Huawei-signed) video firmware on stop and on seek, and lost the picture
on replay; we fixed all three — two places where the driver and the firmware
disagree, and one plain driver bug — so it now behaves as qcom-venus did:

  • Stopping a video mid-stream does not hang the video firmware.
  • Seeking does not crash the firmware.
  • Seeking after the end of a video (replaying it) shows the picture, and every
    later end of stream is reported.

Tested with H.264, HEVC and VP9, including mid-stream resolution changes, and the
video block still powers down between videos. VP8 is no longer hardware
decoded
: the new driver does not support it on this chip, and VP8 video now uses
the software decoder, which handles it easily.

Microphone

The built-in microphones record. Recording used to produce empty files. The
audio HAL now honours the microphone the audio policy picks, captures at the rate
the hardware actually runs at, and hands captured audio over as soon as it arrives
— so recordings no longer start with a fraction of a second of silence and no
longer lag by ~120 ms. Thanks to @mashen11 (PR #10).

Speaker enhancement (experimental)

An optional sound processing chain for the built-in speakers, built by
@mashen11 (PR #7, #8) around the Huawei Histen processing the Windows driver
uses. His comparison measurements against the Windows audio are included; the
shipped defaults are deliberately conservative (150 Hz high-pass, +4 dB) rather
than matched to Windows. It is off by default: Settings › Sound ›
Speaker enhancement (experimental)
; switching it on takes effect from the next
playback. Only the built-in speakers are processed — headphones, Bluetooth and
USB audio are passed through untouched.

Graphical installer (preview)

A touch-friendly installer with a Material Design 3 interface, running from its
own small Linux system. What it adds over the command-line installer:

  • Dual boot: install into free space next to Windows (or shrink a partition
    first — it refuses a hibernated or Fast-Startup Windows volume, which would
    get corrupted).
  • No USB stick needed: from Windows, gaokun3-setup.cmd puts the installer
    on the internal disk — taking only the half a gigabyte or so it needs — and
    boots into it once; you make room for Android in the installer.
  • Reinstall Android in place, wiping data by default or keeping it.
  • Adjust the disk by hand, and download the system over Wi-Fi instead of
    carrying it on the medium.

It is a preview: only reinstalling while keeping data (from the medium and
over the network) has been done on hardware, with an earlier build of the
installer. Reinstalling with data wiped (the default), dual boot, erasing the
whole disk and adjusting or shrinking partitions have only run on test disks. The
Windows script ran in a Windows 11 ARM virtual machine in an earlier form; its
current "only its own space" default and the encryption and Fast Startup steps
have only unit tests, and the one-time boot is unverified on Huawei's firmware.
The USB image has not been booted yet. The command-line installer is what every
earlier release was installed with; it now runs on the same backend as the
graphical one.
Details: docs/INSTALL.md.
Reports are very welcome — include the version from the bottom of the side bar
and gaokun3/diag/installer.log from the medium.

Camera

The rear camera focuses. It has a voice-coil motor that nothing drove until
now. The camera HAL runs contrast-detect autofocus on the frames itself (the
software ISP produces no focus statistics): continuous focus in preview, and a
focus trigger (the shutter button, or a tap in apps that send one) locks focus on
the whole frame — tapping does not pick the point to focus on. The focus state reaches apps the way
Camera2 specifies, so apps that wait for "focus locked" before taking the
picture no longer time out. Front camera: fixed focus, as the hardware is.
Thanks to @mashen11 for the motor bring-up and calibration (PR #6).

Photos are the right way up (checked by eye on the front camera; on the rear,
by image size and the preview's orientation). The HAL now applies the rotation the app asks
for (JPEG_ORIENTATION) to the pixels. Previously every photo came out in the
sensor's native orientation regardless of how the tablet was held.

Rotating the tablet should no longer crash the camera. Reconfiguring the
session (which apps do on rotation or when switching cameras) deadlocked the HAL;
that deadlock is fixed, but we have not re-tested rotation on the device.

USB

USB adb now usually survives unplugging and replugging. After any USB role change the
controller was left unable to start the device side again — which is why
reconnecting the cable used to need a reboot. The controller now uses the USB 2
clock it actually has (the USB 3 PHY clock can belong to DisplayPort), and the
data role follows what is really on the other end: a computer enumerates us as
a device; a hub or a flash drive should get us as the host (designed for, not yet
tried with real hardware). One case is not fixed yet: in one of our two real
replug tests (both after standby) the port ended up in that state again — see
Known issues.

Smaller things

  • The device declares itself a tablet (ro.build.characteristics=tablet).
    Apps that choose a tablet layout or tablet login from this should now do so;
    QQ is the case reported in #5,
    not yet confirmed.
  • Faster downloads on high-latency connections, including the in-system
    update: Wi-Fi TCP buffers were Android's defaults, which cap a single
    connection at about 3.5 MB/s when the server is ~300 ms away. Measured on the
    same link: 3.5 → 9.5 MB/s.
  • Fresh installs made with install-gaokun3.sh now get the full kernel command
    line from boot.img; installs of v0.6.2 made that way were missing the touch
    contact-size axes until their first update.
  • The clock syncs in mainland China: besides time.android.com (unreachable
    there) the system now also asks Aliyun, Tencent and the National Time Service
    Center.
  • The device's own settings pages (Detachable keyboard, Speaker enhancement)
    now look like the rest of Settings, with the new Material 3 Expressive
    switches.
  • SELinux: another round of rules and labels towards enforcing, from a full boot
    audit and an enforcing trial run (still permissive).
  • Standby stays on by default, as before. The switch was renamed: if you had
    turned standby off with persist.gaokun3.allow_suspend=0, set
    adb shell setprop persist.vendor.gaokun3.allow_suspend 0 again.

Known issues

  • SELinux is still permissive.
  • No auto-brightness. The light sensor now answers on the bus, but activating it
    crashes the sensor DSP, so it stays off. A copy of the sensor registry from a
    machine that still has Windows would help us compare — if that is you, please
    get in touch.
  • Erase all data (factory reset) in Settings does not work — this machine has no
    working recovery. Use the graphical installer's Reinstall Android (preview; wipes data
    by default) instead.
  • Audio (and Bluetooth) can deadlock after long uptime; a watchdog records the
    evidence under /data/vendor/gaokun3/hangdump-* — please attach it if you hit
    this.
  • A palm resting on the screen fragments into several touches.
  • Autofocus in the dark is slow to settle (the only focus signal is image
    sharpness, and dark frames are mostly noise).
  • Rear camera image quality is not tuned yet: no colour calibration, dim scenes
    are noisy, and flash shots overexpose.
  • Hardware video encoding is still off (apps record with the software encoder).
  • If the video firmware ever does crash, hardware decoding may stay unavailable
    until a reboot (the driver's firmware restart is not always successful).
  • After replugging, the USB-C port can stop working (no USB adb, no USB
    devices) until a reboot. It does not happen every time: plugging the cable back
    in after standby worked in one of our two tests and not in the other, and we
    have not yet confirmed that standby is what triggers it. Charging should
    continue (the embedded controller handles it, not this USB controller), though
    we did not check it in that state. The detachable keyboard is on a different
    controller and keeps working.

Files

The in-system updater will offer this build; nothing here is needed for a normal
update. For a...

Read more

v0.6.2-alpha — Touch: fast swipes no longer break up, fuzz measured to 0, contact size reported

Choose a tag to compare

@vahiru vahiru released this 16 Sep 15:50

Android 16 (crDroid) for the Huawei MateBook E Go (Snapdragon 8cx Gen 3 /
SC8280XP) on a mainline Linux kernel, with hardware Vulkan on the Adreno 690.

This is the touch release. Everything in it was measured on the device rather
than tuned by feel, and the driver can now show its own work.

Talk to us: Telegram · QQ group 920133252

⚠️ Alpha

Installing erases the internal disk, Windows included, and no image of the
factory state exists anywhere. You should be comfortable recovering a machine
that will not boot. No warranty.

BIOS must be 2.16 — do not upgrade to 2.17. Secure Boot must be off.
Instructions: docs/INSTALL.md

Coming from v0.2.x – v0.6.1: update in Settings, nothing else to do.

Touch

If you have been on v0.6.1 you may have noticed lists that would not fling,
gestures that cancelled half-way, and "ghost" taps appearing along a fast
swipe. Those were one bug, and it was ours.

Fast swipes no longer break up. The touch preset we shipped enabled the
driver's jump detection with a threshold that, because the test compared raw
displacement rather than deviation from the predicted position, acted as a
1.0 m/s speed limit. Above it the driver reported no contact at all, and a
single flick arrived at Android as a dozen separate touches — which is exactly
what a cancelled fling, a dropped gesture and a phantom tap look like. Measured
on the device: the same 8 seconds of flicking produced 87 touches before and 6
after. The test now compares against the predicted position, so it catches a
real finger swap at any speed and never fires on a smooth slide
(#114).

Slow drags track the finger. The driver hard-coded an input fuzz of 8 —
a value chosen so that libinput on desktop Linux would not read a resting
finger as a swipe. On Android that dead band was discarding every movement
under 0.4 mm and damping everything under 1.6 mm. We measured what it was
protecting against: with the finger down, perturbing the real capacitance frame
by the real idle noise moves the reported centroid by about 0.15 output units —
less than half of one unit, below the output quantum. fuzz is now 0 (set in
the device tree, so it survives driver updates). On slow drags, the share of
frames where the finger moved but the pointer did not fell from 13.7% to 1.8%
(#116).

Press latency 25 → 17 ms. The two-frame debounce on a new contact was
insurance against noise; at idle the panel shows zero pixels anywhere near the
detection threshold (11× headroom), so one frame is enough. Verified with 36
taps and swipes: no spurious short contacts.

Contact size and pressure are reported. The driver previously registered
no ABS_MT_TOUCH_MAJOR / ABS_MT_PRESSURE axes, so the framework had nothing
to do palm rejection with. The axes are now enabled and report real values
(the driver's default of reporting constants when the axes exist has been
fixed — every contact used to look like a needle point). This needed a second
fix on the way out: the OTA post-install script never propagated kernel
command-line changes from boot.img into the boot entry, so the first build
of this release came up without the axes. It does now; updates from v0.6.1
get the new command line.

Known: a palm resting on the panel fragments into several contacts rather
than being rejected as one. Taps with the other hand still work. Three
threshold-based fixes were tried and measured; all three either did not
separate palm from fingertip or, in one case, broke fast swipes again (a
moving finger has a lower capacitance peak than a resting one). Left for a
later release; the counters below are what will make it tractable.

The touch driver can now show its work

Six driver defects fixed
(#115):
the connected-region table stopped scanning the rest of the panel when full
(noisy environments could drop real fingers on the lower half of the screen);
palm zones were deleted rather than marked; the SPI read retry re-sent the
previous reply instead of the command; each frame was fetched in two transfers
instead of one; the axis resolution was reported as unknown; and the driver
now builds warning-free under W=1.

New diagnostics (no behaviour change): per-stage counters under
/sys/bus/spi/devices/spi0.0/algo/stats, a log of the last 16 contact births
(contacts_log), and the raw and processed 40×60 capacitance frames under
/sys/kernel/debug/himax-hx83121a/. Tooling to read them is in
scripts/touch/. One direct result: the panel firmware does track a per-pixel
baseline (idle frame within −143…+69 counts of the driver's constant baseline),
which had been an open question.

Known issues

  • SELinux is still permissive.
  • Audio (and Bluetooth) can deadlock after long uptime; a watchdog records the
    evidence under /data/vendor/gaokun3/hangdump-* — please attach it if you hit
    this.
  • Internet downloads on the device are slow (1–2 MB/s) for reasons not yet
    established; LAN throughput is fine. In-system OTA is affected.
  • Rear camera: no tuning file yet; dim scenes are dark, flash shots overexpose.

For developers

Kernel patches 0037–0047 in patches/ (touch), #114–#116 in
docs/stage4-findings.md. The touch tooling in scripts/touch/ is
documented in its README, including the rule that any change to a detection
threshold must be validated with fast swipes, not taps.

Files

The in-system updater will offer this build; nothing here is needed for a normal
update. For a fresh install you want super.img.zst and boot.img.

File What
crDroidAndroid-16.0-20260916-gaokun3-v12.11.zip (1.25 GiB) OTA package, also what the in-system updater downloads
super.img.zst (1.19 GiB) system / system_ext / product / vendor, for a fresh install
boot.img (27.5 MiB) kernel #24 + device tree (with touchscreen-fuzz-x/y = 0) + first-stage ramdisk
install-artifacts.sha256 checksums of the three files above
gaokun3.json the updater manifest for this build

Build stamp 1789570683, incremental 20260916145759. Every claim above was
measured on the machine running exactly this build.

v0.6.1-alpha — camera crash fix, rear-camera exposure and flash, a missing sensor no longer kills the front camera

Choose a tag to compare

@vahiru vahiru released this 14 Sep 09:52

Android 16 (crDroid) for the Huawei MateBook E Go (Snapdragon 8cx Gen 3 /
SC8280XP) on a mainline Linux kernel, with hardware Vulkan on the Adreno 690.

This is a fix release for v0.6.0. If the camera app crashed or showed nothing
on v0.6.0, this fixes it.
It also makes the rear camera usable in dim light,
wires up the flash LED in the kernel, and stops a wrong rear-camera module from
taking the front camera down with it.

Talk to us: Telegram · QQ group 920133252

⚠️ Alpha

Installing erases the internal disk, Windows included, and no image of the
factory state exists anywhere. You should be comfortable recovering a machine
that will not boot. No warranty.

BIOS must be 2.16 — do not upgrade to 2.17. Secure Boot must be off.
Instructions: docs/INSTALL.md

Coming from v0.2.x – v0.6.0: update in Settings, nothing else to do.
Coming from v0.1.x: you still have to reinstall.

The v0.6.0 camera crash

On the v0.6.0 release image the camera app crashed on open, for everyone. The
software-ISP module libcamera needs was installed in /vendor/lib64/ while
libcamera looks for it in /vendor/lib64/libcamera/ipa/. Without it libcamera
handed raw Bayer frames to the camera HAL, which treated them as RGB and read
past the end of the buffer. It had worked throughout development only because
the module had been placed by hand on the development unit. The install path is
fixed, and the HAL now refuses a non-RGB configuration and a short frame instead
of crashing (#109).

Rear camera

  • Exposure works in dim light. libcamera now has a gain model and sensor
    properties for the OV13B10 (gain = code / 128, 1.12 µm pixels) and a tuning
    file, so auto-exposure can raise analogue gain instead of only stretching the
    exposure time.
  • A wrong rear module no longer kills the front camera. Huawei shipped two
    rear modules for this board (OV13B10 and S5K3L6). Mainline camss waits for
    every sensor in the device tree before it creates any camera. This build makes
    it give up on a sensor that never binds after 20 s and continue with the ones
    that did — so on an S5K3L6 unit the front camera appears after a 20 s delay
    and only the rear is missing. If that is your unit, please tell us; the fix is
    a device-tree switch.
  • Flash and torch. The flash LED sits on channels 1 and 4 of the PM8350C
    flash module — identified by lighting each channel in turn with someone
    watching the back of the tablet. The kernel exposes it as
    /sys/class/leds/white:flash, and the camera HAL now drives it: the
    flashlight tile in Quick Settings works, and the rear camera offers flash
    auto / on in the camera app. There is no strobe synchronised to the
    sensor, so "flash" here means the LED comes on at the app's pre-capture step,
    auto-exposure adapts to it over a few frames, and it stays on until the still
    frame has been captured. Torch-level current only (about 200 mA), so it is a
    fill light rather than a xenon-style burst.
  • Request settings were being ignored. The HAL only read capture settings
    sent inline, but the framework sends them through the metadata queue first.
    Most requests therefore arrived with no settings at all; the camera worked
    only because the framework tolerates that. Fixed — which is also what makes
    the flash modes reachable.

OTA on dual-boot installs

If your ESP's partition label is not exactly esp (typically a dual-boot
layout made by hand), v0.6.0's post-install step could not find the ESP and the
update failed on the last step. The post-install hook and the boot-control HAL
now locate the ESP by content (the vfat partition that holds our boot entries).

Smaller things

  • The updater manifest and downloads point at the R2 mirror again: GitHub
    release assets and raw.githubusercontent.com are not reachable from mainland
    China, and v0.6.0 users there could not update.
  • The hang watchdog reads binder state from binderfs instead of debugfs (one
    SELinux blocker less). The camera HAL now runs in its own SELinux domain
    instead of init's, and the media-controller device nodes are labelled.
    Still permissive overall.
  • Kernel #19: patches 0035 (camss fallback) and 0036 (flash LED) on top of
    v0.6.0's #18; the never-lit GPIO93 "flash" LED is gone from the device tree.
  • Two orphaned libcamera libraries from an old build (3.7 MB, referenced by
    nothing) are no longer in the image.
  • Camera IDs are now stable: the rear camera is always camera 0 and the
    front 1, as Android expects. Previously the order depended on which
    camera the kernel happened to register first, and could swap between
    boots.

Known issues

  • SELinux is still permissive.
  • Audio (and Bluetooth) can deadlock after long uptime; a watchdog records the
    evidence under /data/vendor/gaokun3/hangdump-* — please attach it if you hit
    this.
  • Colour is white-balanced but not calibrated (no colour matrix yet).
  • Flash is torch-level fill light, not a synchronised strobe (see above).

Files

The in-system updater will offer this build; nothing here is needed for a normal
update. For a fresh install you want super.img.zst and boot.img.

File What
crDroidAndroid-16.0-20260914-gaokun3-v12.11.zip (1.25 GiB) OTA package, also what the in-system updater downloads
super.img.zst (1.19 GiB) system / system_ext / product / vendor, for a fresh install
boot.img (27.5 MiB) kernel #19 + device tree + first-stage ramdisk
install-artifacts.sha256 checksums of the three files above
gaokun3.json the updater manifest for this build

Build stamp 1789364282. Every claim above was measured on the machine running
exactly this build.

v0.6.0-alpha — Cameras (front and rear), the power-domain fix, speaker and thermal

Choose a tag to compare

@vahiru vahiru released this 13 Sep 23:02

Android 16 (crDroid) for the Huawei MateBook E Go (Snapdragon 8cx Gen 3 /
SC8280XP) on a mainline Linux kernel, with hardware Vulkan on the Adreno 690.

This is the camera release. It also fixes the speaker gain that v0.5.0 shipped
clipping, replaces the mock thermal HAL with a real one, and closes a kernel
power-domain defect that had blocked cameras since the first attempt.

Talk to us: Telegram · QQ group 920133252

⚠️ Alpha

Installing erases the internal disk, Windows included, and no image of the
factory state exists anywhere. You should be comfortable recovering a machine
that will not boot. No warranty.

BIOS must be 2.16 — do not upgrade to 2.17. Secure Boot must be off.
Instructions: docs/INSTALL.md

Coming from v0.2.x – v0.5.x: update in Settings, nothing else to do.
Coming from v0.1.x: you still have to reinstall (v0.1.x has no boot
partitions, so the kernel cannot be delivered over OTA).

Cameras

Both cameras now work in the camera app (Aperture ships with the ROM). As far
as we know this is the first time either camera on this machine has produced a
picture outside Windows.

Front camera (Hynix hi846, 8 MP). Preview and still capture work. The path
is mainline camss → libcamera's simple pipeline with the software ISP
(debayer, grey-world AWB, AGC) → libyuv → a small AIDL camera HAL written for
this port → the camera app. The sensor's analogue gain model was measured on
device (gain = 1 + code/16, verified to within 2.3 %), so exposure control
actually works; colour is white-balanced but not calibrated (there is no colour
matrix yet), so expect slightly flat colours.

Rear camera — experimental. The rear module on the unit this was developed
on is an OmniVision OV13B10 (13 MP), not the Samsung S5K3L6 the device tree
had assumed for a year. We found that out by recovering the sensor's power
sequence from Huawei's Windows driver package, bringing the rails up, and
scanning the camera I²C bus — the sensor answered at address 0x36. With the
mainline ov13b10 driver (plus a device-tree match and the board's power
sequence) the rear camera streams 4208×3120 frames and the camera app opens it.

Rear-camera caveats, all known:

  • No tuning yet. libcamera has no gain model or tuning file for this sensor,
    so auto-exposure cannot raise gain; in dim light the preview is very dark.
    Daylight is fine. This is the next thing to fix.
  • No flash. The flash LED hangs off the PMIC's flash controller, not a GPIO;
    it is not wired up yet.
  • Huawei shipped two rear modules for this board (OV13B10 and S5K3L6). If
    your unit has the S5K3L6 variant, the rear camera will not probe — and because
    the mainline camera subsystem waits for every sensor in the device tree,
    the front camera will disappear too. If you install this build and have
    no cameras at all, that is why; please open an issue and say so, it tells us
    which module you have, and the fix is a device-tree switch.
  • The rear camera's analogue supply is shared with the display's I/O rail. While
    the rear camera is powered the rail sits at 2.8 V instead of 1.8 V — this is
    exactly what Windows does on this board, and the panel is unaffected.

The camera power-domain defect is fixed

Every earlier camera attempt worked once and then never again: the camera power
domain (titan_top) refused to power back on after its first collapse, and
only a reboot recovered it. After eight refuted hypotheses and a register-level
trace the cause turned out to be three clock generators in the SC8280XP camera
clock controller (camnoc_axi, slow_ahb, fast_ahb) that were not marked
shared. When the camera driver finished and released its clocks, the CAMNOC
bus clock was left pointing at a PLL that had just been switched off, and the
power-domain handshake with the bus never completed. Marking those generators
shared (they park on the always-on crystal when idle, as every sibling SoC's
driver already does) fixes it: the domain now powers up and down with normal
runtime PM, no boot-time workaround needed. The fix will be sent upstream.

Speaker: the v0.5.0 gain staging was clipping

v0.5.0 shipped "digital +6 dB / PA −3 dB". Measured on device that produces
−20 dB THD (about 10 % distortion) on −6 dBFS material, because digital gain
sits ahead of the DAC and costs headroom. This build pins digital gain at unity
and takes the loudness from the power amplifier instead — about 20 dB cleaner
at the same volume.

Thermal

The mock thermal HAL is gone. The real one reads the SoC's thermal zones. (The
mock reported a 36 °C shutdown threshold; it never fired only because its
readings were constant. Had a real HAL been dropped in without changing the
threshold, the tablet would have powered off a few minutes after boot.)

Smaller things

  • The navigation bar is back.
  • wpa_cli is in the image for Wi-Fi diagnostics.
  • Kernel: ashmem and xt_quota2 are back (a boot regression from a tree that
    was never committed), the camera GDSC wait values match the hardware reset
    values, and a genpd teardown bug that made re-binding the camera clock
    controller panic is fixed.
  • Fixed a ueventd rule in the camera bring-up that had been overriding the
    GPU / sensor / video-codec device permissions.

Known issues

  • SELinux is still permissive.
  • Audio (and Bluetooth) can deadlock after long uptime; a watchdog records the
    evidence under /data/vendor/gaokun3/hangdump-* — please attach it if you hit
    this.
  • Internet downloads on the device are slow (1–2 MB/s) for reasons not yet
    established; LAN throughput is fine. In-system OTA is affected.
  • Rear camera: see the caveats above.

For developers

70 commits since v0.5.0. The interesting reading is in
docs/stage4-findings.md #88–#107: the libcamera port (#88–#99), the
power-domain investigation (#101–#105) and the rear camera identification
(#106). Kernel patches 0015–0034 in patches/; the diagnostic ones are kept
out of release kernels by scripts/kernel-apply-patches.sh unless --with-diag
is passed.

Files

The in-system updater will offer this build; nothing here is needed for a normal
update. For a fresh install you want super.img.zst and boot.img.
Starting with this release everything is attached to the GitHub release
(the R2 mirror will be retired later):

File What
crDroidAndroid-16.0-20260913-gaokun3-v12.11.zip (1.25 GiB) OTA package, also what the in-system updater downloads
super.img.zst (1.19 GiB) system / system_ext / product / vendor, for a fresh install
boot.img (27.5 MiB) kernel #18 + device tree + first-stage ramdisk
install-artifacts.sha256 checksums of the three files above
gaokun3.json the updater manifest for this build

Build stamp 1789318530. Every claim above was measured on the machine running
exactly this build.

v0.5.0-alpha — HEVC decode, Bluetooth audio, and the back gesture

Choose a tag to compare

@vahiru vahiru released this 24 Aug 11:14

Android 16 (crDroid) for the Huawei MateBook E Go (Snapdragon 8cx Gen 3 /
SC8280XP) on a mainline Linux kernel, with hardware Vulkan on the Adreno 690.

This release makes three things work that were broken or missing, and ships the
root manager alongside the ROM so root is usable out of the box.

Talk to us: Telegram · QQ group 920133252

⚠️ Alpha

Installing erases the internal disk, Windows included, and no image of the
factory state exists anywhere. You should be comfortable recovering a machine
that will not boot. No warranty.

BIOS must be 2.16 — do not upgrade to 2.17. Secure Boot must be off.
Instructions: docs/INSTALL.md

Coming from v0.2.x / v0.3.x / v0.4.x: update in Settings, nothing else to
do — except the one manual step under "Navigation gestures" below.
Coming from v0.1.x: you still have to reinstall (v0.1.x has no boot
partitions, so the kernel cannot be delivered over OTA).

HEVC hardware decode

v0.4.0 shipped hardware H.264. HEVC was declared but produced zero frames —
and because a hardware component outranks the software one, apps got a failure
rather than a fallback. That is fixed. Measured on device:

Codec Resolution Frames
H.264 640x360 / 1280x720 / 1920x1080 30 each
HEVC 1280x720 (two different clips) / 1920x1080 30 each
VP8 1280x720 30
VP9 1920x1080 30

The Venus firmware told us what was wrong once we asked it. Setting
/sys/kernel/debug/venus/fw_level to 0x3f makes the firmware log what it is
doing, and it printed the whole story:

Slice error type H265_CONFIG_FLAG_MISSING
ebd_error_code 0x100b ... default_sps 1 discard_pic 1
Conceal I pic 0 as intra
...
Allocate yuv buffer for pic 0
No phy yuv buffer available          (forever)

Android hands the codec-specific data (VPS/SPS/PPS) as its own buffer with no
"this is config" flag — and HFI_BUFFERFLAG_CODECCONFIG is defined in the
Venus driver but never set. The H.264 decoder in the firmware tolerates that.
The HEVC decoder does not: it reports H265_CONFIG_FLAG_MISSING, invents a
concealment picture from a default SPS, and then blocks forever waiting for an
output buffer for that invented picture — while the host is waiting for the
SOURCE_CHANGE event before it will allocate any. A deadlock, in userspace's
lap.

The fix is in external/v4l2_codec2: for HEVC, hold the CSD and prepend it to
the first frame buffer, so the firmware sees parameter sets and a slice in one
buffer. There is precedent right next to it — the VP9 path already skips CSD
entirely. Causality check, same boot, same binary:
vendor.gaokun3.v4l2c2.merge_csd=0 → 0 frames, =1 → 30 frames.

⚠️ 4K is still untested. We advertise up to 4096x2176 and have never
verified it. If 4K turns out not to work it is the same trap as HEVC was, and
the advertised limit will come down.

Bluetooth headphones

Pairing always worked; audio never did. The cause was not a missing HAL, a
missing codec, or the audio policy — all of that was already correct. Since
Android 14 each Bluetooth profile is gated by its own sysprop, and an unset
sysprop means off
:

// A2dpService.java
public static boolean isEnabled() {
    return BluetoothProperties.isProfileA2dpSourceEnabled().orElse(false);
}

This device had zero bluetooth.* properties, so only AdapterService was
running. Pairing is the adapter's job, which is why it worked; playing audio is
a profile's job, which is why it did not. Thirteen profiles are now declared
(A2DP, AVRCP, HFP, HID host/device, battery, OPP, PAN, PBAP, MAP, GATT, ASHA) —
LE Audio deliberately left off, since a half-enabled LE Audio stack is a classic
source of exactly this "connects but silent" failure.

Navigation gestures (edge-swipe back)

Swipe-from-edge back did nothing, and neither a navigation bar nor a taskbar was
ever created. crDroid reads mHasNavigationBar from a runtime setting
(LineageSettings.System.FORCE_SHOW_NAVBAR) whose default comes from
config_showNavigationBar — which this device now sets to true. But a stored
value beats a default, and force_show_navbar had been written as 0 into
/data by an earlier build.

Fresh installs need nothing. If you are updating an existing install, flip it
once:

adb shell content insert --uri content://lineagesettings/system \
  --bind name:s:force_show_navbar --bind value:s:1
adb reboot

After that, measured: taskbar windows 0 → 5, TaskbarDelegate.mNavigationMode
-1 → 2, EdgeBackGestureHandler mIsAttached/mIsEnabled false → true, and the
navigationBars and systemGestures insets appear.

A real thermal HAL

The framework had been reading an AOSP mock that reports a constant 30.1 °C. It
now reads /sys/class/thermal: 8 CPU zones, the GPU, and a skin value.

⚠️ This one had a landmine in it and it was real. The mock declares the
skin/battery SHUTDOWN threshold at 36.0 °C, and
ThermalManagerService.shutdownIfNeeded() calls powerManager.shutdown() when
it is reached. This machine idles at 36–37 °C. Swapping in a HAL that reports
true temperatures without also fixing the thresholds would shut the tablet down
a few minutes after every boot. The new thresholds are die temperatures
(60/70/80/90/100/105 °C), and SHUTDOWN at 105 sits below the kernel's own 110 °C
critical trip, so the ordering is right: Android shuts down cleanly first, the
kernel remains the backstop.

There is no skin thermistor on this board, so skin is the hottest of the
CPU/GPU dies — an honest proxy, labelled as one, and it is what makes
getThermalHeadroom() return a number games can use instead of NaN.

Also in this release

  • Vulkan 1.3 is now declared (was 1.1), plus android.hardware.vulkan.compute.
    Not an optimistic claim: turnip reports 1.3 for this chip —
    tu_device.cc:1190 selects VK_MAKE_VERSION(1, 3, …) for a6xx when hardware
    multiview is present, and a690 inherits has_hw_multiview = True. We do not
    declare a dEQP level, because we have not run dEQP.
  • Touch: a game preset. The himax driver in our kernel is upstream
    EGoTouchRev (all 14 algorithm functions identical, 19 of 20 defaults identical,
    same-day commits) — so there was nothing to switch to. What we had never used
    was its game preset: no velocity-prediction smoothing, no 2-frame touch-down
    debounce, jump detection on. It is now
    persist.sys.gaokun3.touch_mode (game by default, daily to go back) and
    applies at boot.
  • Root manager included. The kernel has ReSukiSU built in, but the kernel
    alone is not enough — the manager app is what lays down /data/adb/ksud and
    grants root. ReSukiSU_v4.2.0-rc1_35061-arm64-v8a-release.apk is attached; it
    is the unmodified upstream release, verified byte-for-byte against
    ReSukiSU/ReSukiSU v4.2.0-rc1
    (sha256 544cf6cb105acacf219b3db71e43b9818e3f335153763e56aa0356bd09d1b450),
    and the release script refuses to publish if that hash does not match. The
    version matters: it must match the kernel side, which reports
    ksud 4.2.0-rc1 (uapi: 2).

Still not fixed

  • SELinux is permissive. Two structural blockers remain, neither solvable
    by adding rules.
  • 4K hardware decode: never tested. See above.
  • Camera, USB-C DisplayPort, automatic brightness — unchanged. The ambient
    light sensor is on a bus where the chip does not answer; four software avenues
    are exhausted.
  • Downloads from the internet run at 1–2 MB/s on this machine while a PC on
    the same network gets 20x that. Cause still not established, and it is not
    Wi-Fi. It makes the in-system update slow.

Files

The in-system updater will offer this build; nothing here is needed for a normal
update. For a fresh install you want super.img.zst and boot.img:

File Where
super.img.zst (1.19 GiB) download
OTA zip (1.25 GiB) download
boot.img, manager APK, install-artifacts.sha256 attached below

Build stamp 1787552138. Every claim above was measured on the machine running
exactly this build.

v0.4.0-alpha — hardware video decode, and Google apps

Choose a tag to compare

@vahiru vahiru released this 22 Aug 18:00

Android 16 (crDroid) for the Huawei MateBook E Go (Snapdragon 8cx Gen 3 /
SC8280XP) on a mainline Linux kernel, with hardware Vulkan on the Adreno 690
and now hardware video decode on Venus.

Talk to us: Telegram · QQ group 920133252

⚠️ Alpha

Installing erases the internal disk, Windows included, and no image of the
factory state exists anywhere. You should be comfortable recovering a machine
that will not boot. No warranty.

BIOS must be 2.16 — do not upgrade to 2.17. Secure Boot must be off.
Instructions: docs/INSTALL.md

Coming from v0.2.x / v0.3.x: update in Settings, nothing else to do.
Coming from v0.1.x: you still have to reinstall (v0.1.x has no boot
partitions, so the kernel cannot be delivered over OTA).

Hardware video decode

c2.v4l2.avc.decoder now decodes on the Venus block — measured on device, 30
frames out of a 640x360 H.264 clip. As far as we know this is a first for
SC8280XP.

The kernel half had been done since v0.3.0. What was missing was not a driver but
two assumptions inside external/v4l2_codec2, both of which are really
"ChromeOS behaved this way and Venus does not":

  1. It passed ui::Size() as the coded size when setting the format on the
    compressed input queue. ui::Size's default is -1 x -1, not 0 x 0.
    Assigned into a __u32 that becomes 0xFFFFFFFF, Venus clamped it to its
    8192x8192 maximum, and decide_core() then computed a load of 1.573 GHz
    against a 1.332 GHz ceiling and refused every clip, whatever its real size.
    A 640x360 video failed for looking like an 8K one.
  2. It treated a VIDIOC_G_FMT failure on the capture queue during startup as
    fatal. Venus returns -EINVAL there by design — a client that subscribed
    to V4L2_EVENT_SOURCE_CHANGE is required by the V4L2 stateful decoder spec to
    wait for that event before asking about the capture format. The driver is
    right and the client's up-front optimisation cannot work against it.

Both fixes are applied by scripts/crdroid-tree-fixes.py, with the reasoning and
the measurements recorded next to them.

Encode is not fixed and not verified: screenrecord still fails. It very
likely has its own version of the same problem.

Google apps are included

This build bundles MindTheGapps. There is no recovery on this machine, so
flashing a GApps zip separately is not an option — including them is the only way
they can be had.

Google's own setup wizard is removed and LineageOS's is kept. Google's insists
on reaching Google's servers before it will let you finish first-time setup, which
simply does not complete on mainland Chinese networks; the LineageOS one needs no
Google service at all. Nothing else about GApps is affected — the overlay
MindTheGapps ships for the setup wizard already targets org.lineageos.setupwizard.

Play Integrity will fail on this device (unlocked bootloader, permissive SELinux).
Play Store works; expect apps that check integrity not to.

The on-screen keyboard works with the keyboard attached

Android suppresses the on-screen keyboard whenever a hardware keyboard is present.
On a tablet whose keyboard is a magnetic cover — often folded back, often not
being typed on — the result was "tap a text field, nothing happens".
show_ime_with_hard_keyboard now defaults to on.

There is also a switch to disable the magnetic keyboard and touchpad entirely, in
Settings → System → Keyboard, and as a Quick Settings tile. It was originally
built as a workaround for the problem above and does not solve it: Android decides
whether to suppress the on-screen keyboard from whether a keyboard device
exists, not whether it has been inhibited. It is still useful for stopping stray
keypresses when the cover is folded behind the screen.

Also in this release

  • A kernel panic that any app could trigger, fixed. Switching to Settings
    could take the whole machine down. ESR=0xf2000800 identified it as a BUG()
    assertion rather than a null dereference: drm_crtc.c's fence_to_crtc()
    asserts on fence->ops after dma-fence has already detached it on signal. Two
    different apps hit it through two different ioctl paths. Still unfixed upstream
    as of mainline master — verified commit by commit rather than assumed.
  • Brightness control is real. The lights HAL was a stub that accepted values
    and did nothing; it now drives the backlight.
  • Speaker volume is about 6 dB louder. The upstream machine driver caps the
    WSA digital volume 3 dB below the codec's own limit; that cap is raised.
  • Boot images now assert they contain exactly one DTB — an earlier build shipped
    two concatenated, silently.

Not fixed

  • Automatic brightness. The ambient light sensor does not answer on its bus.
    The driver is in the SLPI firmware, the sensor type is declared, and the SEE
    does probe it — but bus_instance 0–7, bus_type 0–3 and both power-rail
    states were swept with no response. A negative control (feeding the working
    accelerometer a wrong I²C address) produces an identical failure signature.
    The board-specific parameters lived in a Windows registry that was erased with
    Windows. Auto-rotation and gyro are unaffected.
  • Hardware video encode, as above.
  • Desktop windowing is deliberately off. An upload of this same filename
    briefly had it enabled and was replaced within the hour; if you updated in that
    window, this release turns it back off.

Verification for this build was partial: hardware decode, the on-screen keyboard
and the desktop-mode revert were each measured, but it has not been through a full
soak.


Install / update

Already on v0.2.x or v0.3.x — Settings → System → System update.

Fresh install — follow
docs/INSTALL.md.
super.img.zst is 1.2 GB and is hosted off GitHub:

sha256 for all three is in install-artifacts.sha256, attached.

v0.3.0-alpha — the machine can sleep, and the headphone jack works

Choose a tag to compare

@vahiru vahiru released this 21 Aug 18:44

Android 16 (crDroid) for the Huawei MateBook E Go (Snapdragon 8cx Gen 3 /
SC8280XP) on a mainline Linux kernel, with hardware Vulkan on the Adreno 690.

Talk to us: Telegram · QQ group 920133252

⚠️ Alpha

Installing erases the internal disk, Windows included, and no image of the
factory state exists anywhere. You should be comfortable recovering a machine
that will not boot. No warranty.

BIOS must be 2.16 — do not upgrade to 2.17. Secure Boot must be off.
Instructions: docs/INSTALL.md

Coming from v0.2.x: update in Settings, nothing else to do.
Coming from v0.1.x: you still have to reinstall (v0.1.x has no boot
partitions, so the kernel cannot be delivered over OTA).

The machine can sleep now

Close the lid, walk away, come back. This is the first build where that works.

Every previous release said suspend was a kernel or EC defect, because it
reproduced identically under Linux on the same kernel. That was wrong, and the
mistake was ours.
In Stage 2 this port changed one line of the device tree —
usb_0's dr_mode from host to otg — to get USB device-mode adb. This
machine's UCSI is broken, so nothing ever tells that controller which role to
take; it settles into device with no gadget and no xHCI attached. Cutting power
to a controller in that state resets the whole SoC, with no panic, no oops and
nothing in pstore — which is exactly why it looked like a hardware-level defect
for four months.

Two things had to be true at once, which is why every single-variable experiment
came back negative and every hypothesis looked "eliminated":

  1. the EC times out in suspend_noirq — fixed upstream, already in our kernel;
  2. that USB controller must not be in device mode when the system suspends.

The fix keeps both halves of the trade-off: the port switches the controller to
host when the screen turns off and back to device when it turns on, gated by
a wakelock that is only released once host mode is confirmed — so any failure
means "no suspend", never "suspend into a reset".

⚠️ The cost: while the screen is off, USB adb disconnects. It comes back when
the screen turns on. adb over TCP (port 5555, on by default) is unaffected. If
you would rather not have this, setprop persist.gaokun3.allow_suspend 0
restores the old always-awake behaviour.

Audio: headphone jack, and the microphones

The headphone jack works. So does the built-in microphone — which turns
out to have been completely dead until now, and nobody had noticed, because
nothing in the ROM recorded audio. The headset microphone works too.

The headphone jack was silent for an unusual reason: the audio routing was
incomplete inside the codec, in a way the kernel logs nothing about. The
interpolator stage of the RX macro was left at its reset defaults, so the DAPM
graph never completed, so the backend DAI could not be opened, so PCM open
failed — and no driver on that path prints a word about it. Nine mixer controls
later, playback runs at a measured 48,960 frames/second, which is real-time
48 kHz rather than a DMA engine spinning on nothing.

The recipe came from upstream ALSA UCM2, which turns out to treat this machine
as a ThinkPad X13s — sc8280xp.conf matches HUAWEI.*MateBook E.* and includes
the X13s profile verbatim. Speaker volume, headphone gain and mic gain are all
derived from the kernel's own dB tables rather than guessed.

Hardware video decode: half of it

The kernel side of Venus is up — /dev/video0 and /dev/video1 are the
Qualcomm decoder and encoder, all clocks, power domains and IOMMU streams
resolve, and firmware loads. As far as we can tell this is the first SC8280XP
device with Venus running on mainline.

This does not speed anything up yet. Android still uses software decoders,
because it needs a Codec2 component that talks V4L2, and that is not wired up.
All 66 decoders remain software ones. Listed here because the hard, undocumented
half is done and the remaining half is ordinary work.

Smaller things

  • A watchdog now collects evidence when audio or Bluetooth deadlocks. It only
    reads /proc thread state — no dumpsys, nothing expensive — and fires only
    when the same thread has been in uninterruptible sleep for two minutes. Reports
    land in /data/vendor/gaokun3/hangdump-<uptime>/.
  • Wi-Fi throughput to the internet is slower than it should be (roughly 1/20 of
    a laptop on the same network). Earlier notes blamed an ath11k defect; that was
    a misattribution — ping to the gateway is clean, LAN transfers hit 61 MB/s, and
    the driver logs nothing. The cause is still unknown.
  • Recovery is built and shipped but does not boot — the entry is deliberately
    not created. adb sideload is not available; updates come through Settings and
    the rescue Linux can write any partition directly.

Still missing

Camera. USB-C DisplayPort. Hardware video decode in Android. Ambient light
sensor, so no auto-brightness — that one lives on the SLPI DSP and its I²C
instance does not respond. SELinux is permissive.

The full, measured status table is in the
README.

Files

The two large files live on Cloudflare R2 rather than being attached here —
pulling a gigabyte out of GitHub Releases from China is painful, and R2 is where
the in-system updater fetches from anyway. Egress is free, so this costs nothing.

File Where For
super.img.zst — 982 MiB R2 Fresh install. system / system_ext / product / vendor
boot.img — 26 MiB attached here (and on R2) Fresh install. Kernel, device tree and ramdisk in one Android boot image
install-artifacts.sha256 attached here Verify the two above
crDroidAndroid-16.0-20260821-gaokun3-v12.11.zip — 1.03 GiB R2 The OTA package. Not needed for a fresh install — the updater downloads it itself
gaokun3.json attached here The OTA manifest, for reference

Proprietary Huawei firmware is already inside these images; it is deliberately
absent from the source tree.

Help wanted

Concrete, well-scoped work, roughly easiest first: a Codec2 V4L2 component so the
Venus hardware actually gets used (external/v4l2_codec2 is already in the
manifest); the GPU SMMU interrupt mismatch in the device tree; a real thermal HAL
(⚠️ raise the SHUTDOWN thresholds at the same time — the AOSP mock reports 36 °C
and ThermalManagerService will power the machine off when it believes that);
SELinux enforcing; and the Wi-Fi throughput mystery above.

Reports of what breaks are as useful as patches. Open an issue with your BIOS
version and SKU, or come to the Telegram / QQ group.

The engineering record — every finding with its evidence, including the
conclusions that later turned out to be wrong
, such as four months of blaming
the kernel for a suspend bug we introduced ourselves — is in
docs/.