Upgrading from Debian 11 Stable to Debian 11 testing. Recompiling Retropie. Moving to bigger SD card.

Here's the short note on what has been done with my project over the last couple of months.

Upgraded from Debian 11 Stable to Debian 11 Testing

This was a piece of cake job. It's well documented in the official Debian documentation. 

Before I did that, I wanted to have an option to rollback, if things go wrong. For that I decided to use Timeshift to create a full backup of my system utilizing a spare 256 GB SD card I had. The tricky thing is, the GUI frontend of Timeshift is not fully functioning in Debian 11 Stable and it looks like it's a known bug. Hopefully the Timeshift CLI was functioning so I was able to make that backup.

The upgrade itself was long and boring and included quite a number of manual interventions, especially for the purposes of merging my modified config files from /etc to align them to what was in Debian 11 Testing. Do not worry, it's not something that you'll have to know about in advance - the apt will warn you when you need to review and make a decision on what to don, when you get there.

As a result of this upgrade, I have eventually got what I wanted - more fresh packages and a rolling-style of release. But subjectively the Xorg (or KDE) is working less stable on Testing - so no surprise it was a price to pay. I'd wish to give myself an advice to not upgrade (or roll back) but it is too late already and I'm lazy one :)

Recompiling Retropie (actually emulationstation, retroarch and libretro cores)

The first thing I have noticed after upgrading to Debian 11 Testing, is that RetroPie part of my distribution stopped working. 

This is how it is supposed to work and worked before I went with  upgrade: when I turn on or reboot my Orange Pi 4 LTS, Linux is booted into systemd' multi-user.target where I do have Retropie scripts started. These scripts run EmulationStation, which acts as a nice UI dashboard with different themes. It is working upon SDL library in a framebuffer mode, so no Xserver is invovled at this point, as it's just not existing in RetroPie distribution. From the EmulationStation you chose a platform (NES, SNES, PSX - you name it) and a game to play. When you click on a game, the EmulationStation runs a Retrorch and passes it a bunch of CLI parameters, which include a selected libretro core and the game ROM file location. You usually don't see Retroarch UI, unless you invoke in-game overlay menu, and for you it looks like you have just started the game directly from EmulationStation, which is off course is not true :) 

So in my case, when I tried to start the game, EmulationStation attempted to start Retroarch but then it was immediately returning back to EmulationStation, like Retroarch was failing to start. It wasn't a surprise for me, given the number of underlying libraries have changed because of aforementioned Debian 11 Stable -> Testing upgrade in my case. 

The solution was to go and recompile all "core components" of Retropie, using their own scripts ~pi/RetroPie-Setup/rertropie_setup.sh as I was hoping they should pick up all the latest libraries that are there in the system.

"Core components" here are:
* EmulationStation itself
* Retroarch
* Libretro cores

The tricky thing in there, is that I managed to install quite a number of additional Debian packages since this whole project started (like X11, hehe), but given:
- RetroPie, as a project, is bit behind from its "core components", which are independent projects, in terms of code base and patches
- RetroPie is probably relying on a particular version of OS (like Debian 11 Stable) and appropriate set/versions of libraries to be there - so they didn't care to accept a lot of patches from their upstream projects, like EmulationStation or Retroarch
- I have significantly changed versions fo all those packages in my system, with my upgrade to Debian 11 Testing
... it wasn't surprise that all of that started to fall apart and I wasn't able to finish the build successfully without manual intervention.

The intervention I'm speaking about was quite simple - just follow the below steps. The main idea is that you run the default script to recompile everything, wait for it to fail,  then deal with a failure, and then attempt to build that thing again. Exactly in this order:

1. Run a script to attempt to build for the first time
$ sudo ~pi/RetroPie-Setup/rertropie_setup.sh

2. In the CLI menu, select "Manage packages" -> "Core" -> "Update all installed packages"

This will run another script that does git clone (or git pull) and then running ./configure and make of all RetroPie "core components", one-by-one. 

The build will be happening in ~pi/RetroPie-Setup/tmp/build/ folder - you'll see different folders for different "core components" will be appearing in there, as the build progresses.

Build logs are put to ~pi/RetroPie-Setup/logs folder.

3. When you see the build fails, don't panic. Go and investigate the log, where exactly it failed. In my case the very first issue I had was:

In file included from /home/pi/RetroPie-Setup/tmp/build/emulationstation/es-core/src/components/DateTimeComponent.h:5,
                 from /home/pi/RetroPie-Setup/tmp/build/emulationstation/es-core/src/components/DateTimeComponent.cpp:1:
/home/pi/RetroPie-Setup/tmp/build/emulationstation/es-core/src/utils/TimeUtil.h:41:37: error: field ‘mTimeStruct’ has incomplete type ‘tm’
   41 |                         tm          mTimeStruct;
      |                                     ^~~~~~~~~~~

The very first hit from google where Arch people were discussing the same issue happening recently for their AUR package was exactly the fix I took. You'll need to go and modify ~pi/RetroPie-Setup/tmp/build/emulationstation/es-core/src/utils/TimeUtil.h file to add this include statement to the top:

#include <time.h<----- this one
#include <string>  

Then you can repeat points 1 and 2 again (run the script and select an option to update all core packages) to see where it fails now.

4. Next issue was awaiting for me in a form of ffmpeg package I had installed to my system for my own needs. For some reason retroarch build scripts were trying to use it in one if Retroarch "drivers" (?) to record screen while playing a game I guess. This is the feature I don't use so I won't be missing it much. In terms of build log error it looked like this:

make: *** [Makefile:206: obj-unix/release/record/drivers/record_ffmpeg.o] Error 1
make: *** Waiting for unfinished jobs....
cores/libretro-ffmpeg/ffmpeg_core.c: In function ‘libretro_ffmpeg_retro_init’:
cores/libretro-ffmpeg/ffmpeg_core.c:243:4: warning: implicit declaration of function ‘av_register_all’ [-Wimplicit-function-declaration]
  243 |    av_register_all();
      |    ^~~~~~~~~~~~~~~
cores/libretro-ffmpeg/ffmpeg_core.c: In function ‘init_hw_decoder’:
cores/libretro-ffmpeg/ffmpeg_core.c:991:82: error: ‘AVStream’ has no member named ‘codec’
  991 |    struct AVCodec *codec = avcodec_find_decoder(fctx->streams[video_stream_index]->codec->codec_id);
      |                                                                                  ^~
cores/libretro-ffmpeg/ffmpeg_core.c: In function ‘select_decoder’:
cores/libretro-ffmpeg/ffmpeg_core.c:1101:49: error: ‘AVStream’ has no member named ‘codec’
 1101 |       format = fctx->streams[video_stream_index]->codec->pix_fmt;
      |                                                 ^~
cores/libretro-ffmpeg/ffmpeg_core.c: In function ‘open_codec’:
cores/libretro-ffmpeg/ffmpeg_core.c:1135:62: error: ‘AVStream’ has no member named ‘codec’
 1135 |    AVCodec *codec = avcodec_find_decoder(fctx->streams[index]->codec->codec_id);
      |                                                              ^~
cores/libretro-ffmpeg/ffmpeg_core.c:1142:31: error: ‘AVStream’ has no member named ‘codec’
 1142 |    *ctx = fctx->streams[index]->codec;
      |                               ^~
cores/libretro-ffmpeg/ffmpeg_core.c: In function ‘open_codecs’:
cores/libretro-ffmpeg/ffmpeg_core.c:1233:47: error: ‘AVStream’ has no member named ‘codec’
 1233 |       enum AVMediaType type = fctx->streams[i]->codec->codec_type;
      |                                               ^~
cores/libretro-ffmpeg/ffmpeg_core.c:1248:54: error: ‘AVStream’ has no member named ‘codec’
 1248 |                   && !codec_is_image(fctx->streams[i]->codec->codec_id))
      |                                                      ^~
cores/libretro-ffmpeg/ffmpeg_core.c:1283:54: error: ‘AVStream’ has no member named ‘codec’
 1283 |                AVCodecContext *ctx = fctx->streams[i]->codec;
      |                                                      ^~


I spent quite a time, trying to figure it out, how to overcome it. I tried to uninstall the ffmpeg package, but that wasn't helping. I tried to play around with configure and various generated define scripts - but that also didn't help. What eventually helped is to modify this script - ~pi/RetroPie-Setup/tmp/build/retroarch/qb/config.params.sh

In there you'll need to modify couple of parameters, to change their values from auto to no:

HAVE_FFMPEG=no

And then you're again free to go and repeat points 1 and 2.

5. The last build error I've got was this one:

(something X11-related cannot remember what exactly)

Knowing that RetroPie shouldn't be using any of X11 as it's running on top of SDL library in a framebuffer mode, we want to keep it as is. So go ahead to modify config.params.sh file again to change the value of HAVE_X11 parameter to no:

HAVE_X11=no

... and run the build again (repeat steps 1 and 2). This time it went just fine. 

 

Migrating everything to a bigger SD card

Initially for this project I bought 128 Gb SD card. It sounded about right, until I realized how big PlayStation 1 games could be. And I also wanted my SBC to host backup of my photos from my Android Phone and some movies. It wasn't long until I ordered another, 256 Gb SD card, but it was just lying around as a spare one.

So now the time has come and I need to move everything from one SD card to another. For that we need:

1. To boot our SBC out of its internal EMMC, which also has Linux flashed by manufacturer. It will just make things easier. For that we'll need to power off the device and eject the SD card and power it back on. 

2. Once Linux is boot up, we'll insert the SD card back and also will use a small USB SD card reader to insert our second SD card.

3. With using lsblk we figure it out, what is the name of our block device (under /dev/). In my case it was /dev/mmcblk1 and /dev/sda

4. With using dd we clone the entire disk, using block size of 4 Mb like this:

dd if=/dev/sda of=/dev/mmcblk1 bs=4M

This is where I started to get errors. dd was complaining it cannot read from source device (smaller SD card) after reading few tens of Gb from it. I run e2fsck / badblocks / some other utilites against it number of times, but all of them were  keep complaining and complaining, finding issues and not actually fixing them. 

I gave up and rebooted the system, using different power adapter and gave it another try. It went just fine this time, the only difference was that I cloned partition (i.e. /dev/sda1 to /dev/mmcblk1) instead of clonning the whole disk. After cloning was successfully finished, I ran the parted CLI partition manager to extend the fresh partition to span all 100% of disk and then tried to upsize the filesystem with resize2fs. This is where I started to see some issues again. I rebooted again, ran e2fsck and badblocks - none of them found anything, so I ran resize2fs again and this time it went fine. 

I'm guessing all these issues had something to do with the cheap USB SD card reader I had.

No comments:

Post a Comment

Start here

Disable Firefox from updating itself and flash those annoying "Restart to Keep Using Firefox" messages on you

I recently switched from Brave to Firefox. Just because Brave appeared to be some proprietary shit, even though they're masking themselv...