Retrolimex: une console de retrocomputing avec un Olinuxino đź”—

Posted by MĂ©dĂ©ric Ribreux 🗓 In projects/retro/

Introduction

Quoi de plus simple qu'une bonne partie de jeux des années 80/90 sur le pouce, sans se prendre la tête avec une configuration complexe. Et pour ça, quoi de mieux qu'une machine dédiée, qui ne prend pas de place et qui se branche à une télé, comme on faisait avant ?

Mais pour parvenir à ça, comme d'habitude en informatique, il va falloir transpirer du cerveau et prendre du temps pour préparer. Ça fait aussi partie du système de récompense: de l'effort initial pour mieux profiter de la suite.

Pour fabriquer cette bécane, je me suis basé sur un Olimex OLinuxino Lime 2 sur lequel j'ai surtout travaillé au niveau logiciel pour faire rentrer tout ça au chausse-pied. D'où le nom du projet: Retrolimex !

Etat du projet

Ce projet n'est PAS terminé !

Ce qu'on veut et avec quels moyens

Préparation de la machine

TODO: dire comment on déploie U-boot dessus. TODO: dire comment on déploie Debian dessus.

Mettre Ă  jour U-Boot

U-Boot c'est le bootloader de la machine, l'équivalent de Grub. En règle générale, la mise à jour de U-Boot c'est quelque-chose d'assez rare: souvent on se contente de dire que si ça marche, on laisse en l'état.

Mais dans mon cas, j'ai eu quelques bugs lors de la première installation de Debian sur cette carte et j'ai du compiler U-Boot avec une option spécifique puis le déployer. Je me retrouve avec un u-boot de 2019 qui certes marche, mais qui n'est plus dans sa première jeunesse. Et puis, il y a au moins un développeur Debian en charge de créer et de maintenir U-Boot pour ma carte. Rien que cet effort bénévole mérite qu'on l'utilise, non ?

Il faut d'abord installer le bon paquet:

# apt install u-boot-sunxi

Une fois que c'est fait, on dispose d'un utilitaire tout fait: u-boot-install-sunxi (un script shell) qui fait tout le job:

Dans mon cas, je souhaite installer la nouvelle version de U-Boot sur la carte SD et sur l'Olinuxino, ça correspond à /dev/mmcblk0.

# u-boot-install-sunxi /dev/mmcblk0

Une fois installé, il suffit de redémarrer la bécane et magie: ça démarre sur la bonne version de U-Boot ! Bien entendu, il faudra penser à renouveler cette commande lors de mise à jour du paquet u-boot-sunxi dans Debian.

Support audio HDMI

Introduction

I run a native version of Debian on the board and everything does work out of the box... ...until I wanted to use audio.

Find the patch

First things first, whenever there is a lack of support of something into Linux Kernel, it's always good to check if the patch has been mainlined on the latest revision of the kernel.

mentionned on the I am not good enough to produce the patch myself.

Official kernel modifications for Olimex hardware are stored in a Github repository. They keep code as a full linux source vith a version of kernel per branch and also a date release from Olimex.

It does mean that if you want to stick to the Linux kernel provided by Debian, you will have to produce a patch by cherry picking code.

I found the following patch:

And I prepared a ready to use patch from it. You can download it from here.

Build the kernel the Debian way

I am not an expert on cross compilation and kernel packaging under Debian. But I use the following method and it does work pretty well.

tar -xaf /usr/src/linux-source-5.10.tar.xz
cd linux-source-5.10
patch -p1 < ../a20-add-hdmi-audio.patch
cp /boot/config-5.10.0-13-armmp-lpae .config
$ make nconfig
  verify if hdmi audio is set in Device Drivers -> Graphics -> All A10 HDMI Audio Support
$ scripts/config --disable MODULE_SIG
$ scripts/config --disable SYSTEM_TRUSTED_KEYS
$ scripts/config --disable DEBUG_INFO
$ make clean
$ nohup make deb-pkg LOCALVERSION=-armmp-lpae >./nohup.out 2>./nohup.err &

Compilation takes more than a day (about 27 hours) on a single core of the AllWinner A20! You've been warned.

Cross-build the kernel the Debian way

You can also cross-compile it from a faster machine (about 30 minutes on my 10 years old i7-3770K CPU):

# apt update && apt install crossbuild-essential-armhf cross-gcc-dev 
$ tar -xaf /usr/src/linux-source-5.10.tar.xz
$ cd linux-source-5.10
$ patch -p1 < ../a20-add-hdmi-audio.patch
$ cp /boot/config-5.10.0-13-armmp-lpae .config
$ ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- make nconfig
  verify if hdmi audio is set in Device Drivers -> Graphics -> Allwinner A10 HDMI Audio Support
$ scripts/config --disable MODULE_SIG
$ scripts/config --disable SYSTEM_TRUSTED_KEYS
$ scripts/config --disable DEBUG_INFO
$ ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- DEB_BUILD_OPTIONS=nocheck make
deb-pkg LOCALVERSION=-armmp-lpae KDEB_PKGVERSION=$(make kernelversion) -j7
$ ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- DEB_BUILD_OPTIONS=nocheck make deb-pkg LOCALVERSION=-armmp-lpae -j7
  ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- DEB_BUILD_OPTIONS=nocheck make deb-pkg LOCALVERSION=-armmp-lpae KDEB_PKGVERSION=$(make kernelversion) -j7
# dpkg -i /home/medspx/linux-image-5.10.106-armmp-lpae_5.10.106-armmp-lpae-1_armhf.deb 

If something goes wrong, most of the time, it is either a problem in the .config Kernel compilation configuration file. Other problems come mostly from an aborted package building. If you encounter an error at this stage, delete the whole source and start from the tar command above.

Enjoy

Now, you have to connect the Olinuxino to an HDMI screen (with an HDMI cable), otherwise, audio device is not set up. Once connected, you will be able to use alsa and pulseaudio.

If you want to be really sure, use speaker test (from alsa-utils package):

speaker-test -c2 -l1 -twav

Conclusions

It's really strange that this feature is not already kernel mainlined. I suspect it is not so simple to produce and maintain mainlined kernel quality code. Anyway, thanks to Olimex to add and maintain this feature, it is already far more than what I could achieve.

Retrolauncher

Mais voilà, il faut bien reconnaître qu'un Olinuxino Lime2, c'est limité en puissance. Sur cette bécane, faire tourner libretro, c'est à peu près impossible.

Et puis, il me manque de quoi piloter l'engin avec un simple joypad USB.

Pour compenser, j'ai créé un petit programme en C (parce qu'en 2022, ça reste blazingly fast) avec la libSDL qui permet de naivguer dans une arborescence de ROMS, de choisir un jeu et de le lancer avec un joypad de base.

Lancement d'une session sway automatique

J'utilise une technique assez simple pour démarrer un environnement graphique sans clavier. Cela consiste en: