zcrc.me is moving!

Just a quick notice to inform you that I am moving my blog from zcrc.me to opendingux.net which I just bought.

In the coming days or weeks (read: when I find some time) I will try to enhance the website so that it's worthy of being the official website of the OpenDingux project. zcrc.me will forward to the new domain until the end of April, after which the website will only be available at the new address.

Note that for the last few months (since around November) the comments system was broken on my blog, so it was impossible to write replies. I feel stupid for not noticing it before, since I would get at least a few replies per week, plus spam, and I had zero in six months. This is fixed now, and the pending comments have been processed and added to the posts. Sorry about that.

We have nighties

For a few days now, we've had nightly builds of OpenDingux. Not exactly nightly, as they are not built once a day, but every time new commits are pushed.

This is a big deal; that makes it so much easier for non-devs to follow closely what's being done in the latest OpenDingux. It is particularly interesting for GCW-Zero users, which have been stuck with a 2014-era firmware for so long now, and can now update to something a bit more recent. This also allows us to get much more feedback on the current state of things, as well as bug reports.

The other important bit is that the GCW-Zero build now also supports the RG-350 and the RG-350M handhelds, so you can test the latest OpenDingux on these handhelds too.

As for what's new compared to the old 2014-era firmware, I will write a blog post soon with an in-depth review of all the changes that have been made for the last 6 years.


I cannot stress more that the nightly builds are alpha quality and I cannot be held accountable for any damage caused to your handheld, your data, or yourself. If you're lucky it may not eat your data, but make a backup before updating, just in case.

As for functionalities, don't expect a fully-working build. A lot of work is yet to be done, and a lot of games don't run and will need to be adapted.

Download links

The latest OpenDingux nightly builds can be found at this permalink:

Note that the toolchains are not uploaded there. The latest RS-90 toolchain will still work on the nightly RS-90 builds. For the GCW-Zero build, the latest toolchain can be found here.


OpenDingux for RS-90 release 2020.10.04

Here is a new OS update for the RetroMini (RS-90). Note that it may very well be the last update for this handheld, since it is pretty much feature-complete, and as far as I can see, pretty much stable too.


  • Based on Linux v5.9-rc7 and Buildroot 2020.08.
  • Fixed out-of-memory issues at boot.
  • Fix overall performance issues of the 2020-01-06 release.
  • Added support for paletted 8bpp.
  • Added support for the IPU. Only multi-planar YUV 4:4:4 can be used. This pixel mode can be used in SDL1 by calling SDL_SetVideoMode with bpp=24 and SDL_YUV444 set in the flags.
  • Fix quick key presses being missed.
  • ExFat-formatted SD cards are now supported.
  • zram swap now uses LZO as the compressor. It seems to be the one that gives the best performance overall.
  • And lots of cleanups that aren't noteworthy enough to appear on this list.

Download links

The update OPK can be downloaded here: OpenDingux 2020-10-04 update OPK.
You MUST be running the 2020-01-06 release to run the update.

An updated toolchain can be downloaded here: OpenDingux 2020-10-04 toolchain.
After extracting the toolchain, be sure to run the relocate-sdk.sh script, so that it can work from the directory you extracted it to.

Update on GCW-Zero / RG-350 OpenDingux ports

It's been a while since I last did a public update on the status of OpenDingux for the GCW-Zero. Believe it or not, a lot has changed since the last release in 2014 🙂. Truth be told, I never really stopped to work on it since 2014, and the folks on the Freenode IRC channel #opendingux can testify just how much work I've been doing.

Linux From Scratch

All the GCW-Zero specific code is gone. Everything has been moved to Device Tree now. Device Tree is a textual representation of all the hardware present in a device. This means that with the right Device Tree files, in theory it should be possible to boot a generic MIPS kernel (Debian anyone?) on both the GCW-Zero, the RG-350, the old Dingoo A320 and the RetroMini. How cool is that?

The Device Tree source file is divided in two parts, one SoC specific (JZ4770) and one device specific (GCW-Zero). At compilation time, these two source files are assembled into one single binary file, that will be either compiled into the kernel, or loaded by the bootloader.

If you are curious about what it looks like, this is the current Device Tree file for the GCW-Zero:

Without going as far as having one kernel to support all devices, this work will allow one single kernel to support both the GCW-Zero and the RG-350, as well as the other JZ4770 based handhelds, provided somebody write the devicetree for these (and the board-specific hardware, like the LCD screen, is supported by Linux). It will also allow to extend the flasher software that's been used to flash the RetroMini through USB, to be used to flash other handhelds as well, since the flasher is basically a Linux kernel with a small payload. We do not want users to have no choice but to crack open a device to flash the internal SD, when there is the option to flash from USB. Besides all of that, switching to Device Tree files was the only way to go to support the OpenDingux devices in the upstream Linux kernel; crappy platform-specific code is not welcome anymore in there.

For the same reason, most of the drivers that were in use in the old 3.12 kernel are gone, too. The clock code, timer code, and drivers for the MMC/SD, DMA, LCD and framebuffer, IPU, VPU, GPU, I2C, ADC, joystick, battery, USB, PWM and backlight, power regulator chip, I2S/AC97 and audio codec are brand new. The WiFi drivers are new too but weren't written by us. Of the old 3.12 drivers, only the watchdog, RTC and interrupt controller drivers are still around. Most of these new drivers now also support multiple Ingenic SoCs, and will work on the Dingoo A320 (JZ4740), the RetroMini (JZ4725B), and even the MIPS CI20 (JZ4780). They will most likely also work on the RS-97 (JZ4760) with very little work needed, if any.

This sums up to a total of 342 patches that have been accepted upstream, and about two dozens still in the process of being upstreamed, for a diff of about 15k lines added and 7.5k lines removed. This may not sound like much, but the process of upstreaming code to the Linux kernel is a long and complicated one. All these patches went under peer review and saw many revisions before being merged. To give an order of magnitude of the work involved, if we count all the intermediary states of these patches, it sums up to more than six thousand commits that were authored by me. In the meantime, I became the de-facto Linux kernel maintainer for Ingenic SoCs, which means that all patches that touch Ingenic specific code now have to go through me, and need my ack to go forward.

Current status

From a usability standpoint, the work on the kernel is pretty much done, almost every single feature of the 3.12 kernel is present in the current development kernel based on 5.7; the only exception being the "linkdev" feature, which allowed to map the face and shoulder buttons to joystick events, as it was simply impossible to upstream for being nothing more than a quick and dirty hack. With that said, the feature could very well be re-introduced at a different level, for instance as a feature within SDL itself; but the feature was never really used so dropping it shouldn't be a problem.

Since 3.12, new features were added, too. The IPU now supports a variety of RGB color formats (15/16/32-bit, RGB/BGR), packed YUV 4:2:2 and planar YUV 4:1:1, 4:2:0, 4:2:2, and 4:4:4. It now also scales with bicubic filtering with a configurable sharpness factor. Experimental support for HDMI was added as well, with support to resolutions up to 720p, a terrible image quality and no audio (for now). Support for hardware overlays has been added too, so it should be possible to have an overlay shown whenever something like the volume or brightness is modified. All the improvements that were made on the RS-90 port of OpenDingux are also present here, for instance a proper mass-storage mode using MTP, just like on Android, to replace the need for a FTP client.

As the kernel is pretty much complete, most of the work left concerns the userspace. Speaking about SDL, while IPU support is integrated into the kernel, the framebuffer emulation of the DRM/KMS core does not allow it to be used through the old fbdev API. As a result, SDL applications cannot yet use the IPU, but it's a problem that needs to be fixed in SDL, not in the kernel, either by adding a DRM/KMS backend to SDL, or by using a SDL-to-SDL2 compat library and using the DRM/KMS backend of SDL2 (which has its own share of challenges).

The second other point that needs work, is WiFi support. The old root filesystem of OpenDingux used ifconfig and iwconfig to configure the network, which have been deprecated for years now. The current root filesystem uses the newer iw tool, but the GCWConnect WiFi configuration tool wasn't updated yet to support it, and the overall performance and stability of wireless links is unknown.

The missing fish is USB OTG. This feature allows to plug USB peripherals like gamepads to the USB port. I think everyone who ever tried USB OTG on their GCW-Zero have had a hardware failure at some point, myself included. I understand the interest in having the handheld plugged to HDMI with a couple of gamepads connected, but that just won't happen on the GCW-Zero. I cannot take the risk of causing more hardware failures. This is however not a problem on the RG-350, which does not use USB OTG, but has a USB host port directly available as USB1. On the GCW-Zero, this USB host port is used internally to connect the WiFi chip.

On the RG-350, the only thing missing right now is support for the right joystick, but that's just a matter of cleaning up the existing code and integrating it properly into the new ADC driver.

Tasty numbers

For people worried about performance, the overhead of the OS is slightly lower, which means that games and emulators gain a few FPS with the 5.7 kernel vs. the old 3.12 kernel. When recompiled with the new toolchain, based on GCC 9, there is an extra small gain that adds up. This is with our super-secret optimization turned OFF, which once enabled, will give a good 10+% performance increase on top of that. I/O performance drastically improved too: the read and write speeds to the SD cards, internal or external, more than doubled between the 3.12 and 5.7 kernels.

Some areas regressed, unfortunately. The upstream GPU kernel driver (etnaviv) along with the OpenGL ES layer (Mesa) that are used in the current development builds of OpenDingux have had a lot of fixes for crashes or graphical glitches, and is in many ways faster, but is also much slower than the old driver in some specific areas. With that said, the numbers of the old firmware should be taken with a grain of salt, since a lot of them are not rendering properly.

The new kernel comes with advanced debugging tools, like performance counters and debug overlays, so debugging the issue shouldn't be a problem, but that still has to be done. On the bright side, working close to upstream means that when we find the bottleneck, they will probably fix it for us.


As usual, it is pretty difficult for me to give an estimate about when the next version of the firmware for all the supported OpenDingux devices will be ready. Working on OpenDingux always feels like taking two steps forward then one step back. The IPU issue with SDL is hopefully the last big rock to smash in what has been a very long and lonesome road. Then will come the testing phase, to be extra-careful that everything that used to work still works.