Georg Lukas, 2024-07-15 18:18
In 2013, Samsung released the Galaxy NX (EK-GN100, EK-GN120, internal name "Galaxy U"), half Android smartphone, half interchangeable lens camera with a 20.3MP APS-C sensor, as part of the NX lineup that I analyzed last year.
A decade later, the Galaxy NX is an expensive rarity on the used market. Luckily, I was able to obtain one of these Android+Linux-SoC hybrids, and will find out what makes it tick in this post.
Hardware Overview
The Android part can probably be called a "phablet" by 2013's standards, given its 4.8" screen and lack of a speaker / microphone. It's powered by the 1.6GHz quad-core Exynos 4412 SoC, featuring LTE connectivity and dual-band WiFi. Back then, there was no VoLTE, so the lack of audio is understandable, and anyway it might look a bit weird to hold a rather large mirrorless camera with an even larger lens to your head.
Due to the large touchscreen, there is not much space for physical camera controls. Just the mode dial, shutter and video recording buttons. Most NX lenses have an additional i-Fn button to cycle through manual camera settings.
From the outside, it's not clear how the Android SoC and the DRIMeIV camera SoC interact with each other. They seem to live in an open relationship, anyway: from time to time, the camera SoC will crash, only showing a black live view, and the Android will eventually find that out and try to restart it (without much success):
Shutting down the camera, removing the battery and restarting everything will calm the evil ghosts... for a while.
Of the 2GB of physical RAM, Android can see 1.5GB, probably meaning that the remaining 512MB are assigned to the DRIMeIV SoC, matching the NX300. We'll do the flash and firmware analysis further below.
Android 4.2 is dead
The latest (and only) Android firmware released by Samsung is Android 4.2.2 Jelly Bean from 2012. There are no official or unofficial ports of later Android releases. The UI is snappy, but the decade of age shows, despite Samsung's customizing.
The dated Android is especially painful due to three issues: lack of apps, outdated encryption, and outdated root certificates:
Issue 1: No apps compatible with Android 4.2
Keeping an app backward-compatible is work. Much work. Especially with Google moving the goalposts every year. Therefore, most developers abandon old Android versions whenever adding a new feature in a backward-compatible fashion would be non-trivial.
Therefore, we need to scrape decade-old APK files from the shady corners of the Internet.
Free & Open Source apps
Google Play is of no help here, but luckily the
F-Droid community cares about old devices.
Less luckily, the old version of F-Droid will OOM-crash under the weight of
the archive repository,
so packages have to be hunted down and installed manually with adb
after
enabling
developer settings.
I had to look up the package name for each app I was interested in, then
manually search for the latest compatible MinVer: 4.
build in the
view-source
of the respective
archive browser page:
- F-Droid: org.fdroid.fdroid, 1.12.1 (2021-04-16) APK (8MB)
- Firefox: org.mozilla.fennec_fdroid, 68.12.0 (2020-08-29) APK (53MB)
- Mastodon: org.joinmastodon.android, first version on F-Droid already requires Android 6. Bummer.
- Fedilab (Mastodon client): fr.gouv.etalab.mastodon, 2.2.0 (2019-06-03) APK (17MB)
- Tusky (Mastodon client): com.keylesspalace.tusky, 1.4.1 (2017-12-07) APK (3MB)
- yaxim: oh look, the newest release still works on 4.x! APK (3MB)
In the end, the official Mastodon client wasn't available, and the other ones were so old and buggy (and/or suffered from issues 2 and 3 below) that I went back to using the mastodon web interface from Firefox.
Proprietary Apps
As everywhere on the Internet, there is a large number of shady,
malware-pushing, SEO-optimized, easy to fall for websites that offer APK
files scraped from Google Play. Most of them will try to push their own
"installer" app to you, or even disguise their installer as the app you
try to get.
Again, knowing the internal package name helps finding the right page. Searching multiple portals might help you get the latest APK that still supports your device.
- apkmonk - scroll down to "All Versions", clicking on an individual version will start the APK download (no way to know the required Android release without trial and error).
- APKPure - don't click on "Use APKPure App", don't install the browser extension. Click on "Old versions of ..." or on "All Versions". Clicking an individual version in the table will show the required Android release.
- APKMirror - has a listing of old versions ("See more uploads..."), but only shows the actual Android release compatibility on the respective app version's page.
Issue 1b: limited RAW editing
TL;DR: Snapseed fails, but Lightroom works with some quirks on the Galaxy NX. Long version:
The Galaxy NX is a camera first, and a smartphone phablet second.
It has very decent interchangeable lenses, a 20MP sensor, and can record
RAW photos in Samsung's
SRW
format.
Snapseed: error messages galore
Given that it's also an Android device, the free
Snapseed
tool is the most obvious choice to process the RAW images. It supports the
industry standard Adobe patented openly-documented
"digital negative" DNG
format.
To convert from RAW to DNG
, there is a convenient tool named
raw2dng that supports quite a
bunch of formats, including SRW
. The latest version running on Android 4.2 is
raw2dng 2.4.2.
The app's UI is a bit cumbersome, but it will successfully convert SRW
to
DNG
on the Galaxy NX! Unfortunately, it will not add them to the Android
media index, so we also need to run
SD Scanner
after each conversion.
Yay! We have completed step 1 out of 3! Now, we only need to open the
newly-converted DNG
in Snapseed.
The latest Snapseed version still running on Android 4.2 is Snapseed 2.17.0.
That version won't register as a file handler for DNG
files, and you can't
choose them from the "Open..." dialog in Snapseed, but you can "Send to..." a
DNG
from your file manager:
Okay, so you can't. Well, but the "Open..." dialog shows each image twice, the
JPG
and the SRW
, so we probably can open the latter and do our RAW editing
anyway:
Bummer. Apparently, this feature relies on DNG
support that was only
added in Android 5.
But the error message means that it was deliberately blocked, so
let's downgrade Snapseed... The error was added in 2.3; versions 2.1 and 2.0
opened the SRW
but treated it like a JPG (no raw development, probably an
implicit conversion implemented by Samsung's firmware; you can also use raw
images with other apps, and then they run out of memory and crash). Snapseed
2.0 finally doesn't have this error message... but instead another one:
So we can't process our raw photos with Snapseed on Android 4.2. What a pity.
Lightroom: one picture a time
Luckily, there is a commercial alternative: Adobe Lightroom. The last version for our old Android is Lightroom 3.5.2.
As part of the overall
enshittification, it
will ask you all the time to login / register with your Adobe account, and
will refuse editing SRW
pictures (because they "were not created on the
device"). However, it will actually accept (and process!) DNG
files
converted with raw2dng and indexed with SD Scanner, and will allow basic
development including full resolution JPEG exports.
However, you may only ever "import" a single DNG
file at a time (it takes
roughly 3-4 seconds). If you try to import multiple files, Lightroom will hang
forever:
It will also remember the pending imports on next app start, and immediately hang up again. The only way out is from Android Settings âž¡ Applications âž¡ Lightroom âž¡ Clear data; then import each image individually into Lightroom.
Issue 2: No TLS 1.3, deactivated TLS 1.2
In 2018, TLS 1.3 happened, and pushed many sites and their API endpoints to remove TLS 1.0 and 1.1.
However, Android's SSLSocket
poses a problem here.
Support for TLS 1.1 and 1.2 was introduced in Android 4.1, but only enabled by
default in Android 5. Apps that didn't explicitly enable it on older devices
are stuck on TLS 1.0, and are out of luck when accessing securely-configured
modern API endpoints. Given that most apps abandoned Android 4.x compatibility
before TLS 1.2 became omnipresent, the old APKs we can use won't work with
today's Internet.
There is another aspect to TLS 1.2, and that's the introduction of elliptic-curve certificates (ECDSA ciphers). Sites that switch from RSA to DSA certificates will not work if TLS 1.2 isn't explicitly enabled in the app. Now, hypothetically, you can decompile the APK, patch in TLS 1.2 support, and reassemble a self-signed app, but that would be real work.
Note: TLS 1.3 was only added (and activated) in Android 10, so we are completely out of luck with any services requiring that.
Of course, the TLS compatibility is only an issue for apps that use Android's native network stack, which is 99.99% of all apps. Firefox is one of the few exceptions as it comes with its own SSL/TLS implementation and actually supports TLS 1.0 to 1.3 on Android 4!
Issue 3: Let's Encrypt Root CA
Now even if the service you want to talk to still supports TLS 1.0 (or the respective app from back when Android 4.x was still en vogue activated TLS 1.2), there is another problem. Most websites are using the free Let's Encrypt certificates, especially for API endpoints. Luckily, Let's Encrypt identified and solved the Android compatibility problem in 2020!
All that a website operator (each website operator) needs to do is to ensure that they add the DST Root CA X3 signed ISRG Root X1 certificate in addition to the Let's Encrypt R3 certificate to their server's certificate chain! 🤯
Otherwise, their server will not be trusted by old Android:
Such a dialog will only be shown by apps which allow the user to override an "untrusted" Root CA (e.g. using the MemorizingTrustManager). Other apps will just abort with obscure error messages, saying that the server is not reachable and please-check-your-internet-connection.
Alternatively, it's possible to patch the respective app (real work!), or to add the LE Root CA to the user's certificate store. The last approach requires setting an Android-wide password or unlock pattern, because, you know, security!
The lock screen requirement can be worked around on a rooted device by adding
the certificate to the /system
partition, using apps like the Root
Certificate Manager(ROOT) (it requires root
permissions to install Root
Certificatfes to the root filesystem!), or following an easy
12-step adb-shell-bouncycastle-keytool tutorial.
Getting Root
There is a handful of Android 4.x rooting apps that use one of the many well-documented exploits to obtain temporary permissions, or to install some old version of SuperSU. All of them fail due to the aforementioned TLS issues.
In the end, the only one that worked was the
Galaxy NX (EK-GN120) Root
from XDA-Dev, which needs to be installed through Samsung's
ODIN, and
will place a su
binary and the SuperSU app on the root filesystem.
Now, ODIN is not only illegal to distribute, but also still causes PTSD
flashbacks years after the last time I used it. Luckily,
Heimdall is a FOSS replacement that
is easy and robust, and all we need to do is to extract the tar
file and
run:
heimdall flash --BOOT boot.img
On the next start, su
and SuperSu will be added to the /system
partition.
Firmware structure
This is a slightly more detailed recap of the earlier Galaxy NX firmware analysis.
Android firmware
The EK-GN120 firmware is a Matryoshka
doll of containers. It is provided as a ZIP that contains a .tar.md5
file (and a DLL?! Maybe for Odin?):
Archive: EK-GN120_DBT_1_20140606095330_hny2nlwefj.zip
Length Method Size Cmpr Date Time CRC-32 Name
-------- ------ ------- ---- ---------- ----- -------- ----
1756416082 Defl:N 1144688906 35% 2014-06-06 09:53 4efae9c7 GN120XXUAND3_GN120DBTANE1_GN120XXUAND3_HOME.tar.md5
1675776 Defl:N 797975 52% 2014-06-06 09:58 34b56b1d SS_DL.dll
-------- ------- --- -------
1758091858 1145486881 35% 2 files
The .tar.md5
is an actual tar archive with an appended MD5 checksum. They
didn't even bother with a newline:
$ tail -1 GN120XXUAND3_GN120DBTANE1_GN120XXUAND3_HOME.tar.md5
[snip garbage]056c3570e489a8a5c84d6d59da3c5dee GN120XXUAND3_GN120DBTANE1_GN120XXUAND3_HOME.tar
The tar itself contains a bunch more containers:
-rwxr-xr-x dpi/dpi 79211348 2014-04-16 13:46 camera.bin
-rw-r--r-- dpi/dpi 5507328 2014-04-16 13:49 boot.img
-rw-r--r-- dpi/dpi 6942976 2014-04-16 13:49 recovery.img
-rw-r--r-- dpi/dpi 1564016712 2014-04-16 13:48 system.img
-rwxr-xr-x dpi/dpi 52370176 2014-04-16 13:46 modem.bin
-rw-r--r-- dpi/dpi 40648912 2014-05-20 21:27 cache.img
-rw-r--r-- dpi/dpi 7704808 2014-05-20 21:27 hidden.img
These img and bin files contain different parts of the firmware and are flashed into respective partitions of the phone/camera:
camera.bin
: SLP container with five partitions for the DRIMeIV Tizen Linux SoCboot.img
: (Android) Linux kernel and initramfsrecovery.img
: Android recovery kernel and initramssystem.img
: Android (sparse) root filesystem imagemodem.bin
: a 50 MByte FAT16 image... with Qualcomm modem filescache.img
: Android cache partition imagehidden.img
: Android hidden partition image (contains a few watermark pictures andOver_the_horizon.mp3
in a folderINTERNAL_SDCARD
)
DRIMeIV firmware
The camera.bin
is 77MB and features the SLP\x00
header
known from the Samsung NX300.
It's also mentioning the internal model name as "GALAXYU":
camera.bin: GALAXYU firmware 0.01 (D20D0LAHB01) with 5 partitions
144 5523488 f68a86 ffffffff vImage
5523632 7356 ad4b0983 7fffffff D4_IPL.bin
5530988 63768 3d31ae89 65ffffff D4_PNLBL.bin
5594756 2051280 b8966d27 543fffff uImage
7646036 71565312 4c5a14bc 4321ffff platform.img
The platform.img
file contains a UBIFS root partition, and presumably vImage
is used for upgrading the DRIMeIV firmware, and uImage is the standard kernel
running on the camera SoC. The rootfs features "squeeze/sid" in
/etc/debian_version
, even though it's Tizen / Samsung Linux Platform.
There is a 500KB /usr/bin/di-galaxyu-app
that's probably responsible for
camera operation as well as for talking to the Android CPU (The NX300
di-camera-app
that actually implements the camera UI is 3.1MB).
Camera API
To actually use the camera, it needs to be exposed to the Android UI, which
talks to the Linux kernel on the Android SoC, which probably talks to the
Linux kernel on the DRIMeIV SoC, which runs di-galaxyu-app
. There is
probably some communication mechanism like SPI or I2C for configuration and
signalling, and also a shared memory area to transmit high-bandwidth data
(images and video streams).
Here we only get a brief overview of the components involved, further source reading and reverse engineering needs to be done to actually understand how the pieces fit together.
The Android side
On Android, the com.sec.android.app.camera
app is responsible for camera
handling. When it's started or switches to gallery mode, the screen briefly
goes black, indicating that maybe the UI control is handed over to the DRIMeIV
SoC?
The code for the camera app can be found in
/system/app/SamsungCamera2_GalaxyNX.apk
and
/system/app/SamsungCamera2_GalaxyNX.odex
and it needs to be
deodexed
in order to decompile the Java code.
There is an Exynos 4412 Linux source drop that also contains a
DRIMeIV video driver.
That driver references a set of resolutions going up to 20MP, which matches
the Galaxy NX sensor specs. It is exposing a Video4Linux camera, and seems to
be using SPI or I2C (based on an #ifdef
) to talk to the actual DRIMeIV
processor.
The DRIMeIV side
On the other end, the
Galaxy NX source code dump
contains the Linux kernel running on the DRIMeIV SoC, with a
drivers/i2c/si2c_drime4.c
file that registers a "Samsung Drime IV Slave I2C
Driver", which also allocates a memory region for MMIO.
The closed-source di-galaxyu-app
is referencing both SPI and I2C, and
needs to be reverse-engineered.
(*) Galaxy NX photo (C) Samsung marketing material