Show Posts

This section allows you to view all posts made by this member. Note that you can only see posts made in areas you currently have access to.

Messages - shuntcap

Pages: [1] 2 3 ... 6
Cosmo Communicator - General Discussion / Re: Camera
« on: April 16, 2022, 02:31:47 am »
When shuntcap adapted a particular build of GCam, intended for another phone with the same sensor, to make it work on the Cosmo, there was probably no intention to remove Google dependencies, but rather to make features work, which probably explains why the dependencies are still there.
Versions v1-v3 were adapted from an existing mod of GCam intended for another phone with a different sensor, actually.  v4 was a clean port from scratch to bring in additional features that were knocked out of the other phone's version.  But Daniel is absolutely correct: my only goal was to improve the poor camera performance on the Cosmo by providing a good software alternative.

Cosmo Communicator - General Discussion / Re: Camera
« on: September 30, 2021, 12:30:31 am »
I read you don't support Astro. How will we do it? Your optimization changes functionality substantially.
Should we petition for a device to be made available to you to work on?
Or a subscription to buy one for yourself?
I don't know ... I'm open to every possibility, but I would like to see the same result on Astro.  :o
Sorry for my long absence from the forum. I've pretty much shelved the Cosmo as I just haven't had much free time to hack on it.

I still won't be backing the Astro, but I've been watching the updates.  This time around they're paying close attention to the camera image quality.  They just might get the camera working right finally.  But if they don't, I have backed the Pro1 X which supposedly has the same camera sensor as the Astro.  I plan to port GCam to the Pro1 X once I receive my device, and that port might just work on the Astro, too.

Please post your "howto" as I dont want to setup everything again!
See my instructions here:

How to manually upgrade Cosmo Linux from v3 to v4 without wiping your data
One serious drawback to running Linux on the Cosmo is that with each new Linux release, Planet's upgrade method wipes your entire Linux partition.  For those who actually use Linux on the Cosmo, this is highly undesirable.  While previous upgrades (v1->v2 and v2->v3) could be performed manually through apt, v4 breaks this due to implementing a replacement Android device driver compatibilty layer.  However, is it still possible to to manually upgrade from v3 to v4!  This guide will show you how.

You will need:
1) TWRP installed on the Cosmo (
2) adb installed on a workstation
3) Enough hard drive space on your workstation to back up the full size of your Cosmo Linux partition
4) The Planet USB-C/Ethernet hub (Wi-Fi will be temporarily lost) and wired (not wireless) Internet connectivity in your home or office (
5) Your full concentration and steady nerves

Disclaimer: You proceed at your own risk.  This is a complicated manual upgrade and many things can go wrong if you are not careful.  I am not responsible, nor is Planet Computers, nor is OESF, nor is Adam Boardman, for anything that goes wrong with your equipment while following this guide.

Step 1: Back up your Linux partition
Stop!  Do NOT skip this step!  Before we do anything, back up your Linux partition just in case something goes wrong during the upgrade.  If you have nothing worth saving on it, don't even bother reading this guide.  You're better off just upgrading with Planet's method.

To back up your Linux partition onto your workstation, first boot TWRP.  On the Mount screen, tap Cancel.  Swipe right to allow modifications.  Plug a USB-C cable from your workstation into the Cosmo's left port.  Make sure you have adb installed on your workstation, then perform these commands:
Code: [Select]
adb pull /dev/block/by-name/linux cosmo_linux_partition_backup
adb pull /dev/block/by-name/DEBIAN_KDE cosmo_linux_boot_backup

This will take some time.  Your Linux partition, including personal data and customizations, will be backed up to a file on your workstation called cosmo_linux_partition_backup.  On a Linux workstation, if you wish, you can mount this file as a loopback device and view the contents:

Code: [Select]
sudo mkdir -p /mnt/cosmo_linux
sudo mount -o loop cosmo_linux_partition_backup /mnt/cosmo_linux
ls /mnt/cosmo_linux

You will see your Linux filesystem data.

The second file backed up is the Linux boot partition.  We back this up to be absolutely certain we can restore your entire working Linux setup as it is right now.  This ensures that we have the kernel version that matches your Linux installation.

See Step 6 for restoration instructions in case anything goes wrong during the upgrade.

Step 2: Set up Ethernet
During the upgrade process, we will lose both Wi-Fi connectivity and the X server graphical interface due to removing the Android device driver compatibility layer which has changed in v4.  These will be restored by the time we finish.  Since MediaTek only provides closed-source Android device drivers for their hardware platforms (beyond basic things like keyboard, LEDs, and LCD initialization), Gemian Linux has to rely on interfacing with Android libraries to provide accelerated graphics, sound, GPS, camera, Wi-Fi, and other critical device support.

We therefore need to rely on wired Ethernet connectivity instead, both for logging into the Cosmo remotely to issue commands, and for the Cosmo's Internet connection.  Planet's USB-C hub is required for this.  You will need a working LAN with a WAN gateway for Internet access.

We will need to determine what IP address the Cosmo receives by DHCP when the USB-C/Ethernet hub is inserted.  During the rest of the upgrade, we will need to remotely log into the Cosmo because the X server will crash.

There are two ways of doing this.  The first is the easiest.  The second is mostly informational.

Method 1
Plug the USB-C/Ethernet hub into the Cosmo's left USB port, then plug an Ethernet cable into the jack, ensuring that the other end is connected to a router with Internet access or a switch behind such a router.  You should see the activity LEDs on the hub's Ethernet jack light up if your cable is live.  Your router should be configured to serve DHCP addresses (most consumer and small office routers are configured this way by default).

We can also power the Cosmo through the hub, but there is a special plug-in order to follow or you won't have Ethernet.  First, disconnect everything.  Now connect the hub to the Cosmo.  Connect USB-C power to the hub.  Finally, connect the Ethernet cable.  (There is no RNDIS interface in this configuration.)  As a side note, this configuration should be of particular interest to anyone wishing to dock the Cosmo and use a monitor, mouse, keyboard, and even Ethernet, and still supply power to the Cosmo for unlimited runtime.  Once HDMI out is working over the right USB port, this will be possible!  I have done it under Android.

On the Cosmo, open a terminal emulator (xterm, for example).  Type this command:
Code: [Select]
ifconfig eth0 | grep inet
You should see output similar to this:
Code: [Select]
        inet  netmask  broadcast
Make note of the inet address ( in this example; yours will differ), then from your workstation (which should be on the same LAN), type this:
Code: [Select]
ssh cosmo@
You are now remotely logged into the Cosmo and can issue commands.  We will use this interface for the upgrade.

Now disable the Wi-Fi interface using NetworkManager or ConnMan.  I don't use either (they are completely disabled), so I won't tell you how to do that.

Our goal is to make sure Internet connectivity is achieved through the USB-C/Ethernet hub, not through Wi-Fi.  Wi-Fi will be lost during the upgrade (but restored at the end).  Test your Internet connection now, then proceed to Step 3.

Method 2
The Cosmo presents an RNDIS interface on the left USB port.  RNDIS is a way of emulating an Ethernet connection over a USB cable.  The Cosmo's IP address on this interface is always  Plug a USB-C cable from your workstation into that left port.  On your workstation, log into the Cosmo:
Code: [Select]
ssh cosmo@
Take down the Wi-Fi interface using whatever connection manager you have installed.  I do not use NetworkManager or ConnMan, so I just take it down by hand:
Code: [Select]
sudo ifconfig wlan0 down
Now we need to determine what IP address the Cosmo will pull for the USB-C/Ethernet hub.  I've been unable to get the USB-C/Ethernet hub to work in the right-hand USB port under Linux (although it does receive power), and likewise RNDIS only runs on the left-hand port.  So we cannot maintain both an RNDIS and a hub-based Ethernet connection at the same time.  We will need to swap the plugs.  First, execute this command:
Code: [Select]
sleep 30; ifconfig eth0 > eth0_info
Next, within 30 seconds (time it with a watch), remove your USB-C cable, then plug the USB-C/Ethernet hub into the left side.  Now plug in the Ethernet cable.  You should see the activity LEDs on the hub's Ethernet jack light up if your cable is live.  Wait for the 30 seconds to expire, during which the Cosmo should pull an IP address from your router via DHCP.  Remove the hub and plug the USB-C cable power back in.  Within a few seconds, your command line prompt should return (it froze because we unplugged your workstation's USB-C cable).  If the activity LEDs never lit, ensure the hub's Ethernet cable is connected to your router or network switch.

With the command line now active again, type this:
Code: [Select]
cat eth0_info
You will see the IP address of your Cosmo when the USB-C/Ethernet hub is connected; e.g., inet

Remove the USB-C cable (again) and insert the hub (again).  Wait for the activity lights to begin flashing, then use ssh to connect to that address:
Code: [Select]
ssh cosmo@  # Your IP address will be different
Finally, test your Cosmo's Internet connectivity through any means you see fit (ping a remote host, direct a web browser to a remote site, etc.)  The point is to make sure your Internet connection is going through the USB-C/Ethernet hub, not through Wi-Fi.

Step 3: Upgrade Gemian and Android compatibility layer
With the backup out of the way (go back to Step 1 if you didn't do it), and a solid, wired Ethernet connection established, we can start the upgrade.

From now on, perform all commands from your workstation while remotely logged into the Cosmo through the USB-C/Ethernet hub.  This is very important because you will temporarily lose your X server during the upgrade and will not be able to enter commands directly on the Cosmo's console.

Edit the file /etc/apt/sources.list.d/gemian.list (use sudo and a text editor of your choice, such as vi, nano, joe, emacs, xedit, etc.) and make it match the following (change "gemian-buster" to "gemian-planet"):
Code: [Select]
deb buster main
deb buster main

Likewise, edit the file /etc/apt/preferences.d/gemian.pref and change from:
Code: [Select]
Code: [Select]
This points apt to the new v4 repository.  Now attempt to upgrade all packages:
Code: [Select]
sudo apt update
sudo apt upgrade

You'll see a long list of packages that will be upgraded, possibly followed by another long list of packages that will be downgraded.  This is expected.  Hit Enter to answer "Y" to the "Do you want to continue? [Y/n]" prompt.

Buried in the output, you will see a message about needing to reboot to use the new kernel. Do NOT reboot yet.

Next, do this:
Code: [Select]
sudo apt install media-hub
Then, this:
Code: [Select]
sudo apt install lxc-android
This will attempt to install gemian-system and lxc-android, but will fail after fetching the packages and doing a bit of setup.  This is expected.

In the next command, your Cosmo's graphical interface will freeze (if it hasn't already; sometimes it does earlier) because we will remove the Android device driver compatibility layer.  The X server relies on Hardware Composer (hwcomposer) to render accelerated 2D graphics, but hwcomposer will be upgraded.

With that warning aside, remove the old Android device driver compatibility layer:
Code: [Select]
sudo apt remove droid-hal-cosmopda
After removing droid-hal-cosmopda, it will start setting up the new gemian-system package, which includes downloading a new Android device driver compatibility layer.  You should see output similar to this:
Code: [Select]
Reading package lists... Done
Building dependency tree     
Reading state information... Done
The following packages will be REMOVED:
0 upgraded, 0 newly installed, 1 to remove and 2 not upgraded.
1 not fully installed or removed.
After this operation, 48.8 MB disk space will be freed.
Do you want to continue? [Y/n]
(Reading database ... 211312 files and directories currently installed.)
Removing droid-hal-cosmopda (0.1+0~20200719231650.20~1.gbp236b48) ...   
Job for dev-cpuset.mount failed.
See "systemctl status dev-cpuset.mount" and "journalctl -xe" for details.
Job for system.mount failed.
See "systemctl status system.mount" and "journalctl -xe" for details.
Setting up gemian-system (0.1+0~20210323112818.11~1.gbp3d78a2) ...   
Target checksum f8b91bd83795c62f1e9b33be9a4156bdf4a90658
Checking /var/lib/lxc/android/android-rootfs.img
sha1sum: /var/lib/lxc/android/android-rootfs.img: No such file or directory
Downloading new Android system image
  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current
                                 Dload  Upload   Total   Spent    Left  Speed 
... (cut download progress lines) ...
100  125M  100  125M    0     0  2227k      0  0:00:57  0:00:57 --:--:-- 1605k
Moving new system image into place, please reboot to activate

Do as it says and reboot your Cosmo as we must start using the v4 kernel in order to complete the upgrade:
Code: [Select]
sudo reboot
You should see a new Gemian boot logo now, but that's all you'll see until we complete Step 4.

Step 4: Finish installing v4 Linux
In Step 3, we installed lxc-android, but it didn't finish because the new Android system image was not active yet.  Now we'll need to run it again and let it finish, but first we must remove some files that were left over from an automatically attempted systemd upgrade.  If we don't, apt will complain about masked /etc/systemd/system/*.mount unit files.

Log back into the Cosmo via ssh as in Step 2 (you will need to remove and reinsert the USB-C/Ethernet hub first), then do this:
Code: [Select]
for file in `ls -l /etc/systemd/system/ | grep /dev/null | awk '{print $9}'`; do sudo rm -f /etc/systemd/system/$file; done
Now tell apt to finish setting up lxc-android:
Code: [Select]
sudo apt install lxc-android
You should see output similar to this:
Code: [Select]
Reading package lists... Done
Building dependency tree     
Reading state information... Done
lxc-android is already the newest version (0.3+gemian+0~20210422170358.20~1.gbp8861de).
0 upgraded, 0 newly installed, 0 to remove and 2 not upgraded.
1 not fully installed or removed.
After this operation, 0 B of additional disk space will be used.
Do you want to continue? [Y/n]
Setting up lxc-android (0.3+gemian+0~20210422170358.20~1.gbp8861de) ...
Synchronizing state of lxc.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install disable lxc
Synchronizing state of lxc-net.service with SysV service script with /lib/systemd/systemd-sysv-install.
Executing: /lib/systemd/systemd-sysv-install disable lxc-net
Created symlink /etc/systemd/system/ -> /lib/systemd/system/mnt-vendor-protect_s.mount.
Created symlink /etc/systemd/system/ -> /lib/systemd/system/mnt-vendor-protect_f.mount.
Created symlink /etc/systemd/system/ -> /lib/systemd/system/mnt-vendor-persist.mount.
Created symlink /etc/systemd/system/ -> /lib/systemd/system/mnt-vendor-nvdata.mount. 
Created symlink /etc/systemd/system/ -> /lib/systemd/system/mnt-vendor-nvcfg.mount.   
Created symlink /etc/systemd/system/ -> /lib/systemd/system/wlan-module.service.
Created symlink /etc/systemd/system/ -> /lib/systemd/system/lxc-android.service.

If you didn't see that but instead received an error about trying to overwrite some file which is also in some package, you will need to remove said package.  For example, I had alsa-utils installed.  I got this error:
Code: [Select]
dpkg: error processing archive /var/cache/apt/archives/lxc-android_0.3+gemian+0~20210422170358.20~1.gbp8861de_all.deb (--unpack):
 trying to overwrite '/lib/udev/rules.d/90-alsa-restore.rules', which is also in package alsa-utils 1.1.8-2

So I simply removed alsa-utils (for now):
Code: [Select]
sudo apt remove alsa-utils
Then I reran the lxc-android installation command above.

If lxc-android successfully installs as shown above, your system is now upgraded to v4!

Reboot and make sure everything boots up cleanly:
Code: [Select]
sudo reboot

Step 5: Confirm that it really is Gemian v4
Let's see if we actually upgraded to v4.  Log back into the Cosmo and check the kernel version:
Code: [Select]
cat /proc/version
As of this writing, the kernel version, compiler version, and build date are:
Code: [Select]
Linux version 4.4.146 (pbuilder@quasar) (gcc version 8.3.0 (Debian 8.3.0-6) ) #1 SMP PREEMPT Mon Apr 19 21:45:57 UTC 2021
Now try installing a v4-only software package.  I tried camera-app.  New for v4 is camera support.  Unfortunately it uses the same low quality MediaTek drivers and libraries as the stock camera app under Android, but it's better than nothing (unless it dissuades you from using a real camera).  If you're interested in a high quality camera app for Android, try my port of Google Camera for the Cosmo here:

Some of you might have followed my OpenGL 3D acceleration improvement instructions here:
This still works on v4, but not with the camera app.  For the camera app, you should disable gl4es before launching, like this:
Code: [Select]
LD_LIBRARY_PATH= camera-app
My Anbox port, which allows you to run Android apps under Linux on the Cosmo, also works on v4, except this time you shouldn't need to recompile the kernel as the necessary changes were added to the v4 kernel (thanks, Adam Boardman!)
See Anbox for the Cosmo:

Step 6: Help!
"I broke it!"
To fully restore your original Linux installation, boot TWRP as in Step 1, plug your USB-C cable from your workstation into the Cosmo's left port, then perform the commands below from your workstation. 

IMPORTANT!  Check your typing carefully before executing!  Flashing the wrong "p" number (in mmcblk0pXX) could erase other parts of your Cosmo, possibly even bricking it.

Note we must supply /dev/block/mmcblk0p41, not /dev/block/by-name/DEBIAN_KDE, and /dev/block/mmcblk0p43, not /dev/block/by-name/linux, when flashing the Linux boot and system partitions.  Otherwise, the boot image won't take, and the system image write will fail with a "No space left on device" error.

First, restore the Linux boot partition.  Type or paste carefully on your workstation:
Code: [Select]
adb push cosmo_linux_boot_backup /dev/block/mmcblk0p41
This push is instant.

Second, restore the Linux system partition.  Type or paste carefully on your workstation:
Code: [Select]
adb push cosmo_linux_partition_backup /dev/block/mmcblk0p43
It took 7,885 seconds (2.2 hours) for my 83 GiB (90 GB) Linux partition to flash, at a rate of 10.9 MB/s.

Your Linux setup should now be exactly as it was before you attempted the upgrade.  Reboot:
Code: [Select]
adb reboot

"I can't use apt!"
If you get a "Temporary failure resolving ''" error while running apt despite having full Internet access, I can only tell you I had to recompile both the v3 and v4 kernels with CONFIG_ANDROID_PARANOID_NETWORK=n to work around this.  See my post for details:

The v4 kernel compile on Gentoo (but apparently not on Debian) requires a few more symlink workarounds than on the v3 kernel.  Request details if needed.

I have manually upgraded from v3 to v4.  My method does not require reflashing your Linux partition.  If anyone is interested, I will post instructions.  For some of us, the whole point of backing the Gemini/Cosmo was to have a miniature ARM Linux box to hack on.  Having to wipe the partition every new Linux release defeats the purpose.  I've upgraded manually every single release and never had to forfeit my customized Linux setup.  v4 was the trickiest, but it's not impossible.

Cosmo Communicator - Linux / Re: On-device kernel compilation
« on: May 05, 2021, 01:21:17 am »

SL, if your build still needs to run the bundled dtc_overlay, make sure these files exist:
Code: [Select]

If they don't exist, qemu-user-binfmt and/or binfmt-support is not installed properly and x86_64 executables will not transparently run.

Confirmed, they exist.

I think I will need to install v4 of the Cosmo Linux Debian first ( and then report back.
I'm still using v3.  Did you try running dtc_overlay directly?  For example, cd into your kernel directory, then try "scripts/dtc/dtc_overlay -v" and see if it prints "Version: DTC 1.4.2-Android-build" or just complains with a "cannot execute binary file" error.

Cosmo Communicator - Linux / Re: Anbox on Cosmo Linux
« on: May 04, 2021, 08:15:25 pm »
mine is a few builds different to yours: 1.8.0_292-8u292-b10-0ubuntu1~20.10-b10
Sounds like your computer won't relent in our fight to build AOSP 7.1.1 on it, so I've updated my instructions above with a download link to my prebuilt rootfs image.  I don't know how you feel about using a 3rd party build in the Gemian repo, but at least the rootfs image will help other folks get started with Anbox on the Cosmo.  It's in step 4 above in post

Cosmo Communicator - Linux / Re: On-device kernel compilation
« on: May 04, 2021, 12:44:39 am »
Sorry I've not looked into the dtc stuff beyond fixing the errors I encounter when trying to get the kernel to build.
That's interesting... this would seem to suggest that the x86_64 dtc_overlay and ufdt_apply_overlay binaries are supplied by MediaTek.  Looking at scripts/drvgen/ confirms this:
"Copyright (C) 2016 MediaTek Inc."

This "drvgen" isn't in any mainline kernel, it's from MediaTek for their kernels.

So if anyone wants to build as pristine a kernel as possible on-device, using qemu_binfmt appears to be the best way.  But if SL's method of recompiling ufdt_apply_overlay works, great!  By the way, dtc_overlay doesn't need to be recompiled.  The "dtc" binary is built by the kernel build and is in scripts/dtc.  scripts/Makefile.lib was modified from stock to call dtc_overlay instead of dtc, so either changing scripts/Makefile.lib from dtc_overlay to dtc or just copying scripts/dtc/dtc to scripts/dtc/dtc_overlay should work if you're determined to build the kernel on the Cosmo.

Cosmo Communicator - Linux / Re: Anbox on Cosmo Linux
« on: May 04, 2021, 12:26:10 am »
In my experimenting the 'jack-admin start-server' fails to return to the console so I was running it in the background (&) to get it out of the way, it completes some minutes later with 'Jack server failed to (re)start, try 'jack-diagnose' or see Jack server log' yet there is nothing in the logs beyond the ... Starting js(1.3-a8 '1.3')/sc/ac (3 lines) finishing with a ... Start timer.

The jack-diagnose script (if made executable) reports spurious errors (error: process ID list syntax error - try ps ... indicating that its designed to work against some incompatible with ubuntu version of 'ps') unless the last thing was a kill-server when it reports no errors.

I also tried changing the port numbers in both config files, just in case there is something else using them, unsurprisingly to no avail as there is nothing unusual running on this machine.
You shouldn't need to play with the jack-server unless it requires specific tweaks, such as in the case of insufficient RAM.  Otherwise, it is started and stopped by the build process.

If it helps any, I used openjdk-bin-8 on Gentoo.  The build is picky about the JVM version.  This is the output from "java -version":
Code: [Select]
openjdk version "1.8.0_272"
OpenJDK Runtime Environment (AdoptOpenJDK)(build 1.8.0_272-b10)
OpenJDK 64-Bit Server VM (AdoptOpenJDK)(build 25.272-b10, mixed mode)

Cosmo Communicator - Linux / Re: On-device kernel compilation
« on: April 30, 2021, 08:33:05 pm »
Followed your instructions on the wiki page for Kernel Compile, managed to compile, install and run the latest kernel from the created debian package, but still had to apply my fix for dtc and ufdt. For some reason on my set-up qemu did not trigger for dtc_overlay and ufdt_apply_overlay, even though I have qemu installed.

Thanks for the link to the wiki, that helped a bunch.
SL, if your build still needs to run the bundled dtc_overlay, make sure these files exist:
Code: [Select]

If they don't exist, qemu-user-binfmt and/or binfmt-support is not installed properly and x86_64 executables will not transparently run.

Adam, SL and I were discussing dtc_overlay outside of the forum and we couldn't figure out why dtc_overlay had to be bundled with the kernel source instead of using the compiled version of scripts/dtc/dtc.  Can you elaborate on the differences between the built dtc and the bundled dtc_overlay (and ufdt_apply_overlay)?

Cosmo Communicator - Linux / Re: Anbox on Cosmo Linux
« on: April 30, 2021, 08:02:00 pm »
I've still not got your suggested android.img rootfs building though, with your recent fixes it can now build the c++ code but bails on the java code due to the jack-server having a bad day. I tried various suggested fixes to no avail.
jack-server has a bad day if your devel machine has less than 16GB RAM.  Swap space doesn't count towards the 16GB.  I found this out the hard way on a trip recently where, incredibly, I accidentally left my devel laptop in the garage.  How a software engineer of several decades can do something like that I'll never figure out.  I had to borrow a laptop with only 8GB for my development work (at least I remembered to bring my bootable external hard drive).  To get jack-server to run properly on an 8GB machine, I had to do this:

1. Edit $HOME/.jack-settings and add this line:
Code: [Select]
JACK_SERVER_VM_ARGUMENTS="-Dfile.encoding=UTF-8 -XX:+TieredCompilation -Xmx4096m"
2. Restart jack-server:
Code: [Select]
prebuilts/sdk/tools/jack-admin kill-server
prebuilts/sdk/tools/jack-admin start-server

I found this article very useful:

Cosmo Communicator - Linux / Re: Anbox on Cosmo Linux
« on: April 27, 2021, 05:09:53 pm »
However I've got stuck with the building of the suggested android-7 image file. On the Debian 10 build server it complains about lacking tools.jar (related to wanting an older version of java). On my desktop which happens to have many versions of java - external/libavc/decoder/arm/ih264d_function_selector.c:67: error: undefined reference to 'ih264d_init_function_ptr_av8' clang++: error: linker command failed with exit code 1 (use -v to see invocation)

I forgot to add workaround steps to my instructions.  I just edited my orginal post.  I simply commented them out for now... I was in a hurry to get Anbox working one way or another!  Besides, I didn't plan on watching any H264 videos under Anbox...

I could probably debug them but ideally we'd be using a newer version of android, and given that we already have a full copy of lineage* running in an LXC container to allow us to access the hardware, it seems a bit odd to have to go back to something so old.

* - granted this is pending release by Planet.

I initially tried booting Anbox with a rootfs image I built around the system partition (/dev/mmcblk0p36 on /system_root), but couldn't get /init to stop aborting.  I worked around a number of issues with /init trying to mount things that were already mounted by droid-hal, plus a reboot caused by reloading the SELinux policy, but no matter what I did /init still just kept dying with SIGABRT.  At that point I gave up on trying to use the native on-device Android and compiled AOSP from scratch.  Besides, the Anbox build instructions ( say: "For Anbox we're using a minimal customized version of Android but otherwise base all our work of a recent release of the Android Open Source Project."  I figured if they customized it for Anbox, I'd be better off trying their version.  And it worked.  My goal was to run Android apps under Linux at native or near-native speed, which we achieve when meshed with gl4es.  Aside from the camera (really wishing I could use my Google Camera port, I didn't have a use for direct hardware access other than GPS which I worked around.  It's a hack, yes, but the hack also lets me run gpsd and Anbox GPS apps simultaneously.

Cosmo Communicator - Linux / Re: Anbox on Cosmo Linux
« on: April 24, 2021, 08:01:47 am »
By popular demand (one reader), I'm posting my steps to compile and flash the kernel for the Cosmo.

How to compile and flash the Linux and Android kernels for the Cosmo

The following document describes how I compiled both the Linux and the Android kernels for the Cosmo.  I also explain how to create a rooted Android image.  I used an x86_64 Gentoo development machine for all work and nothing was compiled directly on the Cosmo.  I also used live kernel configs as a starting point, not predefined configs from the kernel tree, in an attempt to keep the configuration as close to stock as possible before customizing.

Step 1: Prepare the kernel development tree
Create a directory where you will perform all of your kernel development work:
Code: [Select]
mkdir -p /path/to/cosmo/kernel
Retrieve the Cosmo Linux kernel source code:
Code: [Select]
cd /path/to/cosmo/kernel
git clone

Retrieve the Cosmo Android kernel source code:
Code: [Select]
cd /path/to/cosmo/kernel
git clone

Retrieve and build mkbootimg for manipulating ramdisk boot images:
Code: [Select]
cd /path/to/cosmo/kernel
git clone
cd mkbootimg
cd ..

Retrieve the prebuilt gcc arm64 cross compiler tools:
Code: [Select]
cd /path/to/cosmo/kernel
git clone -b nougat-release --depth 1

Retrieve Planet Computers' Linux v3 firmware:
Code: [Select]
cd /path/to/cosmo
unzip \
  cosmo-customos-installer/linux-cosmo-boot.img \
  cosmo-customos-installer/twrp.img \

"linux-cosmo-boot.img" is the stock Linux ramdisk boot image which contains a ramdisk and the Linux kernel image.

"twrp.img" is the handy TWRP rescue image.

"root-boot.img" is the stock rooted Android boot image with ramdisk and kernel.

Unpack the stock Linux boot image:
Code: [Select]
cd /path/to/cosmo/kernel
mkdir linux_boot
mkbootimg/unpackbootimg -i ../cosmo-customos-installer/linux-cosmo-boot.img -o linux_boot
It prints this:
Code: [Select]
  BOARD_KERNEL_CMDLINE bootopt=64S3,32N2,64N2
And it creates linux-cosmo-boot.img-ramdisk.gz which we will use later.

Unpack the stock rooted Android boot image:
Code: [Select]
cd /path/to/cosmo/kernel
mkdir android_root_boot
mkbootimg/unpackbootimg -i ../cosmo-customos-installer/root-boot.img -o android_root_boot
It prints this:
Code: [Select]
  BOARD_KERNEL_CMDLINE bootopt=64S3,32N2,64N2 buildvariant=user veritykeyid=id:7e4333f9bba00adfe0ede979e28ed1920492b40f
And it creates root-boot.img-ramdisk.gz which we will use later.

Retrieve live kernel configs.  Boot stock Linux or stock Android.  Transfer the file /proc/config.gz to your development machine, unzip, and rename:
Code: [Select]
cd /path/to/cosmo/kernel/cosmo-linux-kernel-4.4  # or cosmo-android-kernel
mv config.gz config-from-live-stock-kernel.gz
gunzip config-from-live-stock-kernel.gz
cp config-from-live-stock-kernel .config

Your kernel development directory tree should now resemble this:
Code: [Select]
 `--  # retrieved 2020-11-18
 `-- cosmo-customos-installer/  # from
     `-- linux-cosmo-boot.img  # stock Linux boot image
     `-- root-boot.img  # stock rooted Android boot image
     `-- twrp.img  # TWRP rescue image
 `-- kernel/
     `-- aarch64-linux-android-4.9/  # from
     `-- cosmo-android-kernel/  # from
         `-- config-from-live-stock-kernel
         `-- .config
     `-- cosmo-linux-kernel-4.4/  # from
         `-- config-from-live-stock-kernel
         `-- .config
     `-- mkbootimg/  # from
     `-- android_root_boot/  # from mkbootimg/unpackbootimg
         `-- root-boot.img-ramdisk.gz
     `-- linux_boot/  # from mkbootimg/unpackbootimg
         `-- linux-cosmo-boot.img-ramdisk.gz

Step 2: Prepare the kernel source for building
In my build environment, the kernel build fails "out of the box" with a truckload of #include errors, plus harmless warnings that are treated as errors.  Please note that other kernel build methods with other cross compilers and/or other host distributions may not experience the same build difficulties I did, and judging from other kernel compilation posts, most don't.  But in case you do, I'm including every issue I hit and how to work around it.

First modify some Makefiles to disable treating warnings as errors.
Code: [Select]
cd /path/to/cosmo/kernel/cosmo-linux-kernel-4.4/
Edit drivers/misc/mediatek/Makefile:
Code: [Select]
# SHUNTCAP: remove this  subdir-ccflags-y += -Werror
Edit: drivers/Makefile:
Code: [Select]
# SHUNTCAP: remove this  subdir-ccflags-y += -Werror
Edit Makefile:
Code: [Select]
#SHUNTCAP: remove this  KBUILD_CFLAGS   += $(call cc-option,-Werror=implicit-int)
Now for the messy part.  In my case, the build could not find a large number of header files.  Here is an example from my Gemini build, but the Cosmo build has the same issues (for me):
Code: [Select]
/devel/gemini/kernel/aarch64-linux-android-4.9/bin/aarch64-linux-android-gcc -Wp,-MD,drivers/misc/mediatek/leds/.mtk_leds_drv.o.d  -nostdinc -isystem /devel/gemini/kernel/aarch64-linux-android-4.9/bin/../lib/gcc/aarch64-linux-android/4.9/include -I./arch/arm64/include -Iarch/arm64/include/generated/uapi -Iarch/arm64/include/generated  -Iinclude -I./arch/arm64/include/uapi -Iarch/arm64/include/generated/uapi -I./include/uapi -Iinclude/generated/uapi -include ./include/linux/kconfig.h -I./drivers/misc/mediatek/include -I. -D__KERNEL__ -mlittle-endian -Wall -Wundef -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -Werror-implicit-function-declaration -Wno-format-security -std=gnu89 -fno-PIE -mgeneral-regs-only -fno-pic -fno-asynchronous-unwind-tables -fno-delete-null-pointer-checks -Wno-maybe-uninitialized -O2 --param=allow-store-data-races=0 -DCC_HAVE_ASM_GOTO -Wframe-larger-than=2800 -fstack-protector-strong -Wno-unused-but-set-variable -fno-omit-frame-pointer -fno-optimize-sibling-calls -fno-var-tracking-assignments -g -Wdeclaration-after-statement -Wno-pointer-sign -fno-strict-overflow -fno-merge-all-constants -fmerge-constants -fno-stack-check -fconserve-stack -Werror=implicit-int -Werror=strict-prototypes -Werror=date-time -I./drivers/misc/mediatek/hibcore -I./drivers/misc/mediatek/include -I./drivers/misc/mediatek/include/mt-plat/mt6771/include -I./drivers/misc/mediatek/include/mt-plat -I./drivers/mmc/host/mediatek/mt6771 -I./drivers/misc/mediatek/leds/mt6771 -I./drivers/misc/mediatek/video/include    -D"KBUILD_STR(s)=#s" -D"KBUILD_BASENAME=KBUILD_STR(mtk_leds_drv)"  -D"KBUILD_MODNAME=KBUILD_STR(mtk_leds_drv)" -c -o drivers/misc/mediatek/leds/.tmp_mtk_leds_drv.o drivers/misc/mediatek/leds/mtk_leds_drv.c
drivers/misc/mediatek/leds/mtk_leds_drv.c:26:26: fatal error: mtk_leds_drv.h: No such file or directory
 #include <mtk_leds_drv.h>

This happens because the compiler is called from the toplevel directory on drivers/misc/mediatek/leds/mtk_leds_drv.c, while mtk_leds_drv.h is in drivers/misc/mediatek/leds, but drivers/misc/mediatek/ is not in the -I include path.  According to gcc documentation, <...h> will not search the current directory unless supplied with the -I directive.  And the build doesn't enter that directory anyway, so it has no way to find the header file even if we add "-I." to the toplevel Makefile.  In this case, drivers/misc/mediatek/leds/Makefile lacks an -I directive to include drivers/misc/mediatek/leds.  #include "mtk_leds_drv.h" would have found it, though.

Fix broken build include paths (again, this may not be necessary in other build environments, but it is in mine):
Code: [Select]
cd /path/to/cosmo/kernel/cosmo-linux-kernel-4.4/drivers/misc/mediatek/include
ln -s ../../../devfreq/*.h .
rm mtk_dvfsrc_reg.h  # Avoid ambiguity with misc/mediatek/base/power/spm_v4/*.h
ln -s ../../../input/fingerprint/aw6302_driver/*.h .
ln -s ../../../input/keyboard/mediatek/*.h .
ln -s ../../../misc/mediatek/base/power/cm_mgr_v1/*.h .
ln -s ../../../misc/mediatek/base/power/mt6771/*.h .
ln -s ../../../misc/mediatek/base/power/ppm_v3/src/mach/mt6771/*.h .
ln -s ../../../misc/mediatek/base/power/spm_v4/*.h .
ln -s ../../../misc/mediatek/base/power/swpm_v1/mt6771/*.h .
ln -s ../../../misc/mediatek/cameraisp/src/isp_50/inc .
ln -s ../../../misc/mediatek/ccu/src/mt6771/ccu_ext_interface .
ln -s ../../../misc/mediatek/cmdq/v3/*.h .
ln -s ../../../misc/mediatek/cmdq/v3/mt6771/*.h .
ln -s ../../../misc/mediatek/eccci/*.h .
ln -s ../../../misc/mediatek/eccci/hif .
ln -s ../../../misc/mediatek/eccci/hif/*.h .
ln -s ../../../misc/mediatek/emi/mt6771/*.h .
ln -s ../../../misc/mediatek/ext_disp/mt6771/*.h .
ln -s ../../../misc/mediatek/leds/*.h .
ln -s ../../../misc/mediatek/m4u/mt6771/*.h .
ln -s ../../../misc/mediatek/mu3phy/*.h .
ln -s ../../../misc/mediatek/sspm/*.h .
ln -s ../../../misc/mediatek/sspm/mt6771/*.h .
ln -s ../../../misc/mediatek/timer/timesync/*.h .
cd inc
ln -s ../../../../usb_c/tcpc/inc/* .
cd ..
ln -s ../../../misc/mediatek/video/common/layering_rule_base/v1.1/*.h .
ln -s ../../../misc/mediatek/video/mt6771/dispsys/*.h .
ln -s ../../../misc/mediatek/video/mt6771/videox/*.h .
ln -s ../../../misc/mediatek/vpu/mt6771/*.h .
ln -s ../../../mmc/host/mediatek/ComboA/*.h .
ln -s ../../../pinctrl/mediatek/*.h .
ln -s ../../../power/mediatek/battery/*.h .
ln -s ../../../watchdog/mediatek/wdt/common/wdt_v2/*.h .

Edit drivers/devfreq/helio-dvfsrc.c:
Code: [Select]
// SHUNTCAP: Ambiguous ./drivers/misc/mediatek/include/mtk_dvfsrc_reg.h symlink must be removed.
// SHUNTCAP: Causes Oops due to pulling wrong DVFSRC_LEVEL* definition (lacking DVFSRC_BASE + offset).
// SHUNTCAP: Shouldn't even need these symlinks, but the build system is broken with MTK using the
// SHUNTCAP: angled includes below when the -I directives don't contain the correct paths.  My
// SHUNTCAP: workaround is to create symlinks to the required header files and place them in
// SHUNTCAP: ./drivers/misc/mediatek/include/ for all MTK source to see despite angled includes.
//#include <helio-dvfsrc.h>  // SHUNTCAP
#include "drivers/devfreq/helio-dvfsrc.h"  // SHUNTCAP
//#include <helio-dvfsrc-opp.h>  // SHUNTCAP
#include "drivers/devfreq/helio-dvfsrc-opp.h" // SHUNTCAP
//#include <mtk_dvfsrc_reg.h>  // SHUNTCAP
#include "drivers/devfreq/mtk_dvfsrc_reg.h"  // SHUNTCAP

And only for the Android kernel, these required files weren't even in the tree:
Code: [Select]
ln -s ../../../../../cosmo-linux-kernel-4.4/include/uapi/linux .
cd /path/to/cosmo/kernel/cosmo-android-kernel/net/netfilter
ln -s ../../../cosmo-linux-kernel-4.4/net/netfilter/xt_HL.c .
ln -s ../../../cosmo-linux-kernel-4.4/net/netfilter/xt_TCPMSS.c .
cd -

Also only for the Android build, I had to change drivers/devfreq/helio-dvfsrc.c to the following (different include path than with the Linux build):
Code: [Select]
#include "helio-dvfsrc.h"  // SHUNTCAP
#include "helio-dvfsrc-opp.h" // SHUNTCAP
#include "mtk_dvfsrc_reg.h"  // SHUNTCAP

Step 3: Add exFAT support (optional)
It's frustrating to insert an exFAT-formatted SD card into the Cosmo only to find out there's no support for the filesystem!  So let's add it.  Credit goes to
Code: [Select]
cd /path/to/cosmo/kernel/
wget -O # (do not git clone; it will pull one requiring Linux 4.9+)
cp -a exfat-linux-old cosmo-linux-kernel-4.4/fs/exfat  # if you're compiling Linux kernel
cp -a exfat-linux-old cosmo-android-kernel/fs/exfat  # if you're compiling Android kernel
cd cosmo-linux-kernel-4.4 # or cosmo-android-kernel

Edit fs/Kconfig, add exfat:
Code: [Select]
source "fs/fat/Kconfig"
source "fs/exfat/Kconfig"

Edit fs/Makefile, add exfat:
Code: [Select]
obj-$(CONFIG_FAT_FS)            += fat/ 
obj-$(CONFIG_EXFAT_FS)          += exfat/

Step 4: Configure the kernel
Make any changes to the kernel configuration before building:
Code: [Select]
cd /path/to/cosmo/kernel/cosmo-linux-kernel-4.4  # or cosmo-android-kernel
CROSS_COMPILE=../aarch64-linux-android-4.9/bin/aarch64-linux-android- ARCH=arm64 make menuconfig

Don't forget to enable exFAT if you added the sources in step 3:
Code: [Select]
File systems -> DOS/FAT/NT Filesystems
  <*> exFAT fs support

Step 5: Compile the kernel
Now compile the kernel:
Code: [Select]
cd /path/to/cosmo/kernel/cosmo-linux-kernel-4.4  # or cosmo-android-kernel
CROSS_COMPILE=../aarch64-linux-android-4.9/bin/aarch64-linux-android- ARCH=arm64 make LOCALVERSION= -j8

You may wish to adjust the -j8 parameter based on your CPU.  -j8 will compile using eight threads.  For example, on a quad-core processor, this number comes from having two threads per core.

Note that you can also use clang to compile your kernel if you prefer.  The stock kernels were built with clang.  If you have installed arm64 clang on your development system and prefer it, use this command instead:
Code: [Select]
make ARCH=arm64 CC=clang CLANG_TRIPLE=aarch64-linux-gnu- CROSS_COMPILE=aarch64-linux-android- V=1 LOCALVERSION= -j8
V=1 is optional and will produce a more verbose output.

The stock Cosmo kernel was built with clang-4691093, which you can obtain here:

Step 6: Create a boot image
Now create the Linux kernel boot image:
Code: [Select]
cd /path/to/cosmo/kernel
mkbootimg/mkbootimg \
  --kernel cosmo-linux-kernel-4.4/arch/arm64/boot/Image.gz-dtb \
  --ramdisk linux_boot/linux-cosmo-boot.img-ramdisk.gz \
  --base 0x40078000 \
  --second_offset 0x00e88000 \
  --cmdline "bootopt=64S3,32N2,64N2" \
  --kernel_offset 0x00008000 \
  --ramdisk_offset 0x14f88000 \
  --tags_offset 0x13f88000 \
  --pagesize 2048 \
  --hash sha1 \
  -o linux_test.img

You will now have a new Linux boot image in

Alternatively, create the Android boot image:
Code: [Select]
cd /path/to/cosmo/kernel
mkbootimg/mkbootimg \
  --kernel cosmo-android-kernel/arch/arm64/boot/Image.gz-dtb \
  --ramdisk android_root_boot/root-boot.img-ramdisk.gz \
  --base 0x40078000 \
  --second_offset 0x00e88000 \
  --cmdline "bootopt=64S3,32N2,64N2 buildvariant=user veritykeyid=id:7e4333f9bba00adfe0ede979e28ed1920492b40f" \
  --kernel_offset 0x00008000 \
  --ramdisk_offset 0x14f88000 \
  --tags_offset 0x13f88000 \
  --pagesize 2048 \
  --hash sha1 \
  --os_version 9.0.0 --os_patch_level 2021-01 \
  -o android_test.img

You will now have a new Android boot image in

Note that this Android boot image does not have root capability.  If you want rooted Android, continue to step 7.  Otherwise, skip to step 8.

Step 7: Root the Android boot image (optional)
To root your Android boot image, boot the Cosmo into Android.  Install Magisk Manager.  Transfer /path/to/cosmo/kernel/android_test.img to the Cosmo, placing it in /sdcard/.  You can use adb from your development machine:
Code: [Select]
adb -s <Cosmo_Serial_Num> push /path/to/cosmo/kernel/android_test.img /sdcard/
Open Magisk Manager, tap the Install button, select android_test.img, and let it root the image.  Now transfer the rooted image back to your development machine:
Code: [Select]
adb -s <Cosmo_Serial_Num> pull /sdcard/kernel/android_test.img rooted_android_test.img

Step 8: Flash your new kernel boot image
The Cosmo has four boot partitions which are accessible by /dev/block/platform/bootdevice/by-name/<partition_name>, where <partition_name> is one of the following:
boot - normal Android (not rooted)
ROOTED_ANDROID - rooted Android
TWRP - TWRP rescue image

We will flash our newly created kernel boot image onto one of these partitions.

IMPORTANT: Before flashing, make sure you have a way to reflash a working Linux kernel if your test kernel is broken.  You can rely on either rooted Android or TWRP and use adb to push your test kernel onto the Cosmo, then flash from there.  In other words, if you don't want to use Planet's SD card method of reflashing your Linux or Android boot partitions, install TWRP or rooted Android NOW.
To flash from Cosmo Linux: first transfer linux_test.img to the Cosmo using the means of your choice.  My personal build script ftp's to the Cosmo at (the Cosmo's RNDIS address as presented when plugged into the development machine's USB port).  Then either ssh into the Cosmo or directly type these commands on it:
Code: [Select]
dd if=/path/to/linux_test.img of=/dev/block/platform/bootdevice/by-name/DEBIAN_KDE
Or from Android or TWRP via adb on your development machine:
Code: [Select]
adb -s <Cosmo_Serial_Num> push ../linux_test.img /sdcard/
adb -s <Cosmo_Serial_Num> shell
dd if=/sdcard/root_test.img of=/dev/block/platform/bootdevice/by-name/DEBIAN_KDE

To flash an Android boot image, use the same dd command but flash to either "ROOTED_ANDROID" or "boot".  For example, for non-rooted Android:
Code: [Select]
dd if=/sdcard/android_test.img of=/dev/block/platform/bootdevice/by-name/bootOr for rooted Android:
Code: [Select]
dd if=/sdcard/rooted_android_test.img of=/dev/block/platform/bootdevice/by-name/ROOTED_ANDROID
I actually have a backup Linux boot image on "boot" and a working Android image on ROOTED_ANDROID.

You can also transfer and flash the stock boot images (see step 1 for names).

Now you can reboot and see if your new kernel boots or not.

Step 9: Find out what went wrong
What, your new kernel didn't boot the first time?  Neither did mine.  At this point, you can either flash a stock boot image back (see step 8 above), or boot to an alternative OS such as TWRP or rooted Android and check the last kernel log to see what went wrong during boot.

Inspect this file on the Cosmo: /proc/last_kmsg

In my case, the kernel source referenced an ambiguous driver header and the wrong one was compiled.  I noted this in /proc/last_kmsg:
Code: [Select]
[    0.991933] -(6)[1:swapper/0]Unable to handle kernel NULL pointer dereference at virtual address 000000e0
[    0.991945] -(6)[1:swapper/0]pgd = ffffff800a109000
[    0.991953] [000000e0] *pgd=00000000ffffe003, *pud=00000000ffffe003, *pmd=0000000000000000
[    0.991971] -(6)[1:swapper/0]Internal error: Oops: 96000045 [#1] PREEMPT SMP
[    0.991981] disable aee kernel api
[    0.991984] -(6)[1:swapper/0]Kernel Offset: 0x0 from 0xffffff8008000000
[    0.991996] Modules linked in:
[    1.992010] -(6)[1:swapper/0]Non-crashing CPUs did not react to IPI
[    1.992022] -(6)[1:swapper/0]CPU: 6 PID: 1 Comm: swapper/0 Tainted: G S      W       4.4.146+ #3
[    1.992036] -(6)[1:swapper/0]Hardware name: MT6771V/CT (DT)
[    1.992044] -(6)[1:swapper/0]task: ffffffc05ff58000 task.stack: ffffffc05ff6c000
[    1.992060] -(6)[1:swapper/0]PC is at dvfsrc_init.part.0+0x44/0x3ac  <-- NOTE THIS FUNCTION NAME: CRASH IS HERE
[    1.992069] -(6)[1:swapper/0]LR is at dvfsrc_init.part.0+0x38/0x3ac
... spew ...
[    2.005768] -(6)[1:swapper/0]<4>[111951692] mtk_wdt_probe+0x14c/0x388
[    2.006373] -(6)[1:swapper/0]****************dump wdt reg end*************
[    2.006943] -(6)[1:swapper/0]wdt_arch_reset: sw reset happen!

From there I saw that it was crashing in drivers/misc/mediatek/base/power/spm_v4/mtk_spm_vcorefs_mt6771.c:dvfsrc_init(). To fix it, I had to patch drivers/devfreq/helio-dvfsrc.c to include the correct header.  At least one other OESF user had the same problem:

This concludes my instructions on compiling and flashing the kernel.  I hope this helps some of you.

Cosmo Communicator - Linux / Re: Anbox on Cosmo Linux
« on: April 17, 2021, 04:25:02 am »
Step 5: Add OpenGL hardware acceleration
Anbox requires OpenGL support to run smoothly.  Although you could skip this step and rely on Mesa's software rendering, you'll be dissatisfied with the slow, choppy rendering while running Anbox.

We will use gl4es to give Cosmo accelerated OpenGL capabilities.  gl4es provides a translation layer between OpenGL for Linux and OpenGL ES for Android.  In other words, it uses Android's native GLES libraries to render OpenGL calls under Linux.

First install glxgears from the mesa-utils package:
Code: [Select]
apt install mesa-utils
Now run glxgears and note the frame rate.  On my Cosmo without gl4es 3D acceleration, I see roughly 156 FPS.  After gl4es, I see over 1100 FPS.  That should be enough motivation for the reader to complete this step!  I have seen rates as low as 900 but also as high as 1300, depending on how the Cosmo feels that day.

Fetch the latest gl4es code here:

Unzip it, then enter the directory.
Code: [Select]
cd gl4es-master
mkdir build
cd build
cmake ..
make -j8
cd ..

After that finishes building, install it manually:
Code: [Select]
mkdir -p /opt/gl4es/lib
cp lib/ /opt/gl4es/lib
cp /system/lib64/{,,,} /opt/gl4es/lib

The key to getting gl4es to work properly is copying the native GLES libraries from /system, which is automatically mounted by droid-hybris on boot.  These are from the Android system partition on /dev/mmcblk0p36 (/dev/block/platform/bootdevice/by-name/system).  Without these critical native libraries, gl4es will revert to using software rendering via as installed by libegl1 (and hence libegl-mesa0).

Now try running the following command:
Code: [Select]
LD_LIBRARY_PATH=/opt/gl4es/lib:$LD_LIBRARY_PATH glxinfo | grep GLSL
You should see this:
Code: [Select]
LIBGL: GLSL 300 es supported
LIBGL: GLSL 310 es supported and used

And try this command, too:
Code: [Select]
LD_LIBRARY_PATH=/opt/gl4es/lib:$LD_LIBRARY_PATH glxinfo | grep -i vendor
You should see this:
Code: [Select]
LIBGL: Hardware vendor is ARM
server glx vendor string: ptitSeb
client glx vendor string: ptitSeb
OpenGL vendor string: ptitSeb

If you see "Vendor: VMware, Inc." then your gl4es installation is incorrect.

Finally, try running glxgears and note the frame rate:
Code: [Select]
LD_LIBRARY_PATH=/opt/gl4es/lib:$LD_LIBRARY_PATH glxgears
You should see something like this:
Code: [Select]
5621 frames in 5.0 seconds = 1124.089 FPS
5465 frames in 5.0 seconds = 1092.959 FPS
5687 frames in 5.0 seconds = 1137.375 FPS
5705 frames in 5.0 seconds = 1140.879 FPS

You should NOT see something like this (slow software rendering):
Code: [Select]
714 frames in 5.0 seconds = 142.674 FPS
752 frames in 5.0 seconds = 150.320 FPS
754 frames in 5.0 seconds = 150.681 FPS
766 frames in 5.0 seconds = 153.027 FPS

If you saw high frame rates, you have successfully built and installed gl4es.  Try running some 3D OpenGL games now.  You'll be pleased with the speed increase.

You most likely won't want to keep setting LD_LIBRARY_PATH each time you run a command.  To install system-wide, add the following line to /etc/profile:
Code: [Select]
export LD_LIBRARY_PATH=/opt/gl4es/lib:$LD_LIBRARY_PATH

Step 6: Test Anbox
If you've made it this far, you're itching to try things out!  Anbox consists of two main parts: the LXC container which runs Android, and the session manager.  We have already configured systemd to start Anbox on boot, but we can also start the container and session manager manually for testing.

Start the Anbox container service (as root):
Code: [Select]
systemctl start anbox-container-manager
Start the Anbox session manager (as user):
Code: [Select]
systemctl --user start anbox-session-manager
Or, if you prefer to start it without systemctl to view any potential error output, do this:
Code: [Select]
LD_LIBRARY_PATH=/opt/gl4es/lib anbox session-manager
A properly running Anbox setup will show the following processes (try running ps ax | grep anbox | grep -v grep):
Code: [Select]
23899 ?        Ssl    0:00 /usr/bin/anbox container-manager --daemon --privileged --data-path=/var/lib/anbox
23918 ?        Sl     0:03 anbox session-manager
23949 ?        Ss     0:00 [lxc monitor] /var/lib/anbox/containers default
23989 pts/3    Sl     0:00 /system/bin/anboxd
24413 pts/3    Sl     0:00 org.anbox.appmgr

Now try starting the Anbox app manager:
Code: [Select]
anbox launch --package=org.anbox.appmgr --component=org.anbox.appmgr.AppViewActivity
You should see a window called "Anbox Application Manager" appear with various app icons: Calculator, Calendar, Settings, etc.  Try them out.  They should be fast and responsive if your gl4es installation is working.  Camera does not work (did you expect it to?)

Now reboot and try launching the application manager again to make sure everything starts up automatically.

Anbox logs are located in /var/lib/anbox/logs/ and are only available while the container is running because I've mounted this as a tmpfs to eliminate flash writes (see /lib/systemd/system/anbox-container-manager.service).  /var/lib/anbox/logs/console.log is the session manager log, while /var/lib/anbox/logs/container.log is the LXC container log.

Step 7: Add your own apps
Google Play Store does not work at present, but I am working on it and will update these instructions if I succeed.

Anbox runs adbd, so all you need to do to install an APK is use adb from a command line.  For example, F-Droid works well with Anbox.  Download the APK here:

To install it, simply do this:
Code: [Select]
adb install F-Droid.apk
You should see it appear in the application manager window.

Apps can also be started from the command line.  You just need to figure out the name of the intent that starts the app.  Here's how, using OsmAnd+ as an example.  First get a shell in the Anbox container (as root):
Code: [Select]
Now monitor the system log as follows:
Code: [Select]
logcat | grep START.*intent
In the application manager window, start your app (here, OsmAnd+).  Watch the last line of output from your shell:
Code: [Select]
04-17 02:58:24.196   120   881 I ActivityManager: START u0 {act=android.intent.action.MAIN cat=[android.intent.category.LAUNCHER] flg=0x10000000} from uid 10000 on display 0
Note the pkg= and cmp= values.  Removing any / character, insert them into the following command:
Code: [Select]
anbox launch
Noe that --package matches pkg and --component matches cmp.  Just remember to remove the slash / character.

If you would like to add a shortcut or menu launcher to your favorite window manager, you can add the appropriate "anbox launch ..." command to your desktop configuration.

Not all apps work with Anbox, but a lot do.

Step 8: GPS (optional)
The Cosmo GPS receiver works under Linux.  And even better, it can be used with Anbox.  We will use libhybris to access the GPS sensor with the MediaTek closed-source Android driver, pipe the NMEA sentences into a fake serial port, and use D-Bus to send the sentences to the location service in Anbox.

First fetch the ubports libhybris source here:

Unzip it and enter the directory:
Code: [Select]
cd libhybris-master

It doesn't compile without changing hybris/common/hooks.c:
Code: [Select]
static struct _hook hooks_common[] = {
    {"cfree", /*c*/free },  // SHUNTCAP
    {"writev", write/*v*/}, // SHUNTCAP

The GPS test program seg faults because it hasn't been updated to use the newer Android GPS callback structure, so we need to fix it.  This is why we cannot simply install libhybris-test from the Gemian repository.  Edit hybris/tests/test_gps.c and make the following changes:
Code: [Select]
static void empty_callback(void) {}  // SHUNTCAP: ADD THIS

GpsCallbacks callbacks = {
  empty_callback,  // SHUNTCAP: ADD THIS (request_utc_time_cb)
  empty_callback,  // SHUNTCAP: ADD THIS (set_system_info_cb)
  empty_callback   // SHUNTCAP: ADD THIS (gnss_sv_status_cb)


  while(1/*sleeptime > 0*/)  // SHUNTCAP: RUN FOREVER

Now build it:
Code: [Select]
debian/rules build
This creates a file called ./hybris/tests/.libs/test_gps, among other things.  Install it:
Code: [Select]
cp ./hybris/tests/.libs/test_gps /usr/local/bin
Run test_gps to make sure you see NMEA sentences.

To feed GPS data into Anbox, run this command:
Code: [Select]
test_gps | grep nmea.*: | sed -u 's/nmea.*\$/\$/' | while read LINE; do dbus-send --session --dest=org.anbox --print-reply /org/anbox org.anbox.Gps.PushSentence string:"$LINE"; done &
Now under Anbox, see if you have a lock on your GPS coordinates.  Try SatStat.  It is available on F-Droid.

As a bonus, you can also use the GPS with Linux programs such as gpsd and QGIS by creating a fake serial port that acts like a serial GPS receiver.  Just run these commands as root:
Code: [Select]
test_gps | grep nmea.*: | sed -u 's/nmea.*\$/\$/' | socat - pty,link=/dev/ttyS2,rawer,echo=0,b4800 &
chmod 0644 /dev/ttyS2

Now configure gpsd or any other GPS software that directly reads a serial GPS receiver to use /dev/ttyS2.

This concludes my article on building Anbox for the Cosmo from scratch.  Comments are welcome.

Cosmo Communicator - Linux / Re: Anbox on Cosmo Linux
« on: April 17, 2021, 04:23:59 am »
Anbox for the Cosmo
This article describes how to build and install Anbox for Cosmo Linux.  Anbox is "Android in a Box."  It is a software package that runs Android apps under Linux using LXC (Linux Containers).  Your android apps can literally run in their own windows alongside your native Linux programs.  For many users, this could relieve them of the need to dual-boot the Cosmo.

I might provide prebuilt images of the kernel and Anbox image at a later date depending on user interest.  For now, I present my instructions for building Anbox from scratch.  I assume that the reader is comfortable building and flashing Linux kernels, compiling software from scratch, and building Android AOSP images.

Step 1: Configure the Cosmo Linux kernel
You will need to download v3 of the Cosmo Linux kernel here:

Unzip and build for the Cosmo.  You can find instructions elsewhere on OESF, such as here:
I did not write them and I use a different procedure, but they may work for you.

Flash it and make sure it works.  If enough people have trouble building and flashing the Cosmo kernel, I can post the steps that I use in my development.  Alternatively, I might provide my own kernel image for users to flash at their own risk.  I did have to make a number of changes to the kernel source as it did not compile "out of the box."

Now reconfigure the kernel.

Enable these for iptables to work (called by /usr/share/anbox/
Code: [Select]
Networking support -> Networking options -> Network packet filtering framework (Netfilter) -> Core Netfilter Configuration:
    <*> Netfilter nf_tables support
    <*>   Netfilter nf_tables mixed IPv4/IPv6 tables support
    <*>   Netfilter nf_tables netdev tables support
    <*>   Netfilter nf_tables IPv6 exthdr module
    <*>   Netfilter nf_tables meta module
    <*>   Netfilter nf_tables conntrack module
    <*>   Netfilter nf_tables rbtree set module
    <*>   Netfilter nf_tables hash set module
    <*>   Netfilter nf_tables counter module
    <*>   Netfilter nf_tables log module
    <*>   Netfilter nf_tables limit module
    <*>   Netfilter nf_tables masquerade support
    <*>   Netfilter nf_tables redirect support
    <*>   Netfilter nf_tables nat module
    <*>   Netfilter nf_tables queue module
    <*>   Netfilter nf_tables reject support
    <*>   Netfilter x_tables over nf_tables module

We only need some of these nf_tables options for Anbox, but there's no harm in giving our kernel full functionality.

Code: [Select]
Networking support -> Networking options -> Network packet filtering framework (Netfilter) -> Core Netfilter Configuration -> Netfilter Xtables support:
    <*>   CHECKSUM target support

Add this to kernel (CONFIG_VETH=y):
Code: [Select]
Device drivers -> Network device support -> Network core driver support:
    <*>     Virtual ethernet pair device

Add squashfs support:
Code: [Select]
File systems -> Miscellaneous filesystems:
    <*>   SquashFS 4.0 - Squashed file system support
    Decompressor parallelisation options (Use multiple decompressors for parallel I/O)
    [*]     Squashfs XATTR support
    [*]     Include support for ZLIB compressed file systems
    [*]     Include support for LZ4 compressed file systems
    [*]     Include support for LZO compressed file systems
    [*]     Include support for XZ compressed file systems
    [*]     Use 4K device block size?

And if you find that apt is unable to resolve hostnames despite your Cosmo having full Internet access, configure CONFIG_ANDROID_PARANOID_NETWORK=n here:
Code: [Select]
Networking support -> Networking options:
    [ ] Only allow certain groups to create sockets

Step 2: Fix the kernel
Anbox uses iptables.  But on the Cosmo, iptables causes a reboot as soon as it is run.  The cause is a null pointer access in the kernel.  Edit the following file and make the indicated fix (add the NULL check for ssk).

Enter the kernel source directory:
Code: [Select]
cd /path/to/cosmo-linux-kernel-4.4-master
Edit net/netlink/af_netlink.c:
Code: [Select]
int netlink_unicast(struct sock *ssk, struct sk_buff *skb,
                    u32 portid, int nonblock)
        struct sock *sk;
        int err;
        long timeo;

        skb = netlink_trim(skb, gfp_any());

        // SHUNTCAP: prevent null pointer access from crashing kernel
        // and rebooting Cosmo PDA when iptables command is run
        if (ssk == NULL) {
                printk("SHUNTCAP: warning: ssk is null in %s:%s line %d\n",
                        __FILE__, __FUNCTION__, __LINE__);
                return PTR_ERR(ssk);
        }  // End of SHUNTCAP added
        timeo = sock_sndtimeo(ssk, nonblock);

While we're inside the kernel source, we might as well fix that annoying Cosmo keyboard ghosting issue.  For those of us who type very fast, keyboard ghosting is an incredibly aggravating hardware bug.  Type "more" very quickly and you'll get "mor0e".  Type "()" very quickly (without releasing the shift key) and you'll get "(0)".  Insanely frustrating.

This ghosting issue started with the Gemini.  Users complained.  A community fix was implemented.  So when the Cosmo came along and Planet Computers had the opportunity to build the keyboard hardware properly or at least implement the community kernel patch, they promptly... did nothing.

I believe Adam Boardman is to credit for this fix on the Gemini, but I am not 100% certain.  EDIT: according to my old notes, it was Nathan Banks.

Edit drivers/misc/mediatek/aw9523/aw9523_key.c:
Code: [Select]
static void aw9523_key_eint_work(struct work_struct *work)
                        //printk("0x%02x, ", keyst_new[i]);
                        // //i=p1 keyst[i]=p0
        // AW9523_LOG("\n");

        /* This routine prevents ghosting.  As an example, if Control+L_Shift+N is pressed,
         * the keyboard detects both N & M at the same time due to the electronic circuit.
         * Rather than detect both keys, block both keys until either Control or L_Shift is
         * released, then detect the correct keypress. See */
        if (memcmp(keyst_old, keyst_new, P1_NUM_MAX)) { // keyst changed
                val = P0_KROW_MASK; // The distinct columns used
                y = 0;
                update_now = true; // Now by default, do the update since keyst changed.
                for(i = 0; i < P1_NUM_MAX; i++) {
                        if (keyst_new[i]==P0_KROW_MASK) {
                                // Most of the time no key is pressed, skip it.
                        x = 0; // Count the number of keys pressed (ie. clear bits)
                        for (j = 0; j < P0_NUM_MAX; j++) {
                                if (! (keyst_new[i] & (1 << j))) {      // press
                                        x++; // Increase whenever this bit is clear.
                                        // Boolean expression is false if a previous row
                                        // also has this bit clear.  In this case, the
                                        // keyboard is ghosting, and update_now is false.
                                        update_now = update_now && (val & (1 << j));
                        // If more than one key in this row is pressed, remember which bits
                        // are clear so we can check for ghosting in other rows.
                        if (x>1) {
                                val &= keyst_new[i];

        // update_now is set when the key state changes and there's no ghosting right now.  // SHUNTCAP: ADD
        if (update_now) {  // SHUNTCAP: ADD
                if (memcmp(keyst_old, keyst_new, P1_NUM_MAX)) { // keyst changed
                        memcpy(keyst_old, keyst_new, P1_NUM_MAX);
        }  // SHUNTCAP: ADD

Build, flash, and test the new kernel.  I strongly suggest installing TWRP on one of your Cosmo boot partitions so you can reflash a working stock kernel via adb just in case you break your Linux boot.

Step 3: Build Anbox on the Cosmo
The anbox package in the Gemian repository does not work properly.  In fact, it doesn't even include a rootfs image.  We'll build that later, but first we must build Anbox from scratch.  We will do this directly on the Cosmo.

Install the necessary development packages:
Code: [Select]
apt install build-essential cmake cmake-data debhelper dbus google-mock libboost-dev \
 libboost-filesystem-dev libboost-log-dev libboost-iostreams-dev libboost-program-options-dev \
 libboost-system-dev libboost-test-dev libboost-thread-dev libcap-dev libexpat1-dev libsystemd-dev \
 libegl1-mesa-dev libgles2-mesa-dev libglm-dev libgtest-dev liblxc1 libproperties-cpp-dev \
 libprotobuf-dev libsdl2-dev libsdl2-image-dev lxc-dev pkg-config protobuf-compiler python3-minimal

Check out the Anbox source:
Code: [Select]
git clone --recurse-submodules
Build Anbox:
Code: [Select]
cd anbox
# Comment out add_subdirectory(tests) in CMakeLists.txt as it breaks the build
# and we don't need it anyhow
sed -i 's/add_subdirectory(tests)/#add_subdirectory(tests)/' CMakeLists.txt
mkdir build
cd build
cmake ..
make -j8

Assuming a successful build, install it:
Code: [Select]
make install
You should now see an executable called anbox the /usr/local/bin directory.

Create the Anbox directory structure:
Code: [Select]
mkdir -p /var/lib/anbox/{cache,containers,data,devices,logs,ramdisk,rootfs,state}
Install the network bridge script to give Anbox networking capabilities:
Code: [Select]
mkdir -p /usr/share/anbox
cp ./scripts/ /usr/share/anbox/

The /usr/share/anbox/ requires some changes to work on the Cosmo.  Edit the file, then change all occurances of "iptables" to "iptables-legacy" and save.

Install a convenient root shell script to access the Anbox LXC container shell:
Code: [Select]
cp scripts/ /usr/local/bin
The Anbox container can be configured to start on boot, controlled by systemd.  Create a new systemd service file:
Code: [Select]
echo "[Unit]
Description=Anbox Container Manager

ExecStartPre=/usr/bin/mount -t tmpfs tmpfs /var/lib/anbox/logs
ExecStartPre=/usr/share/anbox/ start
ExecStart=/usr/bin/anbox container-manager --daemon --privileged --data-path=/var/lib/anbox
ExecStopPost=/usr/share/anbox/ stop
ExecStopPost=/usr/bin/umount /var/lib/anbox/logs

[Install]" > /lib/systemd/system/anbox-container-manager.service

Create a new systemd user service to start and stop the Anbox session manager:
Code: [Select]
echo "[Unit]
Description=Anbox Session Manager

ExecStart=/usr/bin/anbox session-manager

[Install]" > /usr/lib/systemd/user/anbox-session-manager.service

Now enable the session manager service.  It will automatically start on first login:
Code: [Select]
systemctl --global enable anbox-session-manager
Add support for hardware-accelerated OpenGL gl4es (described in step 5 below).  Edit /etc/systemd/user.conf and make this change:
Code: [Select]
DefaultEnvironment=LD_LIBRARY_PATH=/opt/gl4es/lib DISPLAY=:0
You might want a desktop entry for Anbox if you use a fancy window manager:
Code: [Select]
echo "[Desktop Entry]
GenericName=Application Manager
Comment=Android in a box
Exec=anbox launch --package=org.anbox.appmgr --component=org.anbox.appmgr.AppViewActivity
Categories=Utility;" > /usr/share/applications/anbox.desktop

Step 4: Build or download Android image from AOSP
Anbox requires an Android filesystem (rootfs) image to run.  On a device running Android natively, this is a ramdisk mounted on / which includes init and its associated scripts, plus a basic directory structure in which other data partitions are mounted (such as /system).  But with Anbox, we need to create a squashfs image from AOSP (Android Open Source Project) to simulate that filesystem.

If you do not wish to or cannot build AOSP from scratch, you can download my 238MB prebuilt image here:

After downloading, rename and install the file:
Code: [Select]
mv /path/to/android.img_AOSP_7.1.1_anbox_arm64_2021-04-08 /var/lib/anbox/android.img
If you download the image, you can skip the following instructions and jump to step 5.

To build AOSP, we need an x86 machine with at least 16GB of RAM and 62GB of free hard drive space.  It's possible to build with less; if necessary, I can post instructions.  My instructions for building AOSP are based on this document:
But follow my instructions, not those, or you'll end up wasting a lot of hard drive space.

You will need the repo tool which might be in your distribution already, but don't count on it being current.  I'd recommend getting the latest version as shown in my instructions below.

First check out the Anbox version of AOSP:
Code: [Select]
mkdir anbox-work
cd anbox-work
curl > repo
export PATH=`pwd`:$PATH
repo init -u -b anbox --depth=1
repo sync -c -j4

The --depth=1 and the -c options will greatly reduce the size of the downloaded repository, only checking out the current branch (-c) and not retrieving all the unneeded history (--depth=1).

Over a fast fiberoptic WAN, the download took about an hour and a half.

Fix a few files with undefined functions that we (hopefully) won't need anyhow.  While I normally prefer to find the root cause of the compile failure, for now, let's just comment them out:
external/libavc/decoder/arm/ih264d_function_selector.c, line 67:
Code: [Select]
// SHUNTCAP: undefined function            ih264d_init_function_ptr_av8(ps_codec);
external/libavc/encoder/arm/ih264e_function_selector.c, line 111:
Code: [Select]
// SHUNTCAP: undefined function           ih264e_init_function_ptr_neon_av8(ps_codec);
external/libmpeg2/common/ideint.c, lines 162 and 180:
Code: [Select]
// SHUNTCAP: undefined function       ps_ctxt->s_params.e_arch = ideint_default_arch();
// SHUNTCAP: undefined function   ideint_init_function_ptr(ps_ctxt);

external/libmpeg2/decoder/arm/impeg2d_function_selector.c, line 80:
Code: [Select]
// SHUNTCAP: undefined function           impeg2d_init_function_ptr_av8(ps_codec);
Now build AOSP:
Code: [Select]
. build/
lunch anbox_arm64-userdebug
make -j8

If successful, you'll see a file in ./out/target/product/arm64/system.img. Transfer that over to the Cosmo.  Mount it, then build a squashfs rootfs image from it (on the Cosmo):
Code: [Select]
apt install squashfs-tools
mkdir system_mnt
mount -o loop system.img system_mnt
mksquashfs system_mnt/* /var/lib/anbox/android.img
umount system_mnt
rmdir system_mnt

Pages: [1] 2 3 ... 6