[OS] RetroArch - Debian OS image based on the minimal Debian (u-boot, kernel, and Debian from scratch) [v0.3]

I created a clean Debian, and u-boot from scratch to be used in our device.

The menu is Retroarch. It boots directly to it in KMS mode (without X11).


  • Based on Debian Bullseye for the latest MESA driver with full lima support.
  • Clean OS with only Debian packages (except RetroArch binary) and small tweaks for hardware compatibility with gameshell.
  • No strange symbolic links nor duplicate files.
  • Max CPU frequency of 1.4GHz. The default governor is ondemand.
  • Standby mode (freeze) by pressing quickly the power key.
  • Power off by long-press (~2 seconds) the power key.
  • 941 MB of space occupied in the disk.
    • The system uses the minimum necessary to have a full Debian distribution with all the functionalities such as:
      • Package management (apt-get).
      • Wifi management with connman.
      • Bluetooth with bluez server.
      • DHCP server for USB ethernet functionality. I’m using network 192.168.11.x because some routers use the 192.168.10.x and using it will cause network problems.
      • SSH server.
      • Retroarch as a menu, and starting at boot. Takes around ~25 seconds from power on to get RetroArch running.
  • RAM usage of only 33MB, and 51MB with RetroArch running.
  • Cedrus support enabled in the kernel (The driver is compiled as a module, you need to enable it if you want to use).
    • This is for video encoding/decoding in hardware. The libva driver still not complete, but we should have it soon. This will be good if you want to record your game with retroarch and ffmpeg driver.
  • Charging LED is now in userspace.
    • I Patched the kernel. Now you have the charging LED (Orange LED) in the userspace at (/sys/class/leds/axp20x\:chgled/). You can control it manually (to use it for what you want like a normal led), or automatic (controlled by the charger).
  • Enabled status LED (green LED) to monitor (kernel 5.7):
    • Activity (CPU usage) [default mode], you can change it in the userspace.
    • Heartbeat. (I will use it later to signalize standby mode).
  • HDMI works and autodetects the screen resolution (up to 720p).
    • HDMI with hotplug detection.
    • The controller can read the screen information to use the best resolution available (up to 720p).
    • The HDMI is part of the kernel and can be manipulated with DRM.
  • U-boot configuration choose the dtb file for HDMI at boot time.
  • wifi driver is a kernel module now. We had issues with intermittent firmware loading. I hope it is fixed now.

Changelog v0.3

  • U-boot doesn’t need a FAT partition to load the kernel, removing the FAT partition for simplicity.
  • Kernel supports unloading modules.
  • Bluetooth firmware is loaded within the kernel.
  • Bluetooth speed increased from 115200bps to 1.5Mbps to support audio over Bluetooth.
  • Added pulseaudio to deal with audio over Bluetooth.
  • Added cpi user without a password.
  • Using connman to manage wifi connections (wpa_supplicant.conf won’t work anymore to manage wifi, only connman).
  • Added auto-expand script at first boot. The script will enlarge the file system to fill all available space on the SD card and reboot. During the first boot, the GameShell will reboot twice, be patient. The first time Debian will check the filesystem since nobody ever used the system before, the second time is the auto-expand script.
  • Added mass storage gadget function. The GameShell will appear as a storage device on your computer so you can easily transfer files.
    • The Storage space is limited to 8GB (This is what you will see on your computer), but the space occupied on the GameShell will increase dynamically (up to 8GB). You can still use a smaller SD card (~2GB) for the OS and everything, just don’t believe you have the 8 GB as your computer says you have.
    • The shared storage space is mounted on /home/cpi/storage/ and it is read-only on the GameShell. We cannot have the GameShell and the computer having write permission to the files at the same time, so only the computer can write to it.
    • All the shared storage space is inside the file /mass_storage on the GameShell.
    • After transferring your files, you need to remount the storage on the GameShell. For convenience, I added a menu option on RetroArch called: Storage reload on main screen to do the job.
  • Boot time increased slightly to fit all the improvements and make it a bit more user friendly (~4 seconds). If you want to develop something on top of this image without the need for the custom RetroArch, BT improvements, better stay with version 0.2.

Customized RetroArch

  1. Wifi management in the menu (Settings>Wi-Fi).
    • Rescan networks going back, and entering on the Wi-Fi settings again.
    • Connect to the network selecting it and use the keypad to enter your password on the on-screen keyboard.
  2. Bluetooth management on the menu (Settings>Bluetooth).
    • It can take a few seconds to scan, be patient.
    • Rescan devices going back, and entering on the Bluetooth settings again.
  3. Screen brightness adjustment on the main screen, together with Reboot and Shutdown options.
  4. You can use the GameShell keypad to navigate the on-screen keyboard to enter text.
  5. You can have temperature and CPU speed information with the FPS counter. To disable it, you have to go to the /home/cpi/.config/retroarch.cfg file and set temp_show = "true", and cpufreq_show = "true" to false. I will make a menu entry to enable/disable in the future, but you can disable all together disabling the fps counter
  6. The entry Start Directory on RetroArch points to /home/cpi/storage.
  7. After transferring your files using the mass storage, you can reload the system using the menu entry: Storage reload on the main screen.


Audio over Bluetooth is a bit complicated under Linux in general. Hopefully, everything will work out of the box. I have 2 Sony headsets and both work differently when trying to pair on GameShell (or any Linux computer), so there is not a single recipe to have everything working. With one headset it doesn’t connect automatically after switching it off and on again, I have to go to the RetroArch Bluetooth settings (or bluetoothctl from the command line) and connect to it (pairing is not needed). With the second headset, it connects automatically but the A2DP profile is not always available:

cpi@clockworkpi :~$ pactl list | grep A2DP
		a2dp_sink: High Fidelity Playback (A2DP Sink) (sinks: 1, sources: 0, priority: 40, available: no)

After pressing some buttons on the headset (Play/Pause), it became available:

cpi@clockworkpi :~$ pactl list | grep A2DP
		a2dp_sink: High Fidelity Playback (A2DP Sink) (sinks: 1, sources: 0, priority: 40, available: yes)

and I have to set the profile manually using (use pacmd list to see your card number):

pacmd set-card-profile your_card_number a2dp_sink

This is better documented here: https://wiki.archlinux.org/index.php/Bluetooth_headset#Switch_between_HSP/HFP_and_A2DP_setting

It works! Good luck!!!


  • There is no password for root, and cpi user!


  1. The HDMI sound output doesn’t work, the sound is routed to the Gameshell speaker.
  2. HDMI driver is a bit unstable and sometimes doesn’t work properly. If you don’t have output after booting with HDMI cable try:
    • Reload module with: modprobe -r ite_it66121, and modprobe ite_it66121.
  3. Inside RetroArch, the first time you try to set wifi (settings>wifi), it will show nothing. Go back to the settings menu and try again.
  4. After entering the wifi password, will appear a message informing an error. Ignore it, you probably successfully connected if you entered the correct password, if not, try again.
  5. Reconnecting devices inside the Bluetooth settings can take a while, and the keypad will be unresponsive, be patient.

Windows users

The storage space will appear as CPI-STORAGE disk.

Windows users need to install the RNDIS driver to use the USB Ethernet now. If you are using Windows 10 you need to disable the driver signature check. Here is a good guide: https://www.howtogeek.com/167723/how-to-disable-driver-signature-verification-on-64-bit-windows-8.1-so-that-you-can-install-unsigned-drivers/

Use the RNDIS_linux_driver.inf file inside the storage driver folder CPI-STORAGE to install it.

Bonus tip


  • RetroArch will look for bios inside the storage drive bios folder.
  • The roms folder inside the storage has the system names that RetroArch understands and can look for the thumbnails (Box arts, Title screen, …) on its repository (http://thumbnails.libretro.com/). Make sure your rom uses the same name as they use to name the pictures.

For instance:

You have an NES Contra rom and want RetroArch to look for the thumbnail.

  1. Go to the RetroArch thumbnail repository under Nintendo - Nintendo Entertainment System/Named_Boxarts and search for Contra.
  2. Check the correct filename for the png file, in my case Contra (USA).png, Which is this:
  3. Name your rom as Contra (USA).nes (or Contra (USA).zip if it is inside a zip file), and place it inside the roms/Nintendo - Nintendo Entertainment System folder in the storage drive.
  4. If your GameShell is connected to the internet, RetroArch will try to search for the thumbnail after you load the rom, and the thumbnail will appear when you go to Load Recent section.

The best is to create a playlist with your roms:

  1. Go to Playlists>Manual Scan.
  2. Change Content Directory to roms/Nintendo - Nintendo Entertainment System (For an NES playlist).
  3. Keep System Name to <Content Directory>.
  4. Change default core to nestopia_libretro.so.
  5. Start scan.

If your roms are named correctly you should have a Playlist named Nintendo - Nintendo Entertainment System inside the Playlists. If you now enter the playlist, the thumbnails should appear correctly:



OS [v0.3]


db09b371e97924f6675f81525654aa41  clockworkpi-debian.img
97ee095cbd44631f10b655248d138dc4  clockworkpi-debian.zip

Kernel 5.7 only

Compiled binaries can be found inside bin folder of the repository.

Download the files:


and copy it to /BOOT

Documentation and patches can be found on:

Edit 1: Organize functionalities, issues, and documentation in a list.
Edit 2: Updating with fixed issues.
Edit 3: New version v0.2 update.
Edit 4: New RetroArch based image.


that’s awesome, thanks a lot for your work !


Thanks, let’s see if people gets interested.

1 Like

Fixed LED issues :grinning:

I updated the main topic for simpler reading.

I will launch this update in the next release 0.2. I hope I can get HDMI working as well so the OS will be complete. I’m inclined to try to make HDMI work in real time (kernel) instead of the need to be recognized at boot (u-boot). I’ll see how difficult it is.

Regarding the LED’s, I used the patch from StefanMavrodiev. It adds a new driver in the Linux Kernel so we can have it in userspace and we change the behavior as we wish. I don’t know why this patch still not in the mainline. The driver is rich, and it is possible to change the operation modes, manual or automatic control. More information can be seen at https://patchwork.kernel.org/patch/10814855/


  • Charging LED is now in userspace (next release 0.2).
    • I Patched the kernel. Now you have the charging LED (Orange LED) in the userspace at (/sys/class/leds/axp20x\:chgled/). You can control it manually (to use it for what you want like a normal led), or automatic (controlled by the charger).

I enabled some configurations in the kernel, so the status LED can monitor the CPU.

  • Enabled status LED (green LED) to monitor (next release 0.2):
    • Activity (CPU usage) [default mode], you can change it in the userspace.
    • Heartbeat. (I will use it later to signalize standby mode).

it cannot be more clean, i hope it will be adopted as default base in future :slight_smile:

hopping also external additions will be released as deb packages

your research make some advance, all community will give benefits from them :sunflower:


I LOVE the idea of having a clean Debian based image for the clockwork pi. The official image is a bit of a mess.

Do you happen have a script / manifest / playbook for building the image?

If not do you have step by step instructions? I’d be up for trying to create an automated process for building images.

(This is assuming you don’t already have one, sorry, just excited and doing some speaking without thinking)


thanks for your great work!!!
I’m very interested in sleep function. How can I adapt it to default OS of Gameshell?

1 Like

Yes, I documented everything in the github page:

Thanks for your interest. I think it should be straightforward to make a bot to compile it with the commands I listed. The only thing missing is to create a virtual sd card for the process.

If you can do it, please, send me a patch :slight_smile:

I’m busy working on the HDMI problem.


What enables this function (sleep and power key) is a patch in the kernel. You can use the patch I used in my github page. All the procedure to make it can be found there, go to the section Kernel in the README.md

Keep in mind that “sleep” is in reality “freezing”. All the information can be found here:

1 Like

I’m improving a lot in the HDMI.

I found a kernel driver that fits the it66121 (our RGB -> HDMI converter). I created another patch with the driver, updated the device tree and now it is working :slight_smile:

In the official image this driver is inside u-boot. We never got the source code for u-boot, which defeats the “An Open Source Portable Game Console” :weary:

The good things are:

  • HDMI with hotplug detection.
  • The controller can read the screen information to use the best resolution available (up to 720p, but I know a way to get full HD :sweat_smile:).
  • The HDMI is part of the kernel and can be manipulated with DRM.

The bad:

  • Sound over HDMI doesn’t work yet.

Working on:

  • I don’t know if I can do it, but I want to have an automatic change when we are using LCD or HDMI. If I see that it is extremely difficult I will focus in getting the sound and find a way to patch u-boot to look for a specific *.dtb when it detects the HDMI cable (like we have in the official image).

This is huge news. This opens a lot of possibilities and hope for the project! I you have a specific thread for the “asking for the missing source part” tell us so we can go and voice our concern there too!

Whenever I get the time I’ll go through your instructions to make sure they are reproducible and that we can improve the documentation.

Thanks a lot :raised_hands: for this work ! I might be able to recommend this device after all !

Thanks for your support.

The missing part is the u-boot patch. I think the way I’m getting it to work is better (kernel drivers), but I still need to understand how to get the audio working. If we have the code I could work in another thing… maybe the deep sleep.


tks! I’ve decide to apply your kernel patch to default OS and it works, boot screen is mixed but i’m ok with it :slight_smile:
Freezing works, I tried with RetroArch and sometime it made GS launcher to reload after resuming. But I can take the risk :smiley:

Wow, by far the fastest-booting image from what I’ve been able to test!


To get the clockworkpi logo back, you can use this patch:

The GS launcher (for what I remember) works inside a while loop and reload after you close the application, in your case Retroarch. So your retroarch is being closed for one motive…

I tried here with my image, and I can keep retroarch running with a game loaded in memory. After wakeup I can still play my game from the same point I left.


Thanks for trying :grinning:

I updated the repository.

In the new patch for kernel 5.7 I enabled support for the new HDMI driver, but without sound over HDMI. The sound is routed to the gameshell speaker for now.

In the new BOOT.scr I enabled an option for u-boot choose the correct *.dtb file when the HDMI cable is connected.

Instead of having a new release, I decided to provide the compiled kernel, and dtb files so you can just copy the files to your /BOOT directory and get the new drivers working, keeping your system without changes.

Honestly speaking the 0.1 release is almost a definitive OS. You can update everything from apt and keep up to date. We need to work only with the kernel, maybe I could create a deb file so you could update the kernel easily.



Thank you a lot for you hard work!

1 Like

I followed the instructions on your git repo with a new 32GB card and it worked wonderfully!

May be worth adding some notes about which build dependencies are required for people following along there. I had most already, but needed multistrap, qemu-user-static, etc.

Great work. Thanks!


Thanks for trying!

The reason I didn’t add the build dependencies is because I don’t really know :joy:

multistrap, and qemu is for the script, but there are many others that you probably already have