megi's PinePhone Development Log RSS


2020–12–05: Alternate EG25G userspace project

I've been reverse engineering EG25G userspace on and off since mid July 2020.

I really dislike the Quectel's code. They took relatively clean (if a bit overengineered) Qualcomm code and made a total mess, that somehow barely holds together.

They manage to do things like sprintf(buf, "echo %s > /dev/kmsg", barely_checked_user_input); system(buf); in a superuser process, or system("rm /something") instead of unlink("/something"), etc. None of their code inspires any confidence in the modem's software as a whole.

Biktor has a nice bootloader/kernel cleanup project, so I decided to start a fully FOSS userspace rewrite project to complement it.

How it will look/work

Alternate FOSS userspace code will be very simple and will not depend on anything in the original root filesystem of the modem's firmware.

You'll be able to install the FOSS userspace along with the existing rootfs content and choose which one to boot to via my modem power manager:

# to power up the modem and boot the original userspace code
echo 1 /sys/class/modem-power/modem-power/device/powered


# to power up the modem and boot the FOSS userspace code
echo N /sys/class/modem-power/modem-power/device/powered

Modem power manager will configure DTR and #W_ENABLE gpios to one of the 4 possible configurations, and then it will power up the modem. These two gpios can be relatively easily read from the modem's userspace during boot, and can be (a)bused to make boot decisions very early on after the kernel starts the /sbin/init process.

The existing firmware will need just a single simple and fairly safe modification. The rest of the changes will be just addition of new files to the root filesystem to a /foss/ directory.

In order to make boot decisions, the FOSS userspace will include a small /sbin/init binary that will be executed by the kernel instead of the original one, and will check the status of the above mentioned gpios and then execute either /foss/init.2, /foss/init.3, /foss/init.4, or the original firmware's /sbin/init.sysvinit. One of these will become the PID 1 process.

This will be the foundation for easy experimentation with the FOSS userspace for the modem's OS running on it's ARM CPU.

Anyone will be able to modify and test the FOSS userspace code quite fearlessly. Recovery will be as simple as booting to the original userspace, or keeping one of the /foss/init.* binaries in an always known-good state, and only experimenting with the others.

Plan / progress

This should hopefully be enough to be able to perform voice calls without having to use any part of the original Quectel's code that is present on the root filesystem of their firmware.

I expect the FOSS code to shrink the firmware quite a bit. Most of the heavy lifting is done by the Qualcomm/Quectel Linux kernel and their modem's DSP code. Userspace code just has to perform some setup tasks by modifying a few files in sysfs and keeping track of a few special needs the modem's DSP code may have, like configuring the codec during the call, and some other minor stuff.

This can probaly be easily handled all by a single 200kB static binary instead of a huge 80MB busybox based system with 15 interacting daemons, hundreds of shell scripts and hard to capture behavior.

And there will be 80MiB of newly released space for some actually interesting additional code to be run on the modem, if you choose to delete the original proprieatry code. :)